From e65fd984d70fc50e8a91dbd08aa4f6f393105be3 Mon Sep 17 00:00:00 2001 From: Francesco Carli <62562180+fcarli3@users.noreply.github.com> Date: Tue, 10 Nov 2020 16:34:49 +0100 Subject: [PATCH] Packet forwarding between supernodes (#486) * Packet forwarding between supernodes * Update wire.c --- include/n2n_define.h | 18 ++-- include/n2n_wire.h | 1 + src/edge_utils.c | 20 ++--- src/n2n.c | 8 +- src/sn.c | 2 +- src/sn_utils.c | 206 ++++++++++++++++++++++++++++--------------- src/wire.c | 4 +- 7 files changed, 165 insertions(+), 94 deletions(-) diff --git a/include/n2n_define.h b/include/n2n_define.h index 7cac1b5..c6aae29 100644 --- a/include/n2n_define.h +++ b/include/n2n_define.h @@ -32,23 +32,25 @@ /* Max available space to add supernodes' informations (sockets and MACs) in REGISTER_SUPER_ACK * Field sizes of REGISTER_SUPER_ACK as used in encode/decode fucntions in src/wire.c * REVISIT: replace 255 by DEFAULT_MTU as soon as header encryption allows for longer packets to be encrypted. */ -#define MAX_AVAILABLE_SPACE_FOR_ENTRIES \ +#define REG_SUPER_ACK_PAYLOAD_SPACE \ (255-(1+1+2+sizeof(n2n_common_t)+sizeof(n2n_cookie_t)+sizeof(n2n_mac_t)+1+2+4+1+sizeof(n2n_sock_t)+1)) \ /* Space needed to store socket and MAC address of a supernode */ -#define ENTRY_SIZE (sizeof(n2n_sock_t)+sizeof(n2n_mac_t)) +#define REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE (sizeof(n2n_sock_t)+sizeof(n2n_mac_t)) #define PURGE_REGISTRATION_FREQUENCY 30 #define RE_REG_AND_PURGE_FREQUENCY 10 #define REGISTRATION_TIMEOUT 60 -#define PURGE_FEDERATION_NODE_INTERVAL 90 #define SOCKET_TIMEOUT_INTERVAL_SECS 10 #define REGISTER_SUPER_INTERVAL_DFL 20 /* sec, usually UDP NAT entries in a firewall expire after 30 seconds */ -#define ALLOWED_TIME 20 /* sec, indicates supernodes that are proven to be alive */ -#define TEST_TIME (PURGE_FEDERATION_NODE_INTERVAL - ALLOWED_TIME)/2 /* sec, indicates supernodes with unsure status, must be tested to check if they are alive */ -#define MAX_PING_TIME 3000 /* millisec, indicates default value for ping_time field in peer_info structure */ -#define SWEEP_TIME 30 /* sec, indicates the value after which we have to sort the hash list of supernodes in edges */ +#define MAX_PING_TIME 3000 /* millisec, indicates default value for ping_time field in peer_info structure */ +#define SWEEP_TIME 30 /* sec, indicates the value after which we have to sort the hash list of supernodes in edges */ + +#define LAST_SEEN_SN_ACTIVE 20 /* sec, indicates supernodes that are proven to be active */ +#define LAST_SEEN_SN_INACTIVE 90 /* sec, indicates supernodes that are proven to be inactive: they will be purged */ +#define LAST_SEEN_SN_NEW (LAST_SEEN_SN_INACTIVE - LAST_SEEN_SN_ACTIVE)/2 /* sec, indicates supernodes with unsure status, must be tested to check if they are active */ + #define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */ #define TRANSOP_TICK_INTERVAL (10) /* sec */ @@ -108,7 +110,7 @@ enum sn_purge{SN_PURGEABLE = 0, SN_UNPURGEABLE = 1}; #define N2N_SN_MGMT_PORT 5645 /* flag used in add_sn_to_list_by_mac_or_sock */ -enum skip_add{NO_SKIP = 0, SKIP = 1, ADDED = 2}; +enum skip_add{SN_ADD = 0, SN_ADD_SKIP = 1, SN_ADD_ADDED = 2}; #define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */ #define N2N_MACNAMSIZ 18 /* AA:BB:CC:DD:EE:FF + NULL*/ diff --git a/include/n2n_wire.h b/include/n2n_wire.h index 86b75e2..72c65a7 100644 --- a/include/n2n_wire.h +++ b/include/n2n_wire.h @@ -195,6 +195,7 @@ typedef struct n2n_PEER_INFO { typedef struct n2n_QUERY_PEER { n2n_mac_t srcMac; + n2n_sock_t sock; n2n_mac_t targetMac; uint8_t req_data; /* data we want the supernode to send back in the answer's payload (e.g. 0 = no payload, 1 = number of connected nodes ...) */ } n2n_QUERY_PEER_t; diff --git a/src/edge_utils.c b/src/edge_utils.c index 11c1d1d..2c5bb0c 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -1956,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)); @@ -2005,10 +2005,10 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { tmp_mac = (void*)&tmpbuf[sizeof(n2n_sock_t)]; for(i=0; iconf.supernodes), tmp_sock, tmp_mac, &skip_add); - if(skip_add == ADDED){ + if(skip_add == SN_ADD_ADDED){ sn->ip_addr = calloc(1,N2N_EDGE_SN_HOST_SIZE); if(sn->ip_addr != NULL){ inet_ntop(tmp_sock->family, @@ -2085,7 +2085,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { } if(memcmp(pi.mac, null_mac, sizeof(n2n_mac_t)) == 0){ - skip_add = SKIP; + skip_add = SN_ADD_SKIP; scan = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), &sender, &pi.srcMac, &skip_add); if(scan != NULL){ scan->ping_time = (now - eee->last_sweep)*1000; @@ -2818,7 +2818,7 @@ int edge_conf_add_supernode(n2n_edge_conf_t *conf, const char *ip_and_port) { return(1); } - skip_add = NO_SKIP; + skip_add = SN_ADD; sn = add_sn_to_list_by_mac_or_sock(&(conf->supernodes), sock, (n2n_mac_t *)null_mac, &skip_add); if(sn != NULL){ diff --git a/src/n2n.c b/src/n2n.c index fa605cd..574d22a 100644 --- a/src/n2n.c +++ b/src/n2n.c @@ -301,21 +301,21 @@ struct peer_info* add_sn_to_list_by_mac_or_sock(struct peer_info **sn_list, n2n_ if(peer == NULL) { /* zero MAC, search by socket */ HASH_ITER(hh,*sn_list,scan,tmp) { if(memcmp(&(scan->sock), sock, sizeof(n2n_sock_t)) == 0) { - HASH_DEL(*sn_list, scan); + HASH_DEL(*sn_list, scan); memcpy(&(scan->mac_addr), mac, sizeof(n2n_mac_t)); - HASH_ADD_PEER(*sn_list, scan); + HASH_ADD_PEER(*sn_list, scan); peer = scan; break; } } - if((peer == NULL) && (*skip_add == NO_SKIP)) { + if((peer == NULL) && (*skip_add == SN_ADD)) { peer = (struct peer_info*)calloc(1,sizeof(struct peer_info)); if(peer) { memcpy(&(peer->sock),sock,sizeof(n2n_sock_t)); memcpy(&(peer->mac_addr),mac, sizeof(n2n_mac_t)); HASH_ADD_PEER(*sn_list, peer); - *skip_add = ADDED; + *skip_add = SN_ADD_ADDED; } } } diff --git a/src/sn.c b/src/sn.c index b09298b..a5f2085 100644 --- a/src/sn.c +++ b/src/sn.c @@ -276,7 +276,7 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) { if(sss->federation != NULL) { - skip_add = NO_SKIP; + skip_add = SN_ADD; anchor_sn = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), socket, (n2n_mac_t*) null_mac, &skip_add); if(anchor_sn != NULL){ diff --git a/src/sn_utils.c b/src/sn_utils.c index 3507131..40bfce8 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -25,7 +25,8 @@ static int try_forward(n2n_sn_t * sss, const n2n_common_t * cmn, const n2n_mac_t dstMac, const uint8_t * pktbuf, - size_t pktsize); + size_t pktsize, + uint8_t from_supernode); static ssize_t sendto_sock(n2n_sn_t *sss, const n2n_sock_t *sock, @@ -42,7 +43,8 @@ static int try_broadcast(n2n_sn_t * sss, const n2n_common_t * cmn, const n2n_mac_t srcMac, const uint8_t * pktbuf, - size_t pktsize); + size_t pktsize, + uint8_t from_supernode); static uint16_t reg_lifetime(n2n_sn_t *sss); @@ -81,7 +83,8 @@ static int try_forward(n2n_sn_t * sss, const n2n_common_t * cmn, const n2n_mac_t dstMac, const uint8_t * pktbuf, - size_t pktsize) + size_t pktsize, + uint8_t from_supernode) { struct peer_info * scan; macstr_t mac_buf; @@ -114,10 +117,15 @@ static int try_forward(n2n_sn_t * sss, } else { - traceEvent(TRACE_DEBUG, "try_forward unknown MAC"); - - /* Not a known MAC so drop. */ - return(-2); + if(!from_supernode){ + /* Forwarding packet to all federated supernodes. */ + traceEvent(TRACE_DEBUG, "Unknown MAC. Broadcasting packet to all federated supernodes."); + try_broadcast(sss, NULL, cmn, sss->mac_addr, pktbuf, pktsize, from_supernode); + } else { + traceEvent(TRACE_DEBUG, "try_forward unknown MAC. Dropping the packet."); + /* Not a known MAC so drop. */ + return(-2); + } } return(0); @@ -167,7 +175,8 @@ static int try_broadcast(n2n_sn_t * sss, const n2n_common_t * cmn, const n2n_mac_t srcMac, const uint8_t * pktbuf, - size_t pktsize) + size_t pktsize, + uint8_t from_supernode) { struct peer_info *scan, *tmp; macstr_t mac_buf; @@ -175,32 +184,63 @@ static int try_broadcast(n2n_sn_t * sss, traceEvent(TRACE_DEBUG, "try_broadcast"); - HASH_ITER(hh, comm->edges, scan, tmp) { - if(memcmp(srcMac, scan->mac_addr, sizeof(n2n_mac_t)) != 0) { - /* REVISIT: exclude if the destination socket is where the packet came from. */ + /* We have to make sure that a broadcast reaches the other supernodes and edges + * connected to them. try_broadcast needs a from_supernode parameter: if set + * do forward to edges of community only. If unset. forward to all locally known + * nodes and all supernodes */ + + if (!from_supernode) { + HASH_ITER(hh, sss->federation->edges, scan, tmp) { int data_sent_len; data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize); if(data_sent_len != pktsize) - { - ++(sss->stats.errors); - traceEvent(TRACE_WARNING, "multicast %lu to [%s] %s failed %s", + { + ++(sss->stats.errors); + traceEvent(TRACE_WARNING, "multicast %lu to supernode [%s] %s failed %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr), + strerror(errno)); + } + else + { + ++(sss->stats.broadcast); + traceEvent(TRACE_DEBUG, "multicast %lu to supernode [%s] %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr)); + } + } + } + + if(comm){ + HASH_ITER(hh, comm->edges, scan, tmp) { + if(memcmp(srcMac, scan->mac_addr, sizeof(n2n_mac_t)) != 0) { + /* REVISIT: exclude if the destination socket is where the packet came from. */ + int data_sent_len; + + data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize); + + if(data_sent_len != pktsize){ + ++(sss->stats.errors); + traceEvent(TRACE_WARNING, "multicast %lu to [%s] %s failed %s", pktsize, sock_to_cstr(sockbuf, &(scan->sock)), macaddr_str(mac_buf, scan->mac_addr), strerror(errno)); + } else { + ++(sss->stats.broadcast); + traceEvent(TRACE_DEBUG, "multicast %lu to [%s] %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr)); + } } - else - { - ++(sss->stats.broadcast); - traceEvent(TRACE_DEBUG, "multicast %lu to [%s] %s", - pktsize, - sock_to_cstr(sockbuf, &(scan->sock)), - macaddr_str(mac_buf, scan->mac_addr)); - } - } + } } + return 0; } @@ -251,7 +291,7 @@ int sn_init(n2n_sn_t *sss) { sss->federation->header_encryption = HEADER_ENCRYPTION_ENABLED; /*setup the encryption key */ packet_header_setup_key(sss->federation->community, &(sss->federation->header_encryption_ctx), &(sss->federation->header_iv_ctx)); - sss->federation->edges = NULL; + sss->federation->edges = NULL; } n2n_srand (n2n_seed()); @@ -534,9 +574,9 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community * if(comm != NULL) { HASH_ITER(hh,comm->edges,peer,tmp) { time = now - peer->last_seen; - if(time <= ALLOWED_TIME) continue; + if(time <= LAST_SEEN_SN_ACTIVE) continue; - if((time < PURGE_FEDERATION_NODE_INTERVAL) + if((time < LAST_SEEN_SN_INACTIVE) || (peer->purgeable == SN_UNPURGEABLE) ) { /* re-regitser (send REGISTER_SUPER) */ @@ -579,7 +619,7 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community * /* sent = */ sendto_sock(sss, &(peer->sock), pktbuf, idx); } - if(time >= PURGE_FEDERATION_NODE_INTERVAL) purge_expired_registrations(&(comm->edges),&time,PURGE_FEDERATION_NODE_INTERVAL);/* purge not-seen-long-time supernodes*/ + if(time >= LAST_SEEN_SN_INACTIVE) purge_expired_registrations(&(comm->edges), &time, LAST_SEEN_SN_INACTIVE);/* purge not-seen-long-time supernodes*/ } } @@ -692,8 +732,8 @@ 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)); @@ -955,9 +995,9 @@ static int process_udp(n2n_sn_t * sss, /* Common section to forward the final product. */ if(unicast) - try_forward(sss, comm, &cmn, pkt.dstMac, rec_buf, encx); + try_forward(sss, comm, &cmn, pkt.dstMac, rec_buf, encx, from_supernode); else - try_broadcast(sss, comm, &cmn, pkt.srcMac, rec_buf, encx); + try_broadcast(sss, comm, &cmn, pkt.srcMac, rec_buf, encx, from_supernode); break; } case MSG_TYPE_REGISTER: @@ -1022,7 +1062,7 @@ static int process_udp(n2n_sn_t * sss, comm->header_iv_ctx, time_stamp (), pearson_hash_16 (rec_buf, encx)); - try_forward(sss, comm, &cmn, reg.dstMac, rec_buf, encx); /* unicast only */ + try_forward(sss, comm, &cmn, reg.dstMac, rec_buf, encx, from_supernode); /* unicast only */ } else traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination"); break; @@ -1036,17 +1076,17 @@ 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 tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE]; 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 num = 0; int skip_add; memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); @@ -1117,9 +1157,9 @@ static int process_udp(n2n_sn_t * sss, memcpy(&(ack.cookie), &(reg.cookie), sizeof(n2n_cookie_t)); if(comm->is_federation == IS_FEDERATION){ - memcpy(&(ack.edgeMac), &(sss->mac_addr), sizeof(n2n_mac_t)); - }else{ - memcpy(&(ack.edgeMac), &(reg.edgeMac), sizeof(n2n_mac_t)); + memcpy(&(ack.edgeMac), &(sss->mac_addr), sizeof(n2n_mac_t)); + } else { + memcpy(&(ack.edgeMac), &(reg.edgeMac), sizeof(n2n_mac_t)); } if ((reg.dev_addr.net_addr == 0) || (reg.dev_addr.net_addr == 0xFFFFFFFF) || (reg.dev_addr.net_bitlen == 0) || @@ -1142,7 +1182,7 @@ static int process_udp(n2n_sn_t * sss, /* Add sender's data to federation (or update it) */ if(comm->is_federation == IS_FEDERATION) { - skip_add = NO_SKIP; + skip_add = SN_ADD; p = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &(ack.sock), &(reg.edgeMac), &skip_add); } @@ -1152,8 +1192,8 @@ static int process_udp(n2n_sn_t * sss, 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((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 */ + if((now - peer->last_seen) >= LAST_SEEN_SN_ACTIVE) continue; /* skip long-time-not-seen supernodes */ + if(((++num)*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE) > REG_SUPER_ACK_PAYLOAD_SPACE) 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); memcpy((void*)tmp_dst, (void*)&(peer->mac_addr), sizeof(n2n_mac_t)); @@ -1194,19 +1234,19 @@ static int process_udp(n2n_sn_t * sss, n2n_REGISTER_SUPER_ACK_t ack; size_t encx=0; struct sn_community *fed; - struct peer_info *scan, *tmp_peer; - 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[REG_SUPER_ACK_PAYLOAD_SPACE]; + int skip_add; + + memset(&sender, 0, sizeof(n2n_sock_t)); sender.family = AF_INET; sender.port = ntohs(sender_sock->sin_port); @@ -1243,7 +1283,7 @@ static int process_udp(n2n_sn_t * sss, sock_to_cstr(sockbuf2, orig_sender)); if(comm->is_federation == IS_FEDERATION) { - skip_add = SKIP; + skip_add = SN_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; @@ -1257,15 +1297,15 @@ static int process_udp(n2n_sn_t * sss, tmp_mac = (void*)dec_tmpbuf + sizeof(n2n_sock_t); for(i=0; ifederation->edges), tmp_sock, tmp_mac, &skip_add); + skip_add = SN_ADD; + tmp = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), tmp_sock, tmp_mac, &skip_add); - if(skip_add == ADDED) { - tmp_peer->last_seen = now - TEST_TIME; + if(skip_add == SN_ADD_ADDED) { + tmp->last_seen = now - LAST_SEEN_SN_NEW; } /* REVISIT: find a more elegant expression to increase following pointers. */ - tmp_sock = (void*)tmp_sock + ENTRY_SIZE; + tmp_sock = (void*)tmp_sock + REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE; tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t); } @@ -1278,10 +1318,11 @@ static int process_udp(n2n_sn_t * sss, n2n_common_t cmn2; n2n_PEER_INFO_t pi; 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; + uint8_t *rec_buf; /* either udp_buf or encbuf */ if(!comm && sss->lock_communities) { HASH_ITER(hh, sss->rules, re, tmp_re) { @@ -1370,14 +1411,41 @@ static int process_udp(n2n_sn_t * sss, 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", + if(cmn.flags & N2N_FLAGS_SOCKET){ + sendto_sock(sss, &query.sock, encbuf, encx); + } else { + 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 ) ); + + if(from_supernode){ + traceEvent( TRACE_DEBUG, "QUERY_PEER on unknown edge from supernode %s. Dropping the packet.", + macaddr_str( mac_buf, query.srcMac ) ); + } else { + traceEvent( TRACE_DEBUG, "QUERY_PEER from unknown edge %s. Forwarding to all other supernodes.", + macaddr_str( mac_buf, query.srcMac ) ); + + memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); + + /* We are going to add socket even if it was not there before */ + cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; + query.sock.family = AF_INET; + query.sock.port = ntohs(sender_sock->sin_port); + memcpy(query.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + + encode_QUERY_PEER( encbuf, &encx, &cmn2, &query ); + + 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)); + + try_broadcast(sss, NULL, &cmn, query.srcMac, encbuf, encx, from_supernode); + } } } diff --git a/src/wire.c b/src/wire.c index 9103129..6c1a1cb 100644 --- a/src/wire.c +++ b/src/wire.c @@ -410,7 +410,7 @@ int encode_REGISTER_SUPER_ACK(uint8_t *base, retval += encode_uint16(base, idx, reg->lifetime); retval += encode_sock(base, idx, &(reg->sock)); retval += encode_uint8(base, idx, reg->num_sn); - retval += encode_buf(base, idx, tmpbuf, (reg->num_sn*ENTRY_SIZE)); + retval += encode_buf(base, idx, tmpbuf, (reg->num_sn*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE)); return retval; } @@ -436,7 +436,7 @@ int decode_REGISTER_SUPER_ACK(n2n_REGISTER_SUPER_ACK_t *reg, /* Following the edge socket are an array of backup supernodes. */ retval += decode_uint8(&(reg->num_sn), base, rem, idx); - retval += decode_buf(tmpbuf, (reg->num_sn*ENTRY_SIZE), base, rem, idx); + retval += decode_buf(tmpbuf, (reg->num_sn*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE), base, rem, idx); return retval; }