Browse Source

Fixes federation bug (#480)

* Fixes federation bug

* Fixes federation bug

* Update edge_utils.c
pull/491/head
Francesco Carli 4 years ago
committed by GitHub
parent
commit
e48f1fcc73
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 98
      src/edge_utils.c
  2. 311
      src/sn_utils.c

98
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; eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS;
traceEvent(TRACE_INFO, "Registering with supernode [%s][number of supernodes %d][attempts left %u]", 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); send_register_super(eee);
eee->sn_wait = 1; eee->sn_wait = 1;
@ -819,13 +819,14 @@ static int sort_supernodes(n2n_edge_t *eee, time_t now){
// this routine gets periodically called // this routine gets periodically called
// it sorts supernodes in ascending order of their ping_time-fields // it sorts supernodes in ascending order of their ping_time-fields
HASH_SORT(eee->conf.supernodes, ping_time_sort); HASH_SORT(eee->conf.supernodes, ping_time_sort);
eee->last_sweep = now; }
HASH_ITER(hh, eee->conf.supernodes, scan, tmp){ HASH_ITER(hh, eee->conf.supernodes, scan, tmp){
scan->ping_time = MAX_PING_TIME; scan->ping_time = MAX_PING_TIME;
}
} }
send_query_peer(eee, null_mac); send_query_peer(eee, null_mac);
eee->last_sweep = now;
} }
return 0; /* OK */ return 0; /* OK */
@ -1337,9 +1338,9 @@ static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) {
"community: %s\n", "community: %s\n",
eee->conf.community_name); eee->conf.community_name);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), 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), 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), msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"supernode_forward:\n"); "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; if(peer->dev_addr.net_addr == 0) continue;
net = htonl(peer->dev_addr.net_addr); net = htonl(peer->dev_addr.net_addr);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), 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), ++num, inet_ntoa(*(struct in_addr *) &net),
macaddr_str(mac_buf, peer->mac_addr), macaddr_str(mac_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)), sock_to_cstr(sockbuf, &(peer->sock)),
peer->dev_desc, peer->dev_desc,
now - peer->last_seen); 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; if(peer->dev_addr.net_addr == 0) continue;
net = htonl(peer->dev_addr.net_addr); net = htonl(peer->dev_addr.net_addr);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), 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), ++num, inet_ntoa(*(struct in_addr *) &net),
macaddr_str(mac_buf, peer->mac_addr), macaddr_str(mac_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)), sock_to_cstr(sockbuf, &(peer->sock)),
peer->dev_desc, peer->dev_desc,
now - peer->last_seen); now - peer->last_seen);
@ -1955,12 +1956,12 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
in_addr_t net; in_addr_t net;
char * ip_str = NULL; char * ip_str = NULL;
n2n_REGISTER_SUPER_ACK_t ra; n2n_REGISTER_SUPER_ACK_t ra;
uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES]; uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES];
n2n_sock_t *tmp_sock; n2n_sock_t *tmp_sock;
n2n_mac_t *tmp_mac; n2n_mac_t *tmp_mac;
int i; int i;
int skip_add; int skip_add;
struct peer_info *sn; struct peer_info *sn;
memset(&ra, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); 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)) if(0 == memcmp(ra.cookie, eee->curr_sn->last_cookie, N2N_COOKIE_SIZE))
{ {
tmp_sock = (void*)&tmpbuf; tmp_sock = (void*)&tmpbuf;
tmp_mac = (void*)&tmpbuf[sizeof(n2n_sock_t)]; tmp_mac = (void*)&tmpbuf[sizeof(n2n_sock_t)];
for(i=0; i<ra.num_sn; i++){ for(i=0; i<ra.num_sn; i++){
skip_add = NO_SKIP; skip_add = NO_SKIP;
sn = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), tmp_sock, tmp_mac, &skip_add); sn = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), tmp_sock, tmp_mac, &skip_add);
if(skip_add == ADDED){
traceEvent(TRACE_NORMAL, "Supernode added to the list of supernodes."); if(skip_add == ADDED){
} sn->ip_addr = calloc(1,N2N_EDGE_SN_HOST_SIZE);
if(sn->ip_addr != NULL){
/* REVISIT: find a more elegant expression to increase following pointers. */ inet_ntop(tmp_sock->family,
tmp_sock = (void*)tmp_sock + ENTRY_SIZE; (tmp_sock->family == AF_INET)?(void*)&tmp_sock->addr.v4:(void*)&tmp_sock->addr.v6,
tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t); 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->last_sup = now;
eee->sn_wait=0; eee->sn_wait=0;
@ -2040,7 +2050,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
* based on its NAT configuration. */ * based on its NAT configuration. */
//eee->conf.register_interval = ra.lifetime; //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 else
{ {
@ -2068,10 +2078,10 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
} }
if(!is_valid_peer_sock(&pi.sock)) { if(!is_valid_peer_sock(&pi.sock)) {
traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]", traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]",
sock_to_cstr(sockbuf1, &pi.sock), sock_to_cstr(sockbuf1, &pi.sock),
macaddr_str(mac_buf1, pi.mac) ); macaddr_str(mac_buf1, pi.mac) );
break; break;
} }
if(memcmp(pi.mac, null_mac, sizeof(n2n_mac_t)) == 0){ 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); HASH_FIND_PEER(eee->pending_peers, pi.mac, scan);
if(scan) { if(scan) {
scan->sock = pi.sock; scan->sock = pi.sock;
traceEvent(TRACE_INFO, "Rx PEER_INFO for %s: is at %s", traceEvent(TRACE_INFO, "Rx PEER_INFO for %s: is at %s",
macaddr_str(mac_buf1, pi.mac), macaddr_str(mac_buf1, pi.mac),
sock_to_cstr(sockbuf1, &pi.sock)); sock_to_cstr(sockbuf1, &pi.sock));
send_register(eee, &scan->sock, scan->mac_addr); send_register(eee, &scan->sock, scan->mac_addr);
} else { } else {
traceEvent(TRACE_INFO, "Rx PEER_INFO unknown peer %s", traceEvent(TRACE_INFO, "Rx PEER_INFO unknown peer %s",
macaddr_str(mac_buf1, pi.mac) ); macaddr_str(mac_buf1, pi.mac) );
} }
} }
break; break;
@ -2770,7 +2780,7 @@ void edge_init_conf_defaults(n2n_edge_conf_t *conf) {
conf->register_interval = REGISTER_SUPER_INTERVAL_DFL; conf->register_interval = REGISTER_SUPER_INTERVAL_DFL;
conf->tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN; conf->tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN;
/* reserve possible last char as null terminator. */ /* 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")) { if (getenv("N2N_KEY")) {
conf->encrypt_key = strdup(getenv("N2N_KEY")); conf->encrypt_key = strdup(getenv("N2N_KEY"));

311
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)); memcpy(&(scan->mac_addr), reg->edgeMac, sizeof(n2n_mac_t));
scan->dev_addr.net_addr = reg->dev_addr.net_addr; scan->dev_addr.net_addr = reg->dev_addr.net_addr;
scan->dev_addr.net_bitlen = reg->dev_addr.net_bitlen; 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)); memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
scan->last_valid_time_stamp = initial_time_stamp(); 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; time_t time;
struct peer_info *peer, *tmp; 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) { if(comm != NULL) {
HASH_ITER(hh,comm->edges,peer,tmp) { 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 */ return 0; /* OK */
} }
@ -665,10 +665,10 @@ static int process_mgmt(n2n_sn_t *sss,
traceEvent(TRACE_DEBUG, "process_mgmt"); 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, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
" id tun_tap MAC edge hint last_seen\n"); "-------------------------------------------------------------------------------------------------\n");
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"-------------------------------------------------------------------------------------------------\n");
HASH_ITER(hh, sss->communities, community, tmp) { HASH_ITER(hh, sss->communities, community, tmp) {
num_edges += HASH_COUNT(community->edges); num_edges += HASH_COUNT(community->edges);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
@ -678,11 +678,11 @@ static int process_mgmt(n2n_sn_t *sss,
num = 0; num = 0;
HASH_ITER(hh, community->edges, peer, tmpPeer) { 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", " %-4u %-18s %-17s %-21s %-15s %lu\n",
++num, ip_subnet_to_str(ip_bit_str, &peer->dev_addr), ++num, ip_subnet_to_str(ip_bit_str, &peer->dev_addr),
macaddr_str(mac_buf, peer->mac_addr), macaddr_str(mac_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)), sock_to_cstr(sockbuf, &(peer->sock)),
peer->dev_desc, peer->dev_desc,
now - peer->last_seen); 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, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"-------------------------------------------------------------------------------------------------\n"); "---------------------------------------------------------------------------------\n");
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"uptime %lu | ", (now - sss->start_time)); "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_REGISTER_SUPER_ACK_t ack;
n2n_common_t cmn2; n2n_common_t cmn2;
uint8_t ackbuf[N2N_SN_PKTBUF_SIZE]; uint8_t ackbuf[N2N_SN_PKTBUF_SIZE];
uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES]; uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES];
uint8_t *tmp_dst; uint8_t *tmp_dst;
size_t encx=0; size_t encx=0;
struct sn_community *fed; struct sn_community *fed;
struct sn_community_regular_expression *re, *tmp_re; 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; int8_t allowed_match = -1;
uint8_t match = 0; uint8_t match = 0;
int match_length = 0; int match_length = 0;
n2n_ip_subnet_t ipaddr; n2n_ip_subnet_t ipaddr;
int num = 0; int num = 0;
int skip_add; int skip_add;
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
@ -1057,13 +1057,13 @@ static int process_udp(n2n_sn_t * sss,
decode_REGISTER_SUPER(&reg, &cmn, udp_buf, &rem, &idx); decode_REGISTER_SUPER(&reg, &cmn, udp_buf, &rem, &idx);
if (comm) { if (comm) {
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { 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)) { 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."); traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER due to time stamp error.");
return -1; return -1;
} }
} }
} }
/* /*
Before we move any further, we need to check if the requested 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) { if(!comm && sss->lock_communities) {
HASH_ITER(hh, sss->rules, re, tmp_re) { 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) && (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) && (allowed_match == 0)) { // --- only full matches allowed (remove, if also partial matches wanted)
match = 1; match = 1;
break; break;
} }
} }
if(match != 1) { if(match != 1) {
traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", 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))) { 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) {
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) {
cmn2.ttl = N2N_DEFAULT_TTL; cmn2.ttl = N2N_DEFAULT_TTL;
cmn2.pc = n2n_register_super_ack; cmn2.pc = n2n_register_super_ack;
cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; 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); memcpy(ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE);
if((from_supernode == 0) != (comm->is_federation == IS_NO_FEDERATION)) { 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"); traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER: from_supernode value doesn't correspond to the internal federation marking");
return -1; return -1;
} }
/* Add sender's data to federation (or update it) */ /* Add sender's data to federation (or update it) */
if(comm->is_federation == IS_FEDERATION) { 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); 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 */ /* Assembling supernode list for REGISTER_SUPER_ACK payload */
tmp_dst = tmpbuf; tmp_dst = tmpbuf;
HASH_ITER(hh, sss->federation->edges, peer, tmp_peer) { 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((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(((++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)); 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)); 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; ack.num_sn = num;
traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]", traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]",
macaddr_str(mac_buf, reg.edgeMac), macaddr_str(mac_buf, reg.edgeMac),
sock_to_cstr(sockbuf, &(ack.sock))); sock_to_cstr(sockbuf, &(ack.sock)));
if(memcmp(reg.edgeMac, &null_mac, N2N_MAC_SIZE) != 0) { if(memcmp(reg.edgeMac, &null_mac, N2N_MAC_SIZE) != 0) {
update_edge(sss, &reg, comm, &(ack.sock), now); update_edge(sss, &reg, comm, &(ack.sock), now);
@ -1175,8 +1174,8 @@ if(comm) {
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx, packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx,
comm->header_iv_ctx, comm->header_iv_ctx,
time_stamp (), pearson_hash_16 (ackbuf, encx)); time_stamp (), pearson_hash_16 (ackbuf, encx));
sendto(sss->sock, ackbuf, encx, 0, sendto(sss->sock, ackbuf, encx, 0,
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in)); (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in));
@ -1185,9 +1184,9 @@ if(comm) {
macaddr_str(mac_buf, reg.edgeMac), macaddr_str(mac_buf, reg.edgeMac),
sock_to_cstr(sockbuf, &(ack.sock))); sock_to_cstr(sockbuf, &(ack.sock)));
} else { } else {
traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'",
(char*)cmn.community); (char*)cmn.community);
return -1; return -1;
} }
break; break;
} }
@ -1195,19 +1194,19 @@ if(comm) {
n2n_REGISTER_SUPER_ACK_t ack; n2n_REGISTER_SUPER_ACK_t ack;
size_t encx=0; size_t encx=0;
struct sn_community *fed; struct sn_community *fed;
struct peer_info *scan, *tmp; struct peer_info *scan, *tmp;
n2n_sock_str_t sockbuf1; n2n_sock_str_t sockbuf1;
n2n_sock_str_t sockbuf2; n2n_sock_str_t sockbuf2;
macstr_t mac_buf1; macstr_t mac_buf1;
n2n_sock_t sender; n2n_sock_t sender;
n2n_sock_t *orig_sender; n2n_sock_t *orig_sender;
n2n_sock_t *tmp_sock; n2n_sock_t *tmp_sock;
n2n_mac_t *tmp_mac; n2n_mac_t *tmp_mac;
int i; int i;
uint8_t dec_tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES]; uint8_t dec_tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES];
int skip_add; int skip_add;
memset(&sender, 0, sizeof(n2n_sock_t)); memset(&sender, 0, sizeof(n2n_sock_t));
sender.family = AF_INET; sender.family = AF_INET;
sender.port = ntohs(sender_sock->sin_port); sender.port = ntohs(sender_sock->sin_port);
memcpy(&(sender.addr.v4), &(sender_sock->sin_addr.s_addr), IPV4_SIZE); memcpy(&(sender.addr.v4), &(sender_sock->sin_addr.s_addr), IPV4_SIZE);
@ -1231,9 +1230,9 @@ if(comm) {
if (comm) { if (comm) {
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { 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)) { 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."); traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to time stamp error.");
return -1; return -1;
} }
} }
} }
@ -1243,13 +1242,13 @@ if(comm) {
sock_to_cstr(sockbuf2, orig_sender)); sock_to_cstr(sockbuf2, orig_sender));
if(comm->is_federation == IS_FEDERATION) { if(comm->is_federation == IS_FEDERATION) {
skip_add = SKIP; skip_add = SKIP;
scan = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &sender, &(ack.edgeMac), &skip_add); scan = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &sender, &(ack.edgeMac), &skip_add);
if(scan != NULL) { if(scan != NULL) {
scan->last_seen = now; scan->last_seen = now;
} else { } else {
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to an unknown supernode."); traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to an unknown supernode.");
break; break;
} }
} }
@ -1257,14 +1256,14 @@ if(comm) {
tmp_mac = (void*)dec_tmpbuf + sizeof(n2n_sock_t); tmp_mac = (void*)dec_tmpbuf + sizeof(n2n_sock_t);
for(i=0; i<ack.num_sn; i++) { for(i=0; i<ack.num_sn; i++) {
skip_add = NO_SKIP; skip_add = NO_SKIP;
tmp = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), tmp_sock, tmp_mac, &skip_add); tmp = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), tmp_sock, tmp_mac, &skip_add);
if(skip_add == ADDED) { 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_sock = (void*)tmp_sock + ENTRY_SIZE;
tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t); tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t);
} }
@ -1272,90 +1271,114 @@ if(comm) {
break; break;
} }
case MSG_TYPE_QUERY_PEER: { case MSG_TYPE_QUERY_PEER: {
n2n_QUERY_PEER_t query; n2n_QUERY_PEER_t query;
uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; uint8_t encbuf[N2N_SN_PKTBUF_SIZE];
size_t encx=0; size_t encx=0;
n2n_common_t cmn2; n2n_common_t cmn2;
n2n_PEER_INFO_t pi; 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) { if(!comm && sss->lock_communities && (match == 0)) {
traceEvent(TRACE_DEBUG, "process_udp QUERY_PEER from unknown community %s", cmn.community); traceEvent(TRACE_DEBUG, "process_udp QUERY_PEER from not allowed community %s", cmn.community);
return -1; return -1;
} }
decode_QUERY_PEER( &query, &cmn, udp_buf, &rem, &idx ); decode_QUERY_PEER( &query, &cmn, udp_buf, &rem, &idx );
// already checked for valid comm // already checked for valid comm
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { if (comm) {
if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, query.srcMac, stamp, TIME_STAMP_ALLOW_JITTER)) { if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
traceEvent(TRACE_DEBUG, "process_udp dropped QUERY_PEER due to time stamp error."); if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, query.srcMac, stamp, TIME_STAMP_ALLOW_JITTER)) {
return -1; 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){ if(memcmp(query.targetMac, null_mac, sizeof(n2n_mac_t)) == 0){
traceEvent( TRACE_DEBUG, "Rx PING from %s. Requested data: %d", traceEvent( TRACE_DEBUG, "Rx PING from %s. Requested data: %d",
macaddr_str( mac_buf, query.srcMac ), macaddr_str( mac_buf, query.srcMac ),
query.req_data ); query.req_data );
cmn2.ttl = N2N_DEFAULT_TTL; cmn2.ttl = N2N_DEFAULT_TTL;
cmn2.pc = n2n_peer_info; cmn2.pc = n2n_peer_info;
cmn2.flags = N2N_FLAGS_FROM_SUPERNODE; cmn2.flags = N2N_FLAGS_FROM_SUPERNODE;
memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) ); memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) );
pi.aflags = 0; pi.aflags = 0;
memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) ); memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) );
memcpy( pi.srcMac, sss->mac_addr, 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));
sendto( sss->sock, encbuf, encx, 0, encode_PEER_INFO( encbuf, &encx, &cmn2, &pi );
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) );
traceEvent( TRACE_DEBUG, "Tx PING to %s", if(comm){
macaddr_str( mac_buf, query.srcMac ) ); if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx,
} else { comm->header_iv_ctx,
traceEvent( TRACE_DEBUG, "Rx QUERY_PEER from %s for %s", time_stamp (), pearson_hash_16 (encbuf, encx));
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, sendto( sss->sock, encbuf, encx, 0,
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) ); (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) );
traceEvent( TRACE_DEBUG, "Tx PEER_INFO to %s", traceEvent( TRACE_DEBUG, "Tx PING to %s",
macaddr_str( mac_buf, query.srcMac ) ); macaddr_str( mac_buf, query.srcMac ) );
} else {
traceEvent( TRACE_DEBUG, "Ignoring QUERY_PEER for unknown edge %s",
macaddr_str( mac_buf, query.targetMac ) );
}
} } 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; break;
} }

Loading…
Cancel
Save