From e48f1fcc734a05ab0d7402b8939e7e50325f7de5 Mon Sep 17 00:00:00 2001 From: Francesco Carli <62562180+fcarli3@users.noreply.github.com> Date: Mon, 9 Nov 2020 16:06:00 +0100 Subject: [PATCH] Fixes federation bug (#480) * Fixes federation bug * Fixes federation bug * Update edge_utils.c --- src/edge_utils.c | 98 ++++++++------- src/sn_utils.c | 311 +++++++++++++++++++++++++---------------------- 2 files changed, 221 insertions(+), 188 deletions(-) diff --git a/src/edge_utils.c b/src/edge_utils.c index 6f3a04c..146636a 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -808,7 +808,7 @@ static int sort_supernodes(n2n_edge_t *eee, time_t now){ eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; traceEvent(TRACE_INFO, "Registering with supernode [%s][number of supernodes %d][attempts left %u]", - supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigned int)eee->sup_attempts); + supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigned int)eee->sup_attempts); send_register_super(eee); eee->sn_wait = 1; @@ -819,13 +819,14 @@ static int sort_supernodes(n2n_edge_t *eee, time_t now){ // this routine gets periodically called // it sorts supernodes in ascending order of their ping_time-fields HASH_SORT(eee->conf.supernodes, ping_time_sort); - eee->last_sweep = now; + } - HASH_ITER(hh, eee->conf.supernodes, scan, tmp){ - scan->ping_time = MAX_PING_TIME; - } + HASH_ITER(hh, eee->conf.supernodes, scan, tmp){ + scan->ping_time = MAX_PING_TIME; } + send_query_peer(eee, null_mac); + eee->last_sweep = now; } return 0; /* OK */ @@ -1337,9 +1338,9 @@ static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) { "community: %s\n", eee->conf.community_name); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), - " id tun_tap MAC edge hint last_seen\n"); + " id tun_tap MAC edge hint last_seen\n"); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), - "-----------------------------------------------------------------------------------------------\n"); + "-----------------------------------------------------------------------------------------------\n"); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), "supernode_forward:\n"); @@ -1349,10 +1350,10 @@ static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) { if(peer->dev_addr.net_addr == 0) continue; net = htonl(peer->dev_addr.net_addr); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), - " %-4u %-15s %-17s %-21s %-15s %lu\n", + " %-4u %-15s %-17s %-21s %-15s %lu\n", ++num, inet_ntoa(*(struct in_addr *) &net), macaddr_str(mac_buf, peer->mac_addr), - sock_to_cstr(sockbuf, &(peer->sock)), + sock_to_cstr(sockbuf, &(peer->sock)), peer->dev_desc, now - peer->last_seen); @@ -1369,10 +1370,10 @@ static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) { if(peer->dev_addr.net_addr == 0) continue; net = htonl(peer->dev_addr.net_addr); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), - " %-4u %-15s %-17s %-21s %-15s %lu\n", + " %-4u %-15s %-17s %-21s %-15s %lu\n", ++num, inet_ntoa(*(struct in_addr *) &net), macaddr_str(mac_buf, peer->mac_addr), - sock_to_cstr(sockbuf, &(peer->sock)), + sock_to_cstr(sockbuf, &(peer->sock)), peer->dev_desc, now - peer->last_seen); @@ -1955,12 +1956,12 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { in_addr_t net; char * ip_str = NULL; n2n_REGISTER_SUPER_ACK_t ra; - uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES]; - n2n_sock_t *tmp_sock; - n2n_mac_t *tmp_mac; - int i; - int skip_add; - struct peer_info *sn; + uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES]; + n2n_sock_t *tmp_sock; + n2n_mac_t *tmp_mac; + int i; + int skip_add; + struct peer_info *sn; memset(&ra, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); @@ -2000,20 +2001,29 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { if(0 == memcmp(ra.cookie, eee->curr_sn->last_cookie, N2N_COOKIE_SIZE)) { - tmp_sock = (void*)&tmpbuf; - tmp_mac = (void*)&tmpbuf[sizeof(n2n_sock_t)]; - - for(i=0; iconf.supernodes), tmp_sock, tmp_mac, &skip_add); - if(skip_add == ADDED){ - traceEvent(TRACE_NORMAL, "Supernode added to the list of supernodes."); - } - - /* REVISIT: find a more elegant expression to increase following pointers. */ - tmp_sock = (void*)tmp_sock + ENTRY_SIZE; - tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t); - } + tmp_sock = (void*)&tmpbuf; + tmp_mac = (void*)&tmpbuf[sizeof(n2n_sock_t)]; + + for(i=0; iconf.supernodes), tmp_sock, tmp_mac, &skip_add); + + if(skip_add == ADDED){ + sn->ip_addr = calloc(1,N2N_EDGE_SN_HOST_SIZE); + if(sn->ip_addr != NULL){ + inet_ntop(tmp_sock->family, + (tmp_sock->family == AF_INET)?(void*)&tmp_sock->addr.v4:(void*)&tmp_sock->addr.v6, + sn->ip_addr, N2N_EDGE_SN_HOST_SIZE-1); + sprintf (sn->ip_addr, "%s:%u", sn->ip_addr, (uint16_t)tmp_sock->port); + } + sn->last_valid_time_stamp = initial_time_stamp(); + traceEvent(TRACE_NORMAL, "Supernode '%s' added to the list of supernodes.", sn->ip_addr); + } + + /* REVISIT: find a more elegant expression to increase following pointers. */ + tmp_sock = (void*)tmp_sock + ENTRY_SIZE; + tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t); + } eee->last_sup = now; eee->sn_wait=0; @@ -2040,7 +2050,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { * based on its NAT configuration. */ //eee->conf.register_interval = ra.lifetime; - eee->curr_sn->ping_time = (now - eee->last_register_req)*1000; + eee->curr_sn->ping_time = (now - eee->last_register_req)*1000; } else { @@ -2068,10 +2078,10 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { } if(!is_valid_peer_sock(&pi.sock)) { - traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]", - sock_to_cstr(sockbuf1, &pi.sock), - macaddr_str(mac_buf1, pi.mac) ); - break; + traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]", + sock_to_cstr(sockbuf1, &pi.sock), + macaddr_str(mac_buf1, pi.mac) ); + break; } if(memcmp(pi.mac, null_mac, sizeof(n2n_mac_t)) == 0){ @@ -2085,16 +2095,16 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { HASH_FIND_PEER(eee->pending_peers, pi.mac, scan); if(scan) { - scan->sock = pi.sock; - traceEvent(TRACE_INFO, "Rx PEER_INFO for %s: is at %s", - macaddr_str(mac_buf1, pi.mac), - sock_to_cstr(sockbuf1, &pi.sock)); + scan->sock = pi.sock; + traceEvent(TRACE_INFO, "Rx PEER_INFO for %s: is at %s", + macaddr_str(mac_buf1, pi.mac), + sock_to_cstr(sockbuf1, &pi.sock)); - send_register(eee, &scan->sock, scan->mac_addr); + send_register(eee, &scan->sock, scan->mac_addr); } else { - traceEvent(TRACE_INFO, "Rx PEER_INFO unknown peer %s", - macaddr_str(mac_buf1, pi.mac) ); + traceEvent(TRACE_INFO, "Rx PEER_INFO unknown peer %s", + macaddr_str(mac_buf1, pi.mac) ); } } break; @@ -2770,7 +2780,7 @@ void edge_init_conf_defaults(n2n_edge_conf_t *conf) { conf->register_interval = REGISTER_SUPER_INTERVAL_DFL; conf->tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN; /* reserve possible last char as null terminator. */ - gethostname((char*)conf->dev_desc, N2N_DESC_SIZE-1); + gethostname((char*)conf->dev_desc, N2N_DESC_SIZE-1); if (getenv("N2N_KEY")) { conf->encrypt_key = strdup(getenv("N2N_KEY")); diff --git a/src/sn_utils.c b/src/sn_utils.c index 4ddf4f5..4327619 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -353,7 +353,7 @@ static int update_edge(n2n_sn_t *sss, memcpy(&(scan->mac_addr), reg->edgeMac, sizeof(n2n_mac_t)); scan->dev_addr.net_addr = reg->dev_addr.net_addr; scan->dev_addr.net_bitlen = reg->dev_addr.net_bitlen; - memcpy((char*)scan->dev_desc, reg->dev_desc, N2N_DESC_SIZE); + memcpy((char*)scan->dev_desc, reg->dev_desc, N2N_DESC_SIZE); memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t)); scan->last_valid_time_stamp = initial_time_stamp(); @@ -529,7 +529,7 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community * time_t time; struct peer_info *peer, *tmp; - if((now - (*p_last_re_reg_and_purge)) < RE_REG_AND_PURGE_FREQUENCY ) return 0; + if((now - (*p_last_re_reg_and_purge)) < RE_REG_AND_PURGE_FREQUENCY ) return 0; if(comm != NULL) { HASH_ITER(hh,comm->edges,peer,tmp) { @@ -583,7 +583,7 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community * } } - (*p_last_re_reg_and_purge) = now; + (*p_last_re_reg_and_purge) = now; return 0; /* OK */ } @@ -665,10 +665,10 @@ static int process_mgmt(n2n_sn_t *sss, traceEvent(TRACE_DEBUG, "process_mgmt"); + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + " id tun_tap MAC edge hint last_seen\n"); ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - " id tun_tap MAC edge hint last_seen\n"); - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "-------------------------------------------------------------------------------------------------\n"); + "-------------------------------------------------------------------------------------------------\n"); HASH_ITER(hh, sss->communities, community, tmp) { num_edges += HASH_COUNT(community->edges); ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, @@ -678,11 +678,11 @@ static int process_mgmt(n2n_sn_t *sss, num = 0; HASH_ITER(hh, community->edges, peer, tmpPeer) { - ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, " %-4u %-18s %-17s %-21s %-15s %lu\n", ++num, ip_subnet_to_str(ip_bit_str, &peer->dev_addr), macaddr_str(mac_buf, peer->mac_addr), - sock_to_cstr(sockbuf, &(peer->sock)), + sock_to_cstr(sockbuf, &(peer->sock)), peer->dev_desc, now - peer->last_seen); @@ -691,7 +691,7 @@ static int process_mgmt(n2n_sn_t *sss, } } ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "-------------------------------------------------------------------------------------------------\n"); + "---------------------------------------------------------------------------------\n"); ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, "uptime %lu | ", (now - sss->start_time)); @@ -1036,18 +1036,18 @@ static int process_udp(n2n_sn_t * sss, n2n_REGISTER_SUPER_ACK_t ack; n2n_common_t cmn2; uint8_t ackbuf[N2N_SN_PKTBUF_SIZE]; - uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES]; - uint8_t *tmp_dst; + uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES]; + uint8_t *tmp_dst; size_t encx=0; struct sn_community *fed; struct sn_community_regular_expression *re, *tmp_re; - struct peer_info *peer, *tmp_peer, *p; + struct peer_info *peer, *tmp_peer, *p; int8_t allowed_match = -1; uint8_t match = 0; - int match_length = 0; + int match_length = 0; n2n_ip_subnet_t ipaddr; - int num = 0; - int skip_add; + int num = 0; + int skip_add; memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); @@ -1057,13 +1057,13 @@ static int process_udp(n2n_sn_t * sss, decode_REGISTER_SUPER(®, &cmn, udp_buf, &rem, &idx); if (comm) { - if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { - if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.edgeMac, stamp, TIME_STAMP_NO_JITTER)) { - traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER due to time stamp error."); - return -1; - } - } - } + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.edgeMac, stamp, TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER due to time stamp error."); + return -1; + } + } + } /* Before we move any further, we need to check if the requested @@ -1074,14 +1074,14 @@ static int process_udp(n2n_sn_t * sss, if(!comm && sss->lock_communities) { HASH_ITER(hh, sss->rules, re, tmp_re) { - allowed_match = re_matchp(re->rule, (const char *)cmn.community, &match_length); + allowed_match = re_matchp(re->rule, (const char *)cmn.community, &match_length); - if( (allowed_match != -1) + if( (allowed_match != -1) && (match_length == strlen((const char *)cmn.community)) // --- only full matches allowed (remove, if also partial matches wanted) && (allowed_match == 0)) { // --- only full matches allowed (remove, if also partial matches wanted) - match = 1; - break; - } + match = 1; + break; + } } if(match != 1) { traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", @@ -1091,25 +1091,24 @@ static int process_udp(n2n_sn_t * sss, } if(!comm && (!sss->lock_communities || (match == 1))) { + comm = (struct sn_community*)calloc(1,sizeof(struct sn_community)); + + if(comm) { + comm_init(comm,(char *)cmn.community); + /* new communities introduced by REGISTERs could not have had encrypted header... */ + comm->header_encryption = HEADER_ENCRYPTION_NONE; + comm->header_encryption_ctx = NULL; + /* ... and also are purgeable during periodic purge */ + comm->purgeable = COMMUNITY_PURGEABLE; + comm->number_enc_packets = 0; + HASH_ADD_STR(sss->communities, community, comm); + + traceEvent(TRACE_INFO, "New community: %s", comm->community); + assign_one_ip_subnet(sss, comm); + } + } - comm = (struct sn_community*)calloc(1,sizeof(struct sn_community)); - - if(comm) { - comm_init(comm,(char *)cmn.community); - /* new communities introduced by REGISTERs could not have had encrypted header... */ - comm->header_encryption = HEADER_ENCRYPTION_NONE; - comm->header_encryption_ctx = NULL; - /* ... and also are purgeable during periodic purge */ - comm->purgeable = COMMUNITY_PURGEABLE; - comm->number_enc_packets = 0; - HASH_ADD_STR(sss->communities, community, comm); - - traceEvent(TRACE_INFO, "New community: %s", comm->community); - assign_one_ip_subnet(sss, comm); - } -} - -if(comm) { + if(comm) { cmn2.ttl = N2N_DEFAULT_TTL; cmn2.pc = n2n_register_super_ack; cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; @@ -1137,13 +1136,13 @@ if(comm) { memcpy(ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); if((from_supernode == 0) != (comm->is_federation == IS_NO_FEDERATION)) { - traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER: from_supernode value doesn't correspond to the internal federation marking"); - return -1; + traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER: from_supernode value doesn't correspond to the internal federation marking"); + return -1; } /* Add sender's data to federation (or update it) */ if(comm->is_federation == IS_FEDERATION) { - skip_add = NO_SKIP; + skip_add = NO_SKIP; p = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &(ack.sock), &(reg.edgeMac), &skip_add); } @@ -1152,20 +1151,20 @@ if(comm) { /* Assembling supernode list for REGISTER_SUPER_ACK payload */ tmp_dst = tmpbuf; HASH_ITER(hh, sss->federation->edges, peer, tmp_peer) { - if(memcmp(&(peer->sock), &(ack.sock), sizeof(n2n_sock_t)) == 0) continue; /* a supernode doesn't add itself to the payload */ + if(memcmp(&(peer->sock), &(ack.sock), sizeof(n2n_sock_t)) == 0) continue; /* a supernode doesn't add itself to the payload */ if((now - peer->last_seen) >= ALLOWED_TIME) continue; /* skip long-time-not-seen supernodes */ if(((++num)*ENTRY_SIZE) > MAX_AVAILABLE_SPACE_FOR_ENTRIES) break; /* no more space available in REGISTER_SUPER_ACK payload */ memcpy((void*)tmp_dst, (void*)&(peer->sock), sizeof(n2n_sock_t)); - tmp_dst += sizeof(n2n_sock_t); + tmp_dst += sizeof(n2n_sock_t); memcpy((void*)tmp_dst, (void*)&(peer->mac_addr), sizeof(n2n_mac_t)); - tmp_dst += sizeof(n2n_mac_t); + tmp_dst += sizeof(n2n_mac_t); } ack.num_sn = num; - traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]", - macaddr_str(mac_buf, reg.edgeMac), - sock_to_cstr(sockbuf, &(ack.sock))); + traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]", + macaddr_str(mac_buf, reg.edgeMac), + sock_to_cstr(sockbuf, &(ack.sock))); if(memcmp(reg.edgeMac, &null_mac, N2N_MAC_SIZE) != 0) { update_edge(sss, ®, comm, &(ack.sock), now); @@ -1175,8 +1174,8 @@ if(comm) { if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx, - comm->header_iv_ctx, - time_stamp (), pearson_hash_16 (ackbuf, encx)); + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (ackbuf, encx)); sendto(sss->sock, ackbuf, encx, 0, (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in)); @@ -1185,9 +1184,9 @@ if(comm) { macaddr_str(mac_buf, reg.edgeMac), sock_to_cstr(sockbuf, &(ack.sock))); } else { - traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", - (char*)cmn.community); - return -1; + traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", + (char*)cmn.community); + return -1; } break; } @@ -1195,19 +1194,19 @@ if(comm) { n2n_REGISTER_SUPER_ACK_t ack; size_t encx=0; struct sn_community *fed; - struct peer_info *scan, *tmp; - n2n_sock_str_t sockbuf1; - n2n_sock_str_t sockbuf2; - macstr_t mac_buf1; - n2n_sock_t sender; - n2n_sock_t *orig_sender; - n2n_sock_t *tmp_sock; - n2n_mac_t *tmp_mac; - int i; - uint8_t dec_tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES]; - int skip_add; - - memset(&sender, 0, sizeof(n2n_sock_t)); + struct peer_info *scan, *tmp; + n2n_sock_str_t sockbuf1; + n2n_sock_str_t sockbuf2; + macstr_t mac_buf1; + n2n_sock_t sender; + n2n_sock_t *orig_sender; + n2n_sock_t *tmp_sock; + n2n_mac_t *tmp_mac; + int i; + uint8_t dec_tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES]; + int skip_add; + + memset(&sender, 0, sizeof(n2n_sock_t)); sender.family = AF_INET; sender.port = ntohs(sender_sock->sin_port); memcpy(&(sender.addr.v4), &(sender_sock->sin_addr.s_addr), IPV4_SIZE); @@ -1231,9 +1230,9 @@ if(comm) { if (comm) { if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, ack.edgeMac, stamp, TIME_STAMP_NO_JITTER)) { - traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to time stamp error."); - return -1; - } + traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to time stamp error."); + return -1; + } } } @@ -1243,13 +1242,13 @@ if(comm) { sock_to_cstr(sockbuf2, orig_sender)); if(comm->is_federation == IS_FEDERATION) { - skip_add = SKIP; - scan = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &sender, &(ack.edgeMac), &skip_add); + skip_add = SKIP; + scan = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &sender, &(ack.edgeMac), &skip_add); if(scan != NULL) { - scan->last_seen = now; + scan->last_seen = now; } else { - traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to an unknown supernode."); - break; + traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to an unknown supernode."); + break; } } @@ -1257,14 +1256,14 @@ if(comm) { tmp_mac = (void*)dec_tmpbuf + sizeof(n2n_sock_t); for(i=0; ifederation->edges), tmp_sock, tmp_mac, &skip_add); if(skip_add == ADDED) { - tmp->last_seen = now - TEST_TIME; + tmp->last_seen = now - TEST_TIME; } - /* REVISIT: find a more elegant expression to increase following pointers. */ + /* REVISIT: find a more elegant expression to increase following pointers. */ tmp_sock = (void*)tmp_sock + ENTRY_SIZE; tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t); } @@ -1272,90 +1271,114 @@ if(comm) { break; } case MSG_TYPE_QUERY_PEER: { - n2n_QUERY_PEER_t query; - uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; - size_t encx=0; - n2n_common_t cmn2; - n2n_PEER_INFO_t pi; + n2n_QUERY_PEER_t query; + uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx=0; + n2n_common_t cmn2; + n2n_PEER_INFO_t pi; + struct sn_community_regular_expression *re, *tmp_re; + struct peer_info *peer, *tmp_peer, *p; + int8_t allowed_match = -1; + uint8_t match = 0; + int match_length = 0; + + if(!comm && sss->lock_communities) { + HASH_ITER(hh, sss->rules, re, tmp_re) { + allowed_match = re_matchp(re->rule, (const char *)cmn.community, &match_length); + + if( (allowed_match != -1) + && (match_length == strlen((const char *)cmn.community)) // --- only full match… + && (allowed_match == 0)) { // --- only full matches allowed (re… + match = 1; + break; + } + } + if(match != 1) { + traceEvent(TRACE_DEBUG, "process_udp QUERY_PEER from unknown community %s", cmn.community); + return -1; + } + } - if(!comm) { - traceEvent(TRACE_DEBUG, "process_udp QUERY_PEER from unknown community %s", cmn.community); + if(!comm && sss->lock_communities && (match == 0)) { + traceEvent(TRACE_DEBUG, "process_udp QUERY_PEER from not allowed community %s", cmn.community); return -1; } decode_QUERY_PEER( &query, &cmn, udp_buf, &rem, &idx ); // already checked for valid comm - if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { - if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, query.srcMac, stamp, TIME_STAMP_ALLOW_JITTER)) { - traceEvent(TRACE_DEBUG, "process_udp dropped QUERY_PEER due to time stamp error."); - return -1; + if (comm) { + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, query.srcMac, stamp, TIME_STAMP_ALLOW_JITTER)) { + traceEvent(TRACE_DEBUG, "process_udp dropped QUERY_PEER due to time stamp error."); + return -1; + } } } if(memcmp(query.targetMac, null_mac, sizeof(n2n_mac_t)) == 0){ - traceEvent( TRACE_DEBUG, "Rx PING from %s. Requested data: %d", - macaddr_str( mac_buf, query.srcMac ), - query.req_data ); + traceEvent( TRACE_DEBUG, "Rx PING from %s. Requested data: %d", + macaddr_str( mac_buf, query.srcMac ), + query.req_data ); - cmn2.ttl = N2N_DEFAULT_TTL; + cmn2.ttl = N2N_DEFAULT_TTL; cmn2.pc = n2n_peer_info; cmn2.flags = N2N_FLAGS_FROM_SUPERNODE; memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) ); pi.aflags = 0; memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) ); - memcpy( pi.srcMac, sss->mac_addr, sizeof(n2n_mac_t) ); - - encode_PEER_INFO( encbuf, &encx, &cmn2, &pi ); - - if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) - packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx, - comm->header_iv_ctx, - time_stamp (), pearson_hash_16 (encbuf, encx)); + memcpy( pi.srcMac, sss->mac_addr, sizeof(n2n_mac_t) ); - sendto( sss->sock, encbuf, encx, 0, - (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) ); + encode_PEER_INFO( encbuf, &encx, &cmn2, &pi ); - traceEvent( TRACE_DEBUG, "Tx PING to %s", - macaddr_str( mac_buf, query.srcMac ) ); - - } else { - traceEvent( TRACE_DEBUG, "Rx QUERY_PEER from %s for %s", - macaddr_str( mac_buf, query.srcMac ), - macaddr_str( mac_buf2, query.targetMac ) ); - - struct peer_info *scan; - HASH_FIND_PEER(comm->edges, query.targetMac, scan); - - if (scan) { - cmn2.ttl = N2N_DEFAULT_TTL; - cmn2.pc = n2n_peer_info; - cmn2.flags = N2N_FLAGS_FROM_SUPERNODE; - memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) ); - - pi.aflags = 0; - memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) ); - pi.sock = scan->sock; - - encode_PEER_INFO( encbuf, &encx, &cmn2, &pi ); - - if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) - packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx, - comm->header_iv_ctx, - time_stamp (), pearson_hash_16 (encbuf, encx)); + if(comm){ + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx, + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (encbuf, encx)); + } - sendto( sss->sock, encbuf, encx, 0, - (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) ); + sendto( sss->sock, encbuf, encx, 0, + (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) ); - traceEvent( TRACE_DEBUG, "Tx PEER_INFO to %s", - macaddr_str( mac_buf, query.srcMac ) ); - } else { - traceEvent( TRACE_DEBUG, "Ignoring QUERY_PEER for unknown edge %s", - macaddr_str( mac_buf, query.targetMac ) ); - } + traceEvent( TRACE_DEBUG, "Tx PING to %s", + macaddr_str( mac_buf, query.srcMac ) ); - } + } else { + traceEvent( TRACE_DEBUG, "Rx QUERY_PEER from %s for %s", + macaddr_str( mac_buf, query.srcMac ), + macaddr_str( mac_buf2, query.targetMac ) ); + + struct peer_info *scan; + HASH_FIND_PEER(comm->edges, query.targetMac, scan); + if (scan) { + cmn2.ttl = N2N_DEFAULT_TTL; + cmn2.pc = n2n_peer_info; + cmn2.flags = N2N_FLAGS_FROM_SUPERNODE; + memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) ); + + pi.aflags = 0; + memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) ); + pi.sock = scan->sock; + + encode_PEER_INFO( encbuf, &encx, &cmn2, &pi ); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx, + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (encbuf, encx)); + + sendto( sss->sock, encbuf, encx, 0, + (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) ); + + traceEvent( TRACE_DEBUG, "Tx PEER_INFO to %s", + macaddr_str( mac_buf, query.srcMac ) ); + } else { + traceEvent( TRACE_DEBUG, "Ignoring QUERY_PEER for unknown edge %s", + macaddr_str( mac_buf, query.targetMac ) ); + } + } break; }