|
|
@ -26,8 +26,7 @@ static int try_forward(n2n_sn_t * sss, |
|
|
|
const n2n_mac_t dstMac, |
|
|
|
uint8_t from_supernode, |
|
|
|
const uint8_t * pktbuf, |
|
|
|
size_t pktsize, |
|
|
|
uint8_t from_supernode); |
|
|
|
size_t pktsize); |
|
|
|
|
|
|
|
static ssize_t sendto_sock(n2n_sn_t *sss, |
|
|
|
const n2n_sock_t *sock, |
|
|
@ -45,8 +44,7 @@ static int try_broadcast(n2n_sn_t * sss, |
|
|
|
const n2n_mac_t srcMac, |
|
|
|
uint8_t from_supernode, |
|
|
|
const uint8_t * pktbuf, |
|
|
|
size_t pktsize, |
|
|
|
uint8_t from_supernode); |
|
|
|
size_t pktsize); |
|
|
|
|
|
|
|
static uint16_t reg_lifetime(n2n_sn_t *sss); |
|
|
|
|
|
|
@ -86,8 +84,7 @@ static int try_forward(n2n_sn_t * sss, |
|
|
|
const n2n_mac_t dstMac, |
|
|
|
uint8_t from_supernode, |
|
|
|
const uint8_t * pktbuf, |
|
|
|
size_t pktsize, |
|
|
|
uint8_t from_supernode) |
|
|
|
size_t pktsize) |
|
|
|
{ |
|
|
|
struct peer_info * scan; |
|
|
|
macstr_t mac_buf; |
|
|
@ -181,8 +178,7 @@ static int try_broadcast(n2n_sn_t * sss, |
|
|
|
const n2n_mac_t srcMac, |
|
|
|
uint8_t from_supernode, |
|
|
|
const uint8_t * pktbuf, |
|
|
|
size_t pktsize, |
|
|
|
uint8_t from_supernode) |
|
|
|
size_t pktsize) |
|
|
|
{ |
|
|
|
struct peer_info *scan, *tmp; |
|
|
|
macstr_t mac_buf; |
|
|
@ -236,15 +232,15 @@ static int try_broadcast(n2n_sn_t * sss, |
|
|
|
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; |
|
|
@ -711,9 +707,9 @@ static int process_mgmt(n2n_sn_t *sss, |
|
|
|
|
|
|
|
traceEvent(TRACE_DEBUG, "process_mgmt"); |
|
|
|
|
|
|
|
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"); |
|
|
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, |
|
|
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, |
|
|
|
"-------------------------------------------------------------------------------------------------\n"); |
|
|
|
HASH_ITER(hh, sss->communities, community, tmp) { |
|
|
|
num_edges += HASH_COUNT(community->edges); |
|
|
@ -724,13 +720,13 @@ 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)), |
|
|
|
peer->dev_desc, |
|
|
|
now - peer->last_seen); |
|
|
|
sock_to_cstr(sockbuf, &(peer->sock)), |
|
|
|
peer->dev_desc, |
|
|
|
now - peer->last_seen); |
|
|
|
|
|
|
|
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); |
|
|
|
ressize = 0; |
|
|
@ -1001,9 +997,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, from_supernode, rec_buf, encx); |
|
|
|
try_forward(sss, comm, &cmn, pkt.dstMac, from_supernode, rec_buf, encx); |
|
|
|
else |
|
|
|
try_broadcast(sss, comm, &cmn, pkt.srcMac, from_supernode, rec_buf, encx); |
|
|
|
try_broadcast(sss, comm, &cmn, pkt.srcMac, from_supernode, rec_buf, encx); |
|
|
|
break; |
|
|
|
} |
|
|
|
case MSG_TYPE_REGISTER: |
|
|
@ -1119,15 +1115,15 @@ 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); |
|
|
|
HASH_ITER(hh, sss->rules, re, tmp_re) { |
|
|
|
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'", |
|
|
@ -1136,25 +1132,25 @@ 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); |
|
|
|
} |
|
|
|
} |
|
|
|
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); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(comm) { |
|
|
|
if(comm) { |
|
|
|
cmn2.ttl = N2N_DEFAULT_TTL; |
|
|
|
cmn2.pc = n2n_register_super_ack; |
|
|
|
cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; |
|
|
@ -1233,8 +1229,8 @@ static int process_udp(n2n_sn_t * sss, |
|
|
|
|
|
|
|
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)); |
|
|
@ -1348,8 +1344,8 @@ static int process_udp(n2n_sn_t * sss, |
|
|
|
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_length == strlen((const char *)cmn.community)) // --- only full match…
|
|
|
|
&& (allowed_match == 0)) { // --- only full matches allowed (re…
|
|
|
|
match = 1; |
|
|
|
break; |
|
|
|
} |
|
|
@ -1416,60 +1412,60 @@ static int process_udp(n2n_sn_t * sss, |
|
|
|
|
|
|
|
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; |
|
|
|
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) ); |
|
|
|
|
|
|
|
encode_PEER_INFO( encbuf, &encx, &cmn2, &pi); |
|
|
|
pi.aflags = 0; |
|
|
|
memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) ); |
|
|
|
pi.sock = scan->sock; |
|
|
|
|
|
|
|
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)); |
|
|
|
encode_PEER_INFO( encbuf, &encx, &cmn2, &pi); |
|
|
|
|
|
|
|
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 ) ); |
|
|
|
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(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 ) ); |
|
|
|
|
|
|
|
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 ) ); |
|
|
|
} else { |
|
|
|
|
|
|
|
memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); |
|
|
|
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 ) ); |
|
|
|
|
|
|
|
/* 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); |
|
|
|
memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); |
|
|
|
|
|
|
|
encode_QUERY_PEER( encbuf, &encx, &cmn2, &query ); |
|
|
|
/* 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); |
|
|
|
|
|
|
|
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)); |
|
|
|
encode_QUERY_PEER( encbuf, &encx, &cmn2, &query ); |
|
|
|
|
|
|
|
try_broadcast(sss, NULL, &cmn, query.srcMac, from_supernode, encbuf, encx); |
|
|
|
} |
|
|
|
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, from_supernode, encbuf, encx); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|