sn_utils.c (n2n-3.0) | : | sn_utils.c (n2n-3.1.1) | ||
---|---|---|---|---|
/** | /** | |||
* (C) 2007-21 - ntop.org and contributors | * (C) 2007-22 - ntop.org and contributors | |||
* | * | |||
* This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 3 of the License, or | * the Free Software Foundation; either version 3 of the License, or | |||
* (at your option) any later version. | * (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU General Public License for more details. | |||
skipping to change at line 32 | skipping to change at line 32 | |||
int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn _list); | int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn _list); | |||
int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, t ime_t now); | int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, t ime_t now); | |||
int resolve_cancel_thread (n2n_resolve_parameter_t *param); | int resolve_cancel_thread (n2n_resolve_parameter_t *param); | |||
static ssize_t sendto_peer (n2n_sn_t *sss, | static ssize_t sendto_peer (n2n_sn_t *sss, | |||
const struct peer_info *peer, | const struct peer_info *peer, | |||
const uint8_t *pktbuf, | const uint8_t *pktbuf, | |||
size_t pktsize); | size_t pktsize); | |||
static int sendto_mgmt (n2n_sn_t *sss, | ||||
const struct sockaddr_in *sender_sock, | ||||
const uint8_t *mgmt_buf, | ||||
size_t mgmt_size); | ||||
static uint16_t reg_lifetime (n2n_sn_t *sss); | static uint16_t reg_lifetime (n2n_sn_t *sss); | |||
static int update_edge (n2n_sn_t *sss, | static int update_edge (n2n_sn_t *sss, | |||
const n2n_common_t* cmn, | const n2n_common_t* cmn, | |||
const n2n_REGISTER_SUPER_t* reg, | const n2n_REGISTER_SUPER_t* reg, | |||
struct sn_community *comm, | struct sn_community *comm, | |||
const n2n_sock_t *sender_sock, | const n2n_sock_t *sender_sock, | |||
const SOCKET socket_fd, | const SOCKET socket_fd, | |||
n2n_auth_t *answer_auth, | n2n_auth_t *answer_auth, | |||
int skip_add, | int skip_add, | |||
skipping to change at line 63 | skipping to change at line 58 | |||
uint8_t forced); | uint8_t forced); | |||
static int purge_expired_communities (n2n_sn_t *sss, | static int purge_expired_communities (n2n_sn_t *sss, | |||
time_t* p_last_purge, | time_t* p_last_purge, | |||
time_t now); | time_t now); | |||
static int sort_communities (n2n_sn_t *sss, | static int sort_communities (n2n_sn_t *sss, | |||
time_t* p_last_sort, | time_t* p_last_sort, | |||
time_t now); | time_t now); | |||
static int process_mgmt (n2n_sn_t *sss, | int process_mgmt (n2n_sn_t *sss, | |||
const struct sockaddr_in *sender_sock, | const struct sockaddr_in *sender_sock, | |||
char *mgmt_buf, | char *mgmt_buf, | |||
size_t mgmt_size, | size_t mgmt_size, | |||
time_t now); | time_t now); | |||
static int process_udp (n2n_sn_t *sss, | static int process_udp (n2n_sn_t *sss, | |||
const struct sockaddr_in *sender_sock, | const struct sockaddr_in *sender_sock, | |||
const SOCKET socket_fd, | const SOCKET socket_fd, | |||
uint8_t *udp_buf, | uint8_t *udp_buf, | |||
size_t udp_size, | size_t udp_size, | |||
skipping to change at line 582 | skipping to change at line 577 | |||
* | * | |||
* This will send the exact same datagram to zero or more edges registered to | * This will send the exact same datagram to zero or more edges registered to | |||
* the supernode. | * the supernode. | |||
*/ | */ | |||
static int try_broadcast (n2n_sn_t * sss, | static int try_broadcast (n2n_sn_t * sss, | |||
const struct sn_community *comm, | const struct sn_community *comm, | |||
const n2n_common_t * cmn, | const n2n_common_t * cmn, | |||
const n2n_mac_t srcMac, | const n2n_mac_t srcMac, | |||
uint8_t from_supernode, | uint8_t from_supernode, | |||
const uint8_t * pktbuf, | const uint8_t * pktbuf, | |||
size_t pktsize) { | size_t pktsize, | |||
time_t now) { | ||||
struct peer_info *scan, *tmp; | struct peer_info *scan, *tmp; | |||
macstr_t mac_buf; | macstr_t mac_buf; | |||
n2n_sock_str_t sockbuf; | n2n_sock_str_t sockbuf; | |||
traceEvent(TRACE_DEBUG, "try_broadcast"); | traceEvent(TRACE_DEBUG, "try_broadcast"); | |||
/* We have to make sure that a broadcast reaches the other supernodes and ed ges | /* We have to make sure that a broadcast reaches the other supernodes and ed ges | |||
* connected to them. try_broadcast needs a from_supernode parameter: if set , | * 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 k nown | * do forward to edges of community only. If unset, forward to all locally k nown | |||
* nodes of community AND all supernodes associated with the community */ | * nodes of community AND all supernodes associated with the community */ | |||
if (!from_supernode) { | if (!from_supernode) { | |||
HASH_ITER(hh, sss->federation->edges, scan, tmp) { | HASH_ITER(hh, sss->federation->edges, scan, tmp) { | |||
int data_sent_len; | int data_sent_len; | |||
data_sent_len = sendto_peer(sss, scan, pktbuf, pktsize); | // only forward to active supernodes | |||
if(scan->last_seen + LAST_SEEN_SN_INACTIVE > now) { | ||||
if(data_sent_len != pktsize) { | data_sent_len = sendto_peer(sss, scan, pktbuf, pktsize); | |||
++(sss->stats.errors); | ||||
traceEvent(TRACE_WARNING, "multicast %lu to supernode [%s] %s fa | if(data_sent_len != pktsize) { | |||
iled %s", | ++(sss->stats.errors); | |||
pktsize, | traceEvent(TRACE_WARNING, "multicast %lu to supernode [%s] % | |||
sock_to_cstr(sockbuf, &(scan->sock)), | s failed %s", | |||
macaddr_str(mac_buf, scan->mac_addr), | pktsize, | |||
strerror(errno)); | sock_to_cstr(sockbuf, &(scan->sock)), | |||
} else { | macaddr_str(mac_buf, scan->mac_addr), | |||
++(sss->stats.broadcast); | strerror(errno)); | |||
traceEvent(TRACE_DEBUG, "multicast %lu to supernode [%s] %s", | } else { | |||
pktsize, | ++(sss->stats.broadcast); | |||
sock_to_cstr(sockbuf, &(scan->sock)), | traceEvent(TRACE_DEBUG, "multicast %lu to supernode [%s] %s | |||
macaddr_str(mac_buf, scan->mac_addr)); | ", | |||
} | pktsize, | |||
sock_to_cstr(sockbuf, &(scan->sock)), | ||||
macaddr_str(mac_buf, scan->mac_addr)); | ||||
} | ||||
} | ||||
} | } | |||
} | } | |||
if(comm) { | if(comm) { | |||
HASH_ITER(hh, comm->edges, scan, tmp) { | HASH_ITER(hh, comm->edges, scan, tmp) { | |||
if(memcmp(srcMac, scan->mac_addr, sizeof(n2n_mac_t)) != 0) { | if(memcmp(srcMac, scan->mac_addr, sizeof(n2n_mac_t)) != 0) { | |||
/* REVISIT: exclude if the destination socket is where the packe t came from. */ | /* REVISIT: exclude if the destination socket is where the packe t came from. */ | |||
int data_sent_len; | int data_sent_len; | |||
data_sent_len = sendto_peer(sss, scan, pktbuf, pktsize); | data_sent_len = sendto_peer(sss, scan, pktbuf, pktsize); | |||
skipping to change at line 653 | skipping to change at line 653 | |||
return 0; | return 0; | |||
} | } | |||
static int try_forward (n2n_sn_t * sss, | static int try_forward (n2n_sn_t * sss, | |||
const struct sn_community *comm, | const struct sn_community *comm, | |||
const n2n_common_t * cmn, | const n2n_common_t * cmn, | |||
const n2n_mac_t dstMac, | const n2n_mac_t dstMac, | |||
uint8_t from_supernode, | uint8_t from_supernode, | |||
const uint8_t * pktbuf, | const uint8_t * pktbuf, | |||
size_t pktsize) { | size_t pktsize, | |||
time_t now) { | ||||
struct peer_info * scan; | struct peer_info * scan; | |||
node_supernode_association_t *assoc; | node_supernode_association_t *assoc; | |||
macstr_t mac_buf; | macstr_t mac_buf; | |||
n2n_sock_str_t sockbuf; | n2n_sock_str_t sockbuf; | |||
HASH_FIND_PEER(comm->edges, dstMac, scan); | HASH_FIND_PEER(comm->edges, dstMac, scan); | |||
if(NULL != scan) { | if(NULL != scan) { | |||
int data_sent_len; | int data_sent_len; | |||
skipping to change at line 693 | skipping to change at line 694 | |||
// check if target edge is associated with a certain supernode | // check if target edge is associated with a certain supernode | |||
HASH_FIND(hh, comm->assoc, dstMac, sizeof(n2n_mac_t), assoc); | HASH_FIND(hh, comm->assoc, dstMac, sizeof(n2n_mac_t), assoc); | |||
if(assoc) { | if(assoc) { | |||
traceEvent(TRACE_DEBUG, "found mac address associated with a kno wn supernode, forwarding packet to that supernode"); | traceEvent(TRACE_DEBUG, "found mac address associated with a kno wn supernode, forwarding packet to that supernode"); | |||
sendto_sock(sss, sss->sock, | sendto_sock(sss, sss->sock, | |||
(const struct sockaddr*)&(assoc->sock), | (const struct sockaddr*)&(assoc->sock), | |||
pktbuf, pktsize); | pktbuf, pktsize); | |||
} else { | } else { | |||
// forwarding packet to all federated supernodes | // forwarding packet to all federated supernodes | |||
traceEvent(TRACE_DEBUG, "unknown mac address, broadcasting packe t to all federated supernodes"); | traceEvent(TRACE_DEBUG, "unknown mac address, broadcasting packe t to all federated supernodes"); | |||
try_broadcast(sss, NULL, cmn, sss->mac_addr, from_supernode, pkt buf, pktsize); | try_broadcast(sss, NULL, cmn, sss->mac_addr, from_supernode, pkt buf, pktsize, now); | |||
} | } | |||
} else { | } else { | |||
traceEvent(TRACE_DEBUG, "unknown mac address in packet from a supern ode, dropping the packet"); | traceEvent(TRACE_DEBUG, "unknown mac address in packet from a supern ode, dropping the packet"); | |||
/* Not a known MAC so drop. */ | /* Not a known MAC so drop. */ | |||
return -2; | return -2; | |||
} | } | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
skipping to change at line 728 | skipping to change at line 729 | |||
char *tmp_string; | char *tmp_string; | |||
#ifdef WIN32 | #ifdef WIN32 | |||
initWin32(); | initWin32(); | |||
#endif | #endif | |||
pearson_hash_init(); | pearson_hash_init(); | |||
memset(sss, 0, sizeof(n2n_sn_t)); | memset(sss, 0, sizeof(n2n_sn_t)); | |||
strncpy(sss->version, GIT_RELEASE, sizeof(n2n_version_t)); | strncpy(sss->version, PACKAGE_VERSION, sizeof(n2n_version_t)); | |||
sss->version[sizeof(n2n_version_t) - 1] = '\0'; | sss->version[sizeof(n2n_version_t) - 1] = '\0'; | |||
sss->daemon = 1; /* By defult run as a daemon. */ | sss->daemon = 1; /* By defult run as a daemon. */ | |||
sss->lport = N2N_SN_LPORT_DEFAULT; | sss->lport = N2N_SN_LPORT_DEFAULT; | |||
sss->mport = N2N_SN_MGMT_PORT; | sss->mport = N2N_SN_MGMT_PORT; | |||
sss->sock = -1; | sss->sock = -1; | |||
sss->mgmt_sock = -1; | sss->mgmt_sock = -1; | |||
sss->min_auto_ip_net.net_addr = inet_addr(N2N_SN_MIN_AUTO_IP_NET_DEFAULT); | sss->min_auto_ip_net.net_addr = inet_addr(N2N_SN_MIN_AUTO_IP_NET_DEFAULT); | |||
sss->min_auto_ip_net.net_addr = ntohl(sss->min_auto_ip_net.net_addr); | sss->min_auto_ip_net.net_addr = ntohl(sss->min_auto_ip_net.net_addr); | |||
sss->min_auto_ip_net.net_bitlen = N2N_SN_AUTO_IP_NET_BIT_DEFAULT; | sss->min_auto_ip_net.net_bitlen = N2N_SN_AUTO_IP_NET_BIT_DEFAULT; | |||
sss->max_auto_ip_net.net_addr = inet_addr(N2N_SN_MAX_AUTO_IP_NET_DEFAULT); | sss->max_auto_ip_net.net_addr = inet_addr(N2N_SN_MAX_AUTO_IP_NET_DEFAULT); | |||
skipping to change at line 1470 | skipping to change at line 1471 | |||
// (other models could reset it to half of their value to respect history) | // (other models could reset it to half of their value to respect history) | |||
HASH_ITER(hh, sss->communities, comm, tmp) { | HASH_ITER(hh, sss->communities, comm, tmp) { | |||
comm->number_enc_packets = 0; | comm->number_enc_packets = 0; | |||
} | } | |||
(*p_last_sort) = now; | (*p_last_sort) = now; | |||
return 0; | return 0; | |||
} | } | |||
static int process_mgmt (n2n_sn_t *sss, | ||||
const struct sockaddr_in *sender_sock, | ||||
char *mgmt_buf, | ||||
size_t mgmt_size, | ||||
time_t now) { | ||||
char resbuf[N2N_SN_PKTBUF_SIZE]; | ||||
size_t ressize = 0; | ||||
uint32_t num_edges = 0; | ||||
uint32_t num_comm = 0; | ||||
uint32_t num = 0; | ||||
struct sn_community *community, *tmp; | ||||
struct peer_info *peer, *tmpPeer; | ||||
macstr_t mac_buf; | ||||
n2n_sock_str_t sockbuf; | ||||
char time_buf[10]; /* 9 digits + 1 terminating zero */ | ||||
dec_ip_bit_str_t ip_bit_str = {'\0'}; | ||||
traceEvent(TRACE_DEBUG, "process_mgmt"); | ||||
/* avoid parsing any uninitialized junk from the stack */ | ||||
mgmt_buf[mgmt_size] = 0; | ||||
// process input, if any | ||||
if((0 == memcmp(mgmt_buf, "help", 4)) || (0 == memcmp(mgmt_buf, "?", 1)) | ||||
) { | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"Help for supernode management console:\n" | ||||
"\thelp | This help message\n" | ||||
"\treload_communities | Reloads communities an | ||||
d user's public keys\n" | ||||
"\t<enter> | Display status and sta | ||||
tistics\n"); | ||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); | ||||
return 0; /* no status output afterwards */ | ||||
} | ||||
if(0 == memcmp(mgmt_buf, "reload_communities", 18)) { | ||||
if(!sss->community_file) { | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressi | ||||
ze, | ||||
"No community file provided (-c command line | ||||
option)\n"); | ||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize) | ||||
; | ||||
return 0; /* no status output afterwards */ | ||||
} | ||||
traceEvent(TRACE_NORMAL, "'reload_communities' command"); | ||||
if(load_allowed_sn_community(sss)) { | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressi | ||||
ze, | ||||
"Error while re-loading community file (not | ||||
found or no valid content)\n"); | ||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize) | ||||
; | ||||
return 0; /* no status output afterwards */ | ||||
} | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"OK.\n"); | ||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); | ||||
return 0; /* no status output afterwards */ | ||||
} | ||||
if((mgmt_buf[0] == 'r' || mgmt_buf[0] == 'w') && (mgmt_buf[1] == ' ')) { | ||||
/* this is a JSON request */ | ||||
handleMgmtJson_sn(sss, mgmt_buf, *sender_sock); | ||||
return 0; | ||||
} | ||||
// output current status | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
" ### | TAP | MAC | EDGE | ||||
| HINT | LAST SEEN\n"); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"======================================================= | ||||
=================================================\n"); | ||||
HASH_ITER(hh, sss->communities, community, tmp) { | ||||
if(num_comm) | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"----------------------------------------------- | ||||
---------------------------------------------------------\n"); | ||||
num_comm++; | ||||
num_edges += HASH_COUNT(community->edges); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"%s '%s'\n", | ||||
(community->is_federation) ? "FEDERATION" : | ||||
((communit | ||||
y->purgeable == COMMUNITY_UNPURGEABLE) ? "FIXED NAME COMMUNITY" : "COMMUNITY"), | ||||
(community->is_federation) ? "-/-" : community->comm | ||||
unity); | ||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); | ||||
ressize = 0; | ||||
num = 0; | ||||
HASH_ITER(hh, community->edges, peer, tmpPeer) { | ||||
sprintf (time_buf, "%9u", (unsigned int)(now - peer->last_seen)); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"%4u | %-19s | %-17s | %-21s %-3s | %-15s | %9s\ | ||||
n", | ||||
++num, | ||||
(peer->dev_addr.net_addr == 0) ? ((peer->purgeab | ||||
le == SN_UNPURGEABLE) ? "-l" : "") : | ||||
ip_subnet_to_ | ||||
str(ip_bit_str, &peer->dev_addr), | ||||
(is_null_mac(peer->mac_addr)) ? "" : macaddr_str | ||||
(mac_buf, peer->mac_addr), | ||||
sock_to_cstr(sockbuf, &(peer->sock)), | ||||
((peer->socket_fd >= 0) && (peer->socket_fd != s | ||||
ss->sock)) ? "TCP" : "", | ||||
peer->dev_desc, | ||||
(peer->last_seen) ? time_buf : ""); | ||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); | ||||
ressize = 0; | ||||
} | ||||
} | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"======================================================= | ||||
=================================================\n"); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"uptime %lu | ", (now - sss->start_time)); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"edges %u | ", | ||||
num_edges); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"reg_sup %u | ", | ||||
(unsigned int) sss->stats.reg_super); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"reg_nak %u | ", | ||||
(unsigned int) sss->stats.reg_super_nak); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"errors %u \n", | ||||
(unsigned int) sss->stats.errors); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"fwd %u | ", | ||||
(unsigned int) sss->stats.fwd); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"broadcast %u | ", | ||||
(unsigned int) sss->stats.broadcast); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"cur_cmnts %u\n", HASH_COUNT(sss->communities)); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"last_fwd %lu sec ago | ", | ||||
(long unsigned int) (now - sss->stats.last_fwd)); | ||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, | ||||
"last reg %lu sec ago\n\n", | ||||
(long unsigned int) (now - sss->stats.last_reg_super)); | ||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); | ||||
return 0; | ||||
} | ||||
static int sendto_mgmt (n2n_sn_t *sss, | ||||
const struct sockaddr_in *sender_sock, | ||||
const uint8_t *mgmt_buf, | ||||
size_t mgmt_size) { | ||||
ssize_t r = sendto(sss->mgmt_sock, (void *)mgmt_buf, mgmt_size, 0 /*flags*/, | ||||
(struct sockaddr *)sender_sock, sizeof (struct sockaddr_i | ||||
n)); | ||||
if(r <= 0) { | ||||
++(sss->stats.errors); | ||||
traceEvent (TRACE_ERROR, "sendto_mgmt : sendto failed. %s", strerror (er | ||||
rno)); | ||||
return -1; | ||||
} | ||||
return 0; | ||||
} | ||||
/** Examine a datagram and determine what to do with it. | /** Examine a datagram and determine what to do with it. | |||
* | * | |||
*/ | */ | |||
static int process_udp (n2n_sn_t * sss, | static int process_udp (n2n_sn_t * sss, | |||
const struct sockaddr_in *sender_sock, | const struct sockaddr_in *sender_sock, | |||
const SOCKET socket_fd, | const SOCKET socket_fd, | |||
uint8_t * udp_buf, | uint8_t * udp_buf, | |||
size_t udp_size, | size_t udp_size, | |||
time_t now) { | time_t now) { | |||
skipping to change at line 1886 | skipping to change at line 1724 | |||
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { | if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { | |||
// in case of user-password auth, also encrypt the iv of pay load assuming ChaCha20 and SPECK having the same iv size | // in case of user-password auth, also encrypt the iv of pay load assuming ChaCha20 and SPECK having the same iv size | |||
packet_header_encrypt(rec_buf, idx + (NULL != comm->allowed_ users) * min(encx - idx, N2N_SPECK_IVEC_SIZE), encx, | packet_header_encrypt(rec_buf, idx + (NULL != comm->allowed_ users) * min(encx - idx, N2N_SPECK_IVEC_SIZE), encx, | |||
comm->header_encryption_ctx_dynamic, c omm->header_iv_ctx_dynamic, | comm->header_encryption_ctx_dynamic, c omm->header_iv_ctx_dynamic, | |||
time_stamp()); | time_stamp()); | |||
} | } | |||
} | } | |||
/* Common section to forward the final product. */ | /* Common section to forward the final product. */ | |||
if(unicast) { | 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, now); | |||
} else { | } else { | |||
try_broadcast(sss, comm, &cmn, pkt.srcMac, from_supernode, rec_b uf, encx); | try_broadcast(sss, comm, &cmn, pkt.srcMac, from_supernode, rec_b uf, encx, now); | |||
} | } | |||
break; | break; | |||
} | } | |||
case MSG_TYPE_REGISTER: { | case MSG_TYPE_REGISTER: { | |||
/* Forwarding a REGISTER from one edge to the next */ | /* Forwarding a REGISTER from one edge to the next */ | |||
n2n_REGISTER_t reg; | n2n_REGISTER_t reg; | |||
n2n_common_t cmn2; | n2n_common_t cmn2; | |||
uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; | uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; | |||
skipping to change at line 1954 | skipping to change at line 1792 | |||
rec_buf = udp_buf; | rec_buf = udp_buf; | |||
encx = udp_size; | encx = udp_size; | |||
} | } | |||
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { | if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { | |||
packet_header_encrypt(rec_buf, encx, encx, | packet_header_encrypt(rec_buf, encx, encx, | |||
comm->header_encryption_ctx_dynamic, c omm->header_iv_ctx_dynamic, | comm->header_encryption_ctx_dynamic, c omm->header_iv_ctx_dynamic, | |||
time_stamp()); | time_stamp()); | |||
} | } | |||
try_forward(sss, comm, &cmn, reg.dstMac, from_supernode, rec_buf , encx); /* unicast only */ | try_forward(sss, comm, &cmn, reg.dstMac, from_supernode, rec_buf , encx, now); /* unicast only */ | |||
} else { | } else { | |||
traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination" ); | traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination" ); | |||
} | } | |||
break; | break; | |||
} | } | |||
case MSG_TYPE_REGISTER_ACK: { | case MSG_TYPE_REGISTER_ACK: { | |||
traceEvent(TRACE_DEBUG, "Rx REGISTER_ACK (not implemented) should no t be via supernode"); | traceEvent(TRACE_DEBUG, "Rx REGISTER_ACK (not implemented) should no t be via supernode"); | |||
break; | break; | |||
} | } | |||
skipping to change at line 2069 | skipping to change at line 1907 | |||
if(memcmp(hash_buf, udp_buf + udp_size - N2N_REG_SUP_HASH_CH ECK_LEN /* length has already been checked */, N2N_REG_SUP_HASH_CHECK_LEN)) { | if(memcmp(hash_buf, udp_buf + udp_size - N2N_REG_SUP_HASH_CH ECK_LEN /* length has already been checked */, N2N_REG_SUP_HASH_CHECK_LEN)) { | |||
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER with wrong has h"); | traceEvent(TRACE_INFO, "Rx REGISTER_SUPER with wrong has h"); | |||
return -1; | return -1; | |||
} | } | |||
} else { | } else { | |||
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER from unknown user" ); | traceEvent(TRACE_INFO, "Rx REGISTER_SUPER from unknown user" ); | |||
// continue and let auth check do the rest (otherwise, no NA K is sent) | // continue and let auth check do the rest (otherwise, no NA K is sent) | |||
} | } | |||
} | } | |||
if(!memcmp(reg.edgeMac, sss->mac_addr, sizeof(n2n_mac_t))) { | ||||
traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER from self, ignoring") | ||||
; | ||||
return -1; | ||||
} | ||||
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; | |||
memcpy(cmn2.community, cmn.community, sizeof(n2n_community_t)); | memcpy(cmn2.community, cmn.community, sizeof(n2n_community_t)); | |||
ack.cookie = reg.cookie; | ack.cookie = reg.cookie; | |||
memcpy(ack.srcMac, sss->mac_addr, sizeof(n2n_mac_t)); | memcpy(ack.srcMac, sss->mac_addr, sizeof(n2n_mac_t)); | |||
if(comm->is_federation != IS_FEDERATION) { /* alternatively, do not send zero tap ip address in federation REGISTER_SUPER */ | if(comm->is_federation != IS_FEDERATION) { /* alternatively, do not send zero tap ip address in federation REGISTER_SUPER */ | |||
if((reg.dev_addr.net_addr == 0) || (reg.dev_addr.net_addr == 0xF FFFFFFF) || (reg.dev_addr.net_bitlen == 0) || | if((reg.dev_addr.net_addr == 0) || (reg.dev_addr.net_addr == 0xF FFFFFFF) || (reg.dev_addr.net_bitlen == 0) || | |||
skipping to change at line 2193 | skipping to change at line 2036 | |||
// if user-password-auth | // if user-password-auth | |||
if(comm->allowed_users) { | if(comm->allowed_users) { | |||
// append an encrypted packet hash | // append an encrypted packet hash | |||
pearson_hash_128(hash_buf, ackbuf, encx); | pearson_hash_128(hash_buf, ackbuf, encx); | |||
// same 'user' as above | // same 'user' as above | |||
speck_128_encrypt(hash_buf, (speck_context_t*)use r->shared_secret_ctx); | speck_128_encrypt(hash_buf, (speck_context_t*)use r->shared_secret_ctx); | |||
encode_buf(ackbuf, &encx, hash_buf, N2N_REG_SUP_H ASH_CHECK_LEN); | encode_buf(ackbuf, &encx, hash_buf, N2N_REG_SUP_H ASH_CHECK_LEN); | |||
} | } | |||
} | } | |||
try_broadcast(sss, NULL, &cmn, reg.edgeMac, from_superno de, ackbuf, encx); | try_broadcast(sss, NULL, &cmn, reg.edgeMac, from_superno de, ackbuf, encx, now); | |||
} | } | |||
// dynamic key time handling if appropriate | // dynamic key time handling if appropriate | |||
ack.key_time = 0; | ack.key_time = 0; | |||
if(comm->is_federation == IS_FEDERATION) { | if(comm->is_federation == IS_FEDERATION) { | |||
if(reg.key_time > sss->dynamic_key_time) { | if(reg.key_time > sss->dynamic_key_time) { | |||
traceEvent(TRACE_DEBUG, "setting new key time"); | traceEvent(TRACE_DEBUG, "setting new key time"); | |||
// have all edges re_register (using old dynamic key ) | // have all edges re_register (using old dynamic key ) | |||
send_re_register_super(sss); | send_re_register_super(sss); | |||
// set new key time | // set new key time | |||
skipping to change at line 2608 | skipping to change at line 2451 | |||
cmn2.flags |= N2N_FLAGS_FROM_SUPERNODE; | cmn2.flags |= N2N_FLAGS_FROM_SUPERNODE; | |||
encode_QUERY_PEER(encbuf, &encx, &cmn2, &query); | encode_QUERY_PEER(encbuf, &encx, &cmn2, &query); | |||
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { | if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { | |||
packet_header_encrypt(encbuf, encx, encx, comm->head er_encryption_ctx_dynamic, | packet_header_encrypt(encbuf, encx, encx, comm->head er_encryption_ctx_dynamic, | |||
comm->header_iv_ctx_dynamic, | comm->header_iv_ctx_dynamic, | |||
time_stamp()); | time_stamp()); | |||
} | } | |||
try_broadcast(sss, NULL, &cmn, query.srcMac, from_supern ode, encbuf, encx); | try_broadcast(sss, NULL, &cmn, query.srcMac, from_supern ode, encbuf, encx, now); | |||
} | } | |||
} | } | |||
} | } | |||
break; | break; | |||
} | } | |||
case MSG_TYPE_PEER_INFO: { | case MSG_TYPE_PEER_INFO: { | |||
n2n_PEER_INFO_t pi; | n2n_PEER_INFO_t pi; | |||
uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; | uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; | |||
size_t encx = 0; | size_t encx = 0; | |||
End of changes. 16 change blocks. | ||||
217 lines changed or deleted | 40 lines changed or added |