readability code clean-up

This commit is contained in:
fcarli3 2020-12-19 16:51:42 +01:00
parent df14d54a29
commit 521a22f90b
2 changed files with 1213 additions and 1173 deletions

View File

@ -30,6 +30,7 @@ static const n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0};
* *
*/ */
static int load_allowed_sn_community (n2n_sn_t *sss, char *path) { static int load_allowed_sn_community (n2n_sn_t *sss, char *path) {
char buffer[4096], *line, *cmn_str, net_str[20]; char buffer[4096], *line, *cmn_str, net_str[20];
dec_ip_str_t ip_str = {'\0'}; dec_ip_str_t ip_str = {'\0'};
uint8_t bitlen; uint8_t bitlen;
@ -48,10 +49,13 @@ static int load_allowed_sn_community(n2n_sn_t *sss, char *path) {
} }
HASH_ITER(hh, sss->communities, s, tmp) { HASH_ITER(hh, sss->communities, s, tmp) {
if(s->is_federation) continue; if(s->is_federation) {
continue;
}
HASH_DEL(sss->communities, s); HASH_DEL(sss->communities, s);
if (NULL != s->header_encryption_ctx) if(NULL != s->header_encryption_ctx) {
free (s->header_encryption_ctx); free (s->header_encryption_ctx);
}
free(s); free(s);
} }
@ -63,17 +67,19 @@ static int load_allowed_sn_community(n2n_sn_t *sss, char *path) {
while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) { while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) {
int len = strlen(line); int len = strlen(line);
if((len < 2) || line[0] == '#') if(((len < 2) || line[0]) == '#') {
continue; continue;
}
len--; len--;
while(len > 0) { while(len > 0) {
if((line[len] == '\n') || (line[len] == '\r')) { if((line[len] == '\n') || (line[len] == '\r')) {
line[len] = '\0'; line[len] = '\0';
len--; len--;
} else } else {
break; break;
} }
}
// cut off any IP sub-network upfront // cut off any IP sub-network upfront
cmn_str = (char*)calloc(len + 1, sizeof(char)); cmn_str = (char*)calloc(len + 1, sizeof(char));
@ -148,8 +154,7 @@ static int load_allowed_sn_community(n2n_sn_t *sss, char *path) {
fclose(fd); fclose(fd);
if ((num_regex + num_communities) == 0) if((num_regex + num_communities) == 0) {
{
traceEvent(TRACE_WARNING, "File %s does not contain any valid community names or regular expressions", path); traceEvent(TRACE_WARNING, "File %s does not contain any valid community names or regular expressions", path);
return -1; return -1;
} }
@ -171,6 +176,7 @@ static int load_allowed_sn_community(n2n_sn_t *sss, char *path) {
/** Help message to print if the command line arguments are not valid. */ /** Help message to print if the command line arguments are not valid. */
static void help () { static void help () {
print_n2n_version(); print_n2n_version();
printf("supernode <config file> (see supernode.conf)\n" printf("supernode <config file> (see supernode.conf)\n"
@ -223,6 +229,7 @@ static void help() {
/* *************************************************** */ /* *************************************************** */
static int setOption (int optkey, char *_optarg, n2n_sn_t *sss) { static int setOption (int optkey, char *_optarg, n2n_sn_t *sss) {
//traceEvent(TRACE_NORMAL, "Option %c = %s", optkey, _optarg ? _optarg : ""); //traceEvent(TRACE_NORMAL, "Option %c = %s", optkey, _optarg ? _optarg : "");
switch(optkey) { switch(optkey) {
@ -275,7 +282,6 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
} }
if(sss->federation != NULL) { if(sss->federation != NULL) {
skip_add = SN_ADD; 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); anchor_sn = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), socket, (n2n_mac_t*) null_mac, &skip_add);
@ -287,7 +293,6 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
memcpy(&(anchor_sn->mac_addr), null_mac, sizeof(n2n_mac_t)); memcpy(&(anchor_sn->mac_addr), null_mac, sizeof(n2n_mac_t));
anchor_sn->purgeable = SN_UNPURGEABLE; anchor_sn->purgeable = SN_UNPURGEABLE;
anchor_sn->last_valid_time_stamp = initial_time_stamp(); anchor_sn->last_valid_time_stamp = initial_time_stamp();
} }
} }
} }
@ -349,7 +354,6 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
#endif #endif
case 'F': { /* federation name */ case 'F': { /* federation name */
snprintf(sss->federation->community, N2N_COMMUNITY_SIZE - 1, "*%s", _optarg); snprintf(sss->federation->community, N2N_COMMUNITY_SIZE - 1, "*%s", _optarg);
sss->federation->community[N2N_COMMUNITY_SIZE - 1] = '\0'; sss->federation->community[N2N_COMMUNITY_SIZE - 1] = '\0';
@ -405,11 +409,14 @@ static const struct option long_options[] = {
/* read command line options */ /* read command line options */
static int loadFromCLI (int argc, char * const argv[], n2n_sn_t *sss) { static int loadFromCLI (int argc, char * const argv[], n2n_sn_t *sss) {
u_char c; u_char c;
while((c = getopt_long(argc, argv, "fp:l:u:g:t:a:c:F:m:vh", while((c = getopt_long(argc, argv, "fp:l:u:g:t:a:c:F:m:vh",
long_options, NULL)) != '?') { long_options, NULL)) != '?') {
if(c == 255) break; if(c == 255) {
break;
}
setOption(c, optarg, sss); setOption(c, optarg, sss);
} }
@ -419,17 +426,21 @@ static int loadFromCLI(int argc, char * const argv[], n2n_sn_t *sss) {
/* *************************************************** */ /* *************************************************** */
static char *trim (char *s) { static char *trim (char *s) {
char *end; char *end;
while(isspace(s[0]) || (s[0] == '"') || (s[0] == '\'')) while(isspace(s[0]) || (s[0] == '"') || (s[0] == '\'')) {
s++; s++;
}
if(s[0] == 0) return s; if(s[0] == 0) {
return s;
}
end = &s[strlen(s) - 1]; end = &s[strlen(s) - 1];
while(end > s while(end > s && (isspace(end[0])|| (end[0] == '"') || (end[0] == '\''))) {
&& (isspace(end[0])|| (end[0] == '"') || (end[0] == '\'')))
end--; end--;
}
end[1] = 0; end[1] = 0;
return s; return s;
@ -439,6 +450,7 @@ static char *trim(char *s) {
/* parse the configuration file */ /* parse the configuration file */
static int loadFromFile (const char *path, n2n_sn_t *sss) { static int loadFromFile (const char *path, n2n_sn_t *sss) {
char buffer[4096], *line, *key, *value; char buffer[4096], *line, *key, *value;
u_int line_len, opt_name_len; u_int line_len, opt_name_len;
FILE *fd; FILE *fd;
@ -452,12 +464,12 @@ static int loadFromFile(const char *path, n2n_sn_t *sss) {
} }
while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) { while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) {
line = trim(line); line = trim(line);
value = NULL; value = NULL;
if((line_len = strlen(line)) < 2 || line[0] == '#') if((line_len = strlen(line)) < 2 || line[0] == '#') {
continue; continue;
}
if(!strncmp(line, "--", 2)) { /* long opt */ if(!strncmp(line, "--", 2)) { /* long opt */
key = &line[2], line_len -= 2; key = &line[2], line_len -= 2;
@ -471,8 +483,12 @@ static int loadFromFile(const char *path, n2n_sn_t *sss) {
|| key[opt_name_len] == '\0' || key[opt_name_len] == '\0'
|| key[opt_name_len] == ' ' || key[opt_name_len] == ' '
|| key[opt_name_len] == '=')) { || key[opt_name_len] == '=')) {
if(line_len > opt_name_len) key[opt_name_len] = '\0'; if(line_len > opt_name_len) {
if(line_len > opt_name_len + 1) value = trim(&key[opt_name_len + 1]); key[opt_name_len] = '\0';
}
if(line_len > opt_name_len + 1) {
value = trim(&key[opt_name_len + 1]);
}
// traceEvent(TRACE_NORMAL, "long key: %s value: %s", key, value); // traceEvent(TRACE_NORMAL, "long key: %s value: %s", key, value);
setOption(opt->val, value, sss); setOption(opt->val, value, sss);
@ -483,8 +499,12 @@ static int loadFromFile(const char *path, n2n_sn_t *sss) {
} }
} else if(line[0] == '-') { /* short opt */ } else if(line[0] == '-') { /* short opt */
key = &line[1], line_len--; key = &line[1], line_len--;
if(line_len > 1) key[1] = '\0'; if(line_len > 1) {
if(line_len > 2) value = trim(&key[2]); key[1] = '\0';
}
if(line_len > 2) {
value = trim(&key[2]);
}
// traceEvent(TRACE_NORMAL, "key: %c value: %s", key[0], value); // traceEvent(TRACE_NORMAL, "key: %c value: %s", key[0], value);
setOption(key[0], value, sss); setOption(key[0], value, sss);
@ -503,13 +523,12 @@ static int loadFromFile(const char *path, n2n_sn_t *sss) {
/* Add the federation to the communities list of a supernode */ /* Add the federation to the communities list of a supernode */
static int add_federation_to_communities (n2n_sn_t *sss) { static int add_federation_to_communities (n2n_sn_t *sss) {
uint32_t num_communities = 0; uint32_t num_communities = 0;
if(sss->federation != NULL) { if(sss->federation != NULL) {
HASH_ADD_STR(sss->communities, community, sss->federation); HASH_ADD_STR(sss->communities, community, sss->federation);
num_communities = HASH_COUNT(sss->communities); num_communities = HASH_COUNT(sss->communities);
traceEvent(TRACE_INFO, "Added federation '%s' to the list of communities [total: %u]", traceEvent(TRACE_INFO, "Added federation '%s' to the list of communities [total: %u]",
(char*)sss->federation->community, num_communities); (char*)sss->federation->community, num_communities);
} }
@ -521,6 +540,7 @@ static int add_federation_to_communities(n2n_sn_t *sss){
#ifdef __linux__ #ifdef __linux__
static void dump_registrations (int signo) { static void dump_registrations (int signo) {
struct sn_community *comm, *ctmp; struct sn_community *comm, *ctmp;
struct peer_info *list, *tmp; struct peer_info *list, *tmp;
char buf[32]; char buf[32];
@ -533,18 +553,19 @@ static void dump_registrations(int signo) {
traceEvent(TRACE_NORMAL, "Dumping community: %s", comm->community); traceEvent(TRACE_NORMAL, "Dumping community: %s", comm->community);
HASH_ITER(hh, comm->edges, list, tmp) { HASH_ITER(hh, comm->edges, list, tmp) {
if(list->sock.family == AF_INET) if(list->sock.family == AF_INET) {
traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: %u.%u.%u.%u:%u][last seen: %u sec ago]", traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: %u.%u.%u.%u:%u][last seen: %u sec ago]",
++num, macaddr_str(buf, list->mac_addr), ++num, macaddr_str(buf, list->mac_addr),
list->sock.addr.v4[0], list->sock.addr.v4[1], list->sock.addr.v4[2], list->sock.addr.v4[3], list->sock.addr.v4[0], list->sock.addr.v4[1], list->sock.addr.v4[2], list->sock.addr.v4[3],
list->sock.port, list->sock.port,
now-list->last_seen); now-list->last_seen);
else } else {
traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: IPv6:%u][last seen: %u sec ago]", traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: IPv6:%u][last seen: %u sec ago]",
++num, macaddr_str(buf, list->mac_addr), list->sock.port, ++num, macaddr_str(buf, list->mac_addr), list->sock.port,
now-list->last_seen); now-list->last_seen);
} }
} }
}
traceEvent(TRACE_NORMAL, "===================================="); traceEvent(TRACE_NORMAL, "====================================");
} }
@ -582,6 +603,7 @@ BOOL WINAPI term_handler(DWORD sig)
/** Main program entry point from kernel. */ /** Main program entry point from kernel. */
int main (int argc, char * const argv[]) { int main (int argc, char * const argv[]) {
int rc; int rc;
#ifndef WIN32 #ifndef WIN32
struct passwd *pw = NULL; struct passwd *pw = NULL;
@ -592,11 +614,12 @@ int main(int argc, char * const argv[]) {
if((argc >= 2) && (argv[1][0] != '-')) { if((argc >= 2) && (argv[1][0] != '-')) {
rc = loadFromFile(argv[1], &sss_node); rc = loadFromFile(argv[1], &sss_node);
if(argc > 2) if(argc > 2) {
rc = loadFromCLI(argc, argv, &sss_node); rc = loadFromCLI(argc, argv, &sss_node);
} else if(argc > 1) }
} else if(argc > 1) {
rc = loadFromCLI(argc, argv, &sss_node); rc = loadFromCLI(argc, argv, &sss_node);
else } else
#ifdef WIN32 #ifdef WIN32
/* Load from current directory */ /* Load from current directory */
rc = loadFromFile("supernode.conf", &sss_node); rc = loadFromFile("supernode.conf", &sss_node);
@ -604,8 +627,9 @@ int main(int argc, char * const argv[]) {
rc = -1; rc = -1;
#endif #endif
if(rc < 0) if(rc < 0) {
help(); help();
}
#if defined(N2N_HAVE_DAEMON) #if defined(N2N_HAVE_DAEMON)
if(sss_node.daemon) { if(sss_node.daemon) {
@ -632,9 +656,9 @@ int main(int argc, char * const argv[]) {
if(-1 == sss_node.mgmt_sock) { if(-1 == sss_node.mgmt_sock) {
traceEvent(TRACE_ERROR, "Failed to open management socket. %s", strerror(errno)); traceEvent(TRACE_ERROR, "Failed to open management socket. %s", strerror(errno));
exit(-2); exit(-2);
} else } else {
traceEvent(TRACE_NORMAL, "supernode is listening on UDP %u (management)", sss_node.mport); traceEvent(TRACE_NORMAL, "supernode is listening on UDP %u (management)", sss_node.mport);
}
#ifndef WIN32 #ifndef WIN32
if(((pw = getpwnam ("n2n")) != NULL) || ((pw = getpwnam ("nobody")) != NULL)) { if(((pw = getpwnam ("n2n")) != NULL) || ((pw = getpwnam ("nobody")) != NULL)) {
sss_node.userid = sss_node.userid == 0 ? pw->pw_uid : 0; sss_node.userid = sss_node.userid == 0 ? pw->pw_uid : 0;
@ -652,8 +676,9 @@ int main(int argc, char * const argv[]) {
} }
} }
if((getuid() == 0) || (getgid() == 0)) if((getuid() == 0) || (getgid() == 0)) {
traceEvent(TRACE_WARNING, "Running as root is discouraged, check out the -u/-g options"); traceEvent(TRACE_WARNING, "Running as root is discouraged, check out the -u/-g options");
}
#endif #endif
traceEvent(TRACE_NORMAL, "supernode started"); traceEvent(TRACE_NORMAL, "supernode started");

View File

@ -85,29 +85,25 @@ static int try_forward(n2n_sn_t * sss,
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) {
{
struct peer_info * scan; struct peer_info * scan;
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;
data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize); data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize);
if(data_sent_len == pktsize) if(data_sent_len == pktsize) {
{
++(sss->stats.fwd); ++(sss->stats.fwd);
traceEvent(TRACE_DEBUG, "unicast %lu to [%s] %s", traceEvent(TRACE_DEBUG, "unicast %lu to [%s] %s",
pktsize, pktsize,
sock_to_cstr(sockbuf, &(scan->sock)), sock_to_cstr(sockbuf, &(scan->sock)),
macaddr_str(mac_buf, scan->mac_addr)); macaddr_str(mac_buf, scan->mac_addr));
} } else {
else
{
++(sss->stats.errors); ++(sss->stats.errors);
traceEvent(TRACE_ERROR, "unicast %lu to [%s] %s FAILED (%d: %s)", traceEvent(TRACE_ERROR, "unicast %lu to [%s] %s FAILED (%d: %s)",
pktsize, pktsize,
@ -115,9 +111,7 @@ static int try_forward(n2n_sn_t * sss,
macaddr_str(mac_buf, scan->mac_addr), macaddr_str(mac_buf, scan->mac_addr),
errno, strerror(errno)); errno, strerror(errno));
} }
} } else {
else
{
if(!from_supernode) { if(!from_supernode) {
/* Forwarding packet to all federated supernodes. */ /* Forwarding packet to all federated supernodes. */
traceEvent(TRACE_DEBUG, "Unknown MAC. Broadcasting packet to all federated supernodes."); traceEvent(TRACE_DEBUG, "Unknown MAC. Broadcasting packet to all federated supernodes.");
@ -139,12 +133,11 @@ static int try_forward(n2n_sn_t * sss,
static ssize_t sendto_sock (n2n_sn_t *sss, static ssize_t sendto_sock (n2n_sn_t *sss,
const n2n_sock_t *sock, const n2n_sock_t *sock,
const uint8_t *pktbuf, const uint8_t *pktbuf,
size_t pktsize) size_t pktsize) {
{
n2n_sock_str_t sockbuf; n2n_sock_str_t sockbuf;
if (AF_INET == sock->family) if(AF_INET == sock->family) {
{
struct sockaddr_in udpsock; struct sockaddr_in udpsock;
udpsock.sin_family = AF_INET; udpsock.sin_family = AF_INET;
@ -157,9 +150,7 @@ static ssize_t sendto_sock(n2n_sn_t *sss,
return sendto(sss->sock, pktbuf, pktsize, 0, return sendto(sss->sock, pktbuf, pktsize, 0,
(const struct sockaddr *)&udpsock, sizeof(struct sockaddr_in)); (const struct sockaddr *)&udpsock, sizeof(struct sockaddr_in));
} } else {
else
{
/* AF_INET6 not implemented */ /* AF_INET6 not implemented */
errno = EAFNOSUPPORT; errno = EAFNOSUPPORT;
return -1; return -1;
@ -177,8 +168,8 @@ static int try_broadcast(n2n_sn_t * sss,
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) {
{
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;
@ -196,17 +187,14 @@ static int try_broadcast(n2n_sn_t * sss,
data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize); data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize);
if(data_sent_len != pktsize) if(data_sent_len != pktsize) {
{
++(sss->stats.errors); ++(sss->stats.errors);
traceEvent(TRACE_WARNING, "multicast %lu to supernode [%s] %s failed %s", traceEvent(TRACE_WARNING, "multicast %lu to supernode [%s] %s failed %s",
pktsize, pktsize,
sock_to_cstr(sockbuf, &(scan->sock)), sock_to_cstr(sockbuf, &(scan->sock)),
macaddr_str(mac_buf, scan->mac_addr), macaddr_str(mac_buf, scan->mac_addr),
strerror(errno)); strerror(errno));
} } else {
else
{
++(sss->stats.broadcast); ++(sss->stats.broadcast);
traceEvent(TRACE_DEBUG, "multicast %lu to supernode [%s] %s", traceEvent(TRACE_DEBUG, "multicast %lu to supernode [%s] %s",
pktsize, pktsize,
@ -258,6 +246,7 @@ int comm_init(struct sn_community *comm, char *cmn) {
/** Initialise the supernode structure */ /** Initialise the supernode structure */
int sn_init(n2n_sn_t *sss) { int sn_init(n2n_sn_t *sss) {
int i; int i;
size_t idx; size_t idx;
@ -301,8 +290,9 @@ int sn_init(n2n_sn_t *sss) {
/* Random auth token */ /* Random auth token */
sss->auth.scheme = n2n_auth_simple_id; sss->auth.scheme = n2n_auth_simple_id;
for (idx = 0; idx < N2N_AUTH_TOKEN_SIZE; ++idx) for(idx = 0; idx < N2N_AUTH_TOKEN_SIZE; ++idx) {
sss->auth.token[idx] = n2n_rand() % 0xff; sss->auth.token[idx] = n2n_rand() % 0xff;
}
sss->auth.toksize = sizeof(sss->auth.token); sss->auth.toksize = sizeof(sss->auth.token);
@ -318,28 +308,26 @@ int sn_init(n2n_sn_t *sss) {
/** Deinitialise the supernode structure and deallocate any memory owned by /** Deinitialise the supernode structure and deallocate any memory owned by
* it. */ * it. */
void sn_term(n2n_sn_t *sss) void sn_term (n2n_sn_t *sss) {
{
struct sn_community *community, *tmp; struct sn_community *community, *tmp;
struct sn_community_regular_expression *re, *tmp_re; struct sn_community_regular_expression *re, *tmp_re;
if (sss->sock >= 0) if(sss->sock >= 0) {
{
closesocket(sss->sock); closesocket(sss->sock);
} }
sss->sock = -1; sss->sock = -1;
if (sss->mgmt_sock >= 0) if(sss->mgmt_sock >= 0) {
{
closesocket(sss->mgmt_sock); closesocket(sss->mgmt_sock);
} }
sss->mgmt_sock = -1; sss->mgmt_sock = -1;
HASH_ITER(hh, sss->communities, community, tmp) HASH_ITER(hh, sss->communities, community, tmp) {
{
clear_peer_list(&community->edges); clear_peer_list(&community->edges);
if (NULL != community->header_encryption_ctx) if(NULL != community->header_encryption_ctx) {
free(community->header_encryption_ctx); free(community->header_encryption_ctx);
}
HASH_DEL(sss->communities, community); HASH_DEL(sss->communities, community);
free(community); free(community);
} }
@ -362,8 +350,8 @@ void sn_term(n2n_sn_t *sss)
* If the supernode has been put into a pre-shutdown phase then this lifetime * If the supernode has been put into a pre-shutdown phase then this lifetime
* should not allow registrations to continue beyond the shutdown point. * should not allow registrations to continue beyond the shutdown point.
*/ */
static uint16_t reg_lifetime(n2n_sn_t *sss) static uint16_t reg_lifetime (n2n_sn_t *sss) {
{
/* NOTE: UDP firewalls usually have a 30 seconds timeout */ /* NOTE: UDP firewalls usually have a 30 seconds timeout */
return 15; return 15;
} }
@ -373,6 +361,7 @@ static uint16_t reg_lifetime(n2n_sn_t *sss)
* with the one received from the packet. * with the one received from the packet.
*/ */
static int auth_edge (const n2n_auth_t *auth1, const n2n_auth_t *auth2) { static int auth_edge (const n2n_auth_t *auth1, const n2n_auth_t *auth2) {
/* 0 = success (tokens are equal). */ /* 0 = success (tokens are equal). */
return (memcmp(auth1, auth2, sizeof(n2n_auth_t))); return (memcmp(auth1, auth2, sizeof(n2n_auth_t)));
} }
@ -385,6 +374,7 @@ static int update_edge(n2n_sn_t *sss,
const n2n_sock_t *sender_sock, const n2n_sock_t *sender_sock,
int skip_add, int skip_add,
time_t now) { time_t now) {
macstr_t mac_buf; macstr_t mac_buf;
n2n_sock_str_t sockbuf; n2n_sock_str_t sockbuf;
struct peer_info *scan, *iter, *tmp; struct peer_info *scan, *iter, *tmp;
@ -413,9 +403,7 @@ static int update_edge(n2n_sn_t *sss,
if(NULL == scan) { if(NULL == scan) {
/* Not known */ /* Not known */
if(skip_add == SN_ADD) { if(skip_add == SN_ADD) {
scan = (struct peer_info *) calloc(1, scan = (struct peer_info *) calloc(1, sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */
sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */
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;
@ -431,7 +419,6 @@ static int update_edge(n2n_sn_t *sss,
macaddr_str(mac_buf, reg->edgeMac), macaddr_str(mac_buf, reg->edgeMac),
sock_to_cstr(sockbuf, sender_sock)); sock_to_cstr(sockbuf, sender_sock));
} }
ret = update_edge_new_sn; ret = update_edge_new_sn;
} else { } else {
/* Known */ /* Known */
@ -449,7 +436,6 @@ static int update_edge(n2n_sn_t *sss,
ret = update_edge_auth_fail; ret = update_edge_auth_fail;
} }
} else { } else {
memcpy(&(scan->last_cookie), reg->cookie, sizeof(N2N_COOKIE_SIZE)); memcpy(&(scan->last_cookie), reg->cookie, sizeof(N2N_COOKIE_SIZE));
@ -470,8 +456,10 @@ static int update_edge(n2n_sn_t *sss,
static signed int peer_tap_ip_sort (struct peer_info *a, struct peer_info *b) { static signed int peer_tap_ip_sort (struct peer_info *a, struct peer_info *b) {
uint32_t a_host_id = a->dev_addr.net_addr & (~bitlen2mask(a->dev_addr.net_bitlen)); uint32_t a_host_id = a->dev_addr.net_addr & (~bitlen2mask(a->dev_addr.net_bitlen));
uint32_t b_host_id = b->dev_addr.net_addr & (~bitlen2mask(b->dev_addr.net_bitlen)); uint32_t b_host_id = b->dev_addr.net_addr & (~bitlen2mask(b->dev_addr.net_bitlen));
return ((signed int)a_host_id - (signed int)b_host_id); return ((signed int)a_host_id - (signed int)b_host_id);
} }
@ -479,6 +467,7 @@ static signed int peer_tap_ip_sort(struct peer_info *a, struct peer_info *b) {
/** The IP address assigned to the edge by the auto ip address function of sn. */ /** The IP address assigned to the edge by the auto ip address function of sn. */
static int assign_one_ip_addr (struct sn_community *comm, static int assign_one_ip_addr (struct sn_community *comm,
n2n_ip_subnet_t *ipaddr) { n2n_ip_subnet_t *ipaddr) {
struct peer_info *peer, *tmpPeer; struct peer_info *peer, *tmpPeer;
uint32_t net_id, mask, max_host, host_id = 1; uint32_t net_id, mask, max_host, host_id = 1;
dec_ip_bit_str_t ip_bit_str = {'\0'}; dec_ip_bit_str_t ip_bit_str = {'\0'};
@ -508,6 +497,7 @@ static int assign_one_ip_addr(struct sn_community *comm,
ipaddr->net_bitlen = comm->auto_ip_net.net_bitlen; ipaddr->net_bitlen = comm->auto_ip_net.net_bitlen;
traceEvent(TRACE_INFO, "Assign IP %s to tap adapter of edge.", ip_subnet_to_str(ip_bit_str, ipaddr)); traceEvent(TRACE_INFO, "Assign IP %s to tap adapter of edge.", ip_subnet_to_str(ip_bit_str, ipaddr));
return 0; return 0;
} }
@ -522,8 +512,12 @@ int subnet_available(n2n_sn_t *sss,
int success = 1; int success = 1;
HASH_ITER(hh, sss->communities, cmn, tmpCmn) { HASH_ITER(hh, sss->communities, cmn, tmpCmn) {
if (cmn == comm) continue; if(cmn == comm) {
if(cmn->is_federation == IS_FEDERATION) continue; continue;
}
if(cmn->is_federation == IS_FEDERATION) {
continue;
}
if((net_id <= (cmn->auto_ip_net.net_addr + ~bitlen2mask(cmn->auto_ip_net.net_bitlen))) if((net_id <= (cmn->auto_ip_net.net_addr + ~bitlen2mask(cmn->auto_ip_net.net_bitlen)))
&&(net_id + ~mask >= cmn->auto_ip_net.net_addr)) { &&(net_id + ~mask >= cmn->auto_ip_net.net_addr)) {
success = 0; success = 0;
@ -558,13 +552,17 @@ int assign_one_ip_subnet(n2n_sn_t *sss,
net_increment = (~mask+1); net_increment = (~mask+1);
for(net_id_i = net_id; net_id_i >= sss->min_auto_ip_net.net_addr; net_id_i -= net_increment) { for(net_id_i = net_id; net_id_i >= sss->min_auto_ip_net.net_addr; net_id_i -= net_increment) {
success = subnet_available(sss, comm, net_id_i, mask); success = subnet_available(sss, comm, net_id_i, mask);
if(success) break; if(success) {
break;
}
} }
// ... then upwards // ... then upwards
if(!success) { if(!success) {
for(net_id_i = net_id + net_increment; net_id_i <= sss->max_auto_ip_net.net_addr; net_id_i += net_increment) { for(net_id_i = net_id + net_increment; net_id_i <= sss->max_auto_ip_net.net_addr; net_id_i += net_increment) {
success = subnet_available(sss, comm, net_id_i, mask); success = subnet_available(sss, comm, net_id_i, mask);
if(success) break; if(success) {
break;
}
} }
} }
@ -613,19 +611,23 @@ static int find_edge_time_stamp_and_verify (struct peer_info * edges,
} }
static int re_register_and_purge_supernodes (n2n_sn_t *sss, struct sn_community *comm, time_t *p_last_re_reg_and_purge, time_t now) { static int re_register_and_purge_supernodes (n2n_sn_t *sss, struct sn_community *comm, time_t *p_last_re_reg_and_purge, time_t now) {
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) {
time = now - peer->last_seen; time = now - peer->last_seen;
if(time <= LAST_SEEN_SN_ACTIVE) continue; if(time <= LAST_SEEN_SN_ACTIVE) {
continue;
}
if((time < LAST_SEEN_SN_INACTIVE) if((time < LAST_SEEN_SN_INACTIVE)
|| (peer->purgeable == SN_UNPURGEABLE) || (peer->purgeable == SN_UNPURGEABLE)) {
) {
/* re-regitser (send REGISTER_SUPER) */ /* re-regitser (send REGISTER_SUPER) */
uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0}; uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0};
size_t idx; size_t idx;
@ -643,8 +645,9 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community *
cmn.flags = N2N_FLAGS_FROM_SUPERNODE; cmn.flags = N2N_FLAGS_FROM_SUPERNODE;
memcpy(cmn.community, comm->community, N2N_COMMUNITY_SIZE); memcpy(cmn.community, comm->community, N2N_COMMUNITY_SIZE);
for (idx = 0; idx < N2N_COOKIE_SIZE; ++idx) for(idx = 0; idx < N2N_COOKIE_SIZE; ++idx) {
cookie[idx] = n2n_rand() % 0xff; cookie[idx] = n2n_rand() % 0xff;
}
memcpy(reg.cookie, cookie, N2N_COOKIE_SIZE); memcpy(reg.cookie, cookie, N2N_COOKIE_SIZE);
reg.dev_addr.net_addr = ntohl(peer->dev_addr.net_addr); reg.dev_addr.net_addr = ntohl(peer->dev_addr.net_addr);
@ -666,7 +669,9 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community *
/* sent = */ sendto_sock(sss, &(peer->sock), pktbuf, idx); /* sent = */ sendto_sock(sss, &(peer->sock), pktbuf, idx);
} }
if(time >= LAST_SEEN_SN_INACTIVE) purge_expired_registrations(&(comm->edges), &time, LAST_SEEN_SN_INACTIVE);/* 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*/
}
} }
} }
@ -677,12 +682,14 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community *
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) {
{
struct sn_community *comm, *tmp; struct sn_community *comm, *tmp;
size_t num_reg = 0; size_t num_reg = 0;
if ((now - (*p_last_purge)) < PURGE_REGISTRATION_FREQUENCY) return 0; if((now - (*p_last_purge)) < PURGE_REGISTRATION_FREQUENCY) {
return 0;
}
traceEvent(TRACE_DEBUG, "Purging old communities and edges"); traceEvent(TRACE_DEBUG, "Purging old communities and edges");
@ -690,9 +697,10 @@ static int purge_expired_communities(n2n_sn_t *sss,
num_reg += purge_peer_list(&comm->edges, now - REGISTRATION_TIMEOUT); num_reg += purge_peer_list(&comm->edges, now - REGISTRATION_TIMEOUT);
if((comm->edges == NULL) && (comm->purgeable == COMMUNITY_PURGEABLE)) { if((comm->edges == NULL) && (comm->purgeable == COMMUNITY_PURGEABLE)) {
traceEvent(TRACE_INFO, "Purging idle community %s", comm->community); traceEvent(TRACE_INFO, "Purging idle community %s", comm->community);
if (NULL != comm->header_encryption_ctx) if(NULL != comm->header_encryption_ctx) {
/* this should not happen as 'purgeable' and thus only communities w/o encrypted header here */ /* this should not happen as 'purgeable' and thus only communities w/o encrypted header here */
free(comm->header_encryption_ctx); free(comm->header_encryption_ctx);
}
HASH_DEL(sss->communities, comm); HASH_DEL(sss->communities, comm);
free(comm); free(comm);
} }
@ -706,6 +714,7 @@ static int purge_expired_communities(n2n_sn_t *sss,
static int number_enc_packets_sort (struct sn_community *a, struct sn_community *b) { static int number_enc_packets_sort (struct sn_community *a, struct sn_community *b) {
// comparison function for sorting communities in descending order of their // comparison function for sorting communities in descending order of their
// number_enc_packets-fields // number_enc_packets-fields
return (b->number_enc_packets - a->number_enc_packets); return (b->number_enc_packets - a->number_enc_packets);
@ -713,11 +722,13 @@ static int number_enc_packets_sort (struct sn_community *a, struct sn_community
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) {
{
struct sn_community *comm, *tmp; struct sn_community *comm, *tmp;
if ((now - (*p_last_sort)) < SORT_COMMUNITIES_INTERVAL) return 0; if((now - (*p_last_sort)) < SORT_COMMUNITIES_INTERVAL) {
return 0;
}
// this routine gets periodically called as defined in SORT_COMMUNITIES_INTERVAL // this routine gets periodically called as defined in SORT_COMMUNITIES_INTERVAL
// it sorts the communities in descending order of their number_enc_packets-fields... // it sorts the communities in descending order of their number_enc_packets-fields...
@ -740,6 +751,7 @@ static int process_mgmt(n2n_sn_t *sss,
const uint8_t *mgmt_buf, const uint8_t *mgmt_buf,
size_t mgmt_size, size_t mgmt_size,
time_t now) { time_t now) {
char resbuf[N2N_SN_PKTBUF_SIZE]; char resbuf[N2N_SN_PKTBUF_SIZE];
size_t ressize = 0; size_t ressize = 0;
uint32_t num_edges = 0; uint32_t num_edges = 0;
@ -827,8 +839,8 @@ static int process_mgmt(n2n_sn_t *sss,
static int sendto_mgmt (n2n_sn_t *sss, static int sendto_mgmt (n2n_sn_t *sss,
const struct sockaddr_in *sender_sock, const struct sockaddr_in *sender_sock,
const uint8_t *mgmt_buf, const uint8_t *mgmt_buf,
size_t mgmt_size) size_t mgmt_size) {
{
ssize_t r = sendto(sss->mgmt_sock, mgmt_buf, mgmt_size, 0 /*flags*/, ssize_t r = sendto(sss->mgmt_sock, mgmt_buf, mgmt_size, 0 /*flags*/,
(struct sockaddr *)sender_sock, sizeof (struct sockaddr_in)); (struct sockaddr *)sender_sock, sizeof (struct sockaddr_in));
@ -837,6 +849,7 @@ static int sendto_mgmt(n2n_sn_t *sss,
traceEvent (TRACE_ERROR, "sendto_mgmt : sendto failed. %s", strerror (errno)); traceEvent (TRACE_ERROR, "sendto_mgmt : sendto failed. %s", strerror (errno));
return -1; return -1;
} }
return 0; return 0;
} }
@ -847,8 +860,8 @@ static int process_udp(n2n_sn_t * sss,
const struct sockaddr_in * sender_sock, const struct sockaddr_in * sender_sock,
uint8_t * udp_buf, uint8_t * udp_buf,
size_t udp_size, size_t udp_size,
time_t now) time_t now) {
{
n2n_common_t cmn; /* common fields in the packet header */ n2n_common_t cmn; /* common fields in the packet header */
size_t rem; size_t rem;
size_t idx; size_t idx;
@ -903,8 +916,9 @@ static int process_udp(n2n_sn_t * sss,
uint32_t ret = 0; uint32_t ret = 0;
HASH_ITER(hh, sss->communities, comm, tmp) { HASH_ITER(hh, sss->communities, comm, tmp) {
/* skip the definitely unencrypted communities */ /* skip the definitely unencrypted communities */
if (comm->header_encryption == HEADER_ENCRYPTION_NONE) if(comm->header_encryption == HEADER_ENCRYPTION_NONE) {
continue; continue;
}
uint16_t checksum = 0; uint16_t checksum = 0;
if((ret = packet_header_decrypt(udp_buf, udp_size, comm->community, comm->header_encryption_ctx, if((ret = packet_header_decrypt(udp_buf, udp_size, comm->community, comm->header_encryption_ctx,
comm->header_iv_ctx, comm->header_iv_ctx,
@ -964,8 +978,7 @@ static int process_udp(n2n_sn_t * sss,
--(cmn.ttl); /* The value copied into all forwarded packets. */ --(cmn.ttl); /* The value copied into all forwarded packets. */
switch(msg_type) { switch(msg_type) {
case MSG_TYPE_PACKET: case MSG_TYPE_PACKET: {
{
/* PACKET from one edge to another edge via supernode. */ /* PACKET from one edge to another edge via supernode. */
/* pkt will be modified in place and recoded to an output of potentially /* pkt will be modified in place and recoded to an output of potentially
@ -1012,7 +1025,6 @@ static int process_udp(n2n_sn_t * sss,
memcpy(pkt.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); memcpy(pkt.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE);
rec_buf = encbuf; rec_buf = encbuf;
/* Re-encode the header. */ /* Re-encode the header. */
encode_PACKET(encbuf, &encx, &cmn2, &pkt); encode_PACKET(encbuf, &encx, &cmn2, &pkt);
uint16_t oldEncx = encx; uint16_t oldEncx = encx;
@ -1020,11 +1032,11 @@ static int process_udp(n2n_sn_t * sss,
/* Copy the original payload unchanged */ /* Copy the original payload unchanged */
encode_buf(encbuf, &encx, (udp_buf + idx), (udp_size - idx)); encode_buf(encbuf, &encx, (udp_buf + idx), (udp_size - idx));
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
packet_header_encrypt(rec_buf, oldEncx, comm->header_encryption_ctx, packet_header_encrypt(rec_buf, oldEncx, comm->header_encryption_ctx,
comm->header_iv_ctx, comm->header_iv_ctx,
time_stamp(), pearson_hash_16(rec_buf, encx)); time_stamp(), pearson_hash_16(rec_buf, encx));
}
} else { } else {
/* Already from a supernode. Nothing to modify, just pass to /* Already from a supernode. Nothing to modify, just pass to
* destination. */ * destination. */
@ -1034,21 +1046,23 @@ static int process_udp(n2n_sn_t * sss,
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, idx, comm->header_encryption_ctx, packet_header_encrypt(rec_buf, idx, comm->header_encryption_ctx,
comm->header_iv_ctx, comm->header_iv_ctx,
time_stamp(), pearson_hash_16(rec_buf, udp_size)); time_stamp(), pearson_hash_16(rec_buf, udp_size));
} }
}
/* 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);
else } 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; 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;
@ -1104,20 +1118,24 @@ static int process_udp(n2n_sn_t * sss,
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, comm->header_encryption_ctx, packet_header_encrypt(rec_buf, encx, comm->header_encryption_ctx,
comm->header_iv_ctx, comm->header_iv_ctx,
time_stamp(), pearson_hash_16(rec_buf, encx)); time_stamp(), pearson_hash_16(rec_buf, encx));
}
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); /* 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 not be via supernode"); traceEvent(TRACE_DEBUG, "Rx REGISTER_ACK (NOT IMPLEMENTED) Should not be via supernode");
break; break;
case MSG_TYPE_REGISTER_SUPER: }
{
case MSG_TYPE_REGISTER_SUPER: {
n2n_REGISTER_SUPER_t reg; n2n_REGISTER_SUPER_t reg;
n2n_REGISTER_SUPER_ACK_t ack; n2n_REGISTER_SUPER_ACK_t ack;
n2n_REGISTER_SUPER_NAK_t nak; n2n_REGISTER_SUPER_NAK_t nak;
@ -1248,11 +1266,9 @@ static int process_udp(n2n_sn_t * sss,
continue; continue;
} }
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) >= (2*LAST_SEEN_SN_ACTIVE)) continue; /* skip long-time-not-seen supernodes. if((now - peer->last_seen) >= (2*LAST_SEEN_SN_ACTIVE)) continue; /* skip long-time-not-seen supernodes.
* We need to allow for a little extra time because supernodes sometimes exceed * We need to allow for a little extra time because supernodes sometimes exceed
* their SN_ACTIVE time before they get re-registred to. */ * their SN_ACTIVE time before they get re-registred to. */
if(((++num)*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE) > REG_SUPER_ACK_PAYLOAD_SPACE) break; /* no more space available in REGISTER_SUPER_ACK payload */ if(((++num)*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE) > REG_SUPER_ACK_PAYLOAD_SPACE) break; /* no more space available in REGISTER_SUPER_ACK payload */
memcpy(&(payload->sock), &(peer->sock), sizeof(n2n_sock_t)); memcpy(&(payload->sock), &(peer->sock), sizeof(n2n_sock_t));
memcpy(&(payload->mac), &(peer->mac_addr), sizeof(n2n_mac_t)); memcpy(&(payload->mac), &(peer->mac_addr), sizeof(n2n_mac_t));
@ -1261,7 +1277,6 @@ static int process_udp(n2n_sn_t * sss,
} }
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)));
@ -1276,17 +1291,16 @@ static int process_udp(n2n_sn_t * sss,
if(ret_value == update_edge_auth_fail) { if(ret_value == update_edge_auth_fail) {
cmn2.pc = n2n_register_super_nak; cmn2.pc = n2n_register_super_nak;
memcpy(&(nak.cookie), &(reg.cookie), sizeof(n2n_cookie_t)); memcpy(&(nak.cookie), &(reg.cookie), sizeof(n2n_cookie_t));
memcpy(&(nak.srcMac), &(reg.edgeMac), sizeof(n2n_mac_t)); memcpy(&(nak.srcMac), &(reg.edgeMac), sizeof(n2n_mac_t));
encode_REGISTER_SUPER_NAK(ackbuf, &encx, &cmn2, &nak); encode_REGISTER_SUPER_NAK(ackbuf, &encx, &cmn2, &nak);
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));
@ -1305,10 +1319,11 @@ static int process_udp(n2n_sn_t * sss,
cmn2.pc = n2n_register_super; cmn2.pc = n2n_register_super;
encode_REGISTER_SUPER(ackbuf, &encx, &cmn2, &reg); encode_REGISTER_SUPER(ackbuf, &encx, &cmn2, &reg);
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));
}
try_broadcast(sss, NULL, &cmn, reg.edgeMac, from_supernode, ackbuf, encx); try_broadcast(sss, NULL, &cmn, reg.edgeMac, from_supernode, ackbuf, encx);
@ -1321,6 +1336,7 @@ static int process_udp(n2n_sn_t * sss,
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));
@ -1337,6 +1353,7 @@ static int process_udp(n2n_sn_t * sss,
} }
break; break;
} }
case MSG_TYPE_UNREGISTER_SUPER: { case MSG_TYPE_UNREGISTER_SUPER: {
n2n_UNREGISTER_SUPER_t unreg; n2n_UNREGISTER_SUPER_t unreg;
struct peer_info *peer; struct peer_info *peer;
@ -1376,6 +1393,7 @@ static int process_udp(n2n_sn_t * sss,
break; break;
} }
case MSG_TYPE_REGISTER_SUPER_ACK: { case MSG_TYPE_REGISTER_SUPER_ACK: {
n2n_REGISTER_SUPER_ACK_t ack; n2n_REGISTER_SUPER_ACK_t ack;
size_t encx = 0; size_t encx = 0;
@ -1455,6 +1473,7 @@ static int process_udp(n2n_sn_t * sss,
break; break;
} }
case MSG_TYPE_REGISTER_SUPER_NAK: { case MSG_TYPE_REGISTER_SUPER_NAK: {
n2n_REGISTER_SUPER_NAK_t nak; n2n_REGISTER_SUPER_NAK_t nak;
size_t encx = 0; size_t encx = 0;
@ -1499,6 +1518,7 @@ static int process_udp(n2n_sn_t * sss,
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];
@ -1566,11 +1586,12 @@ static int process_udp(n2n_sn_t * sss,
encode_PEER_INFO(encbuf, &encx, &cmn2, &pi); encode_PEER_INFO(encbuf, &encx, &cmn2, &pi);
if(comm) { if(comm) {
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
packet_header_encrypt(encbuf, encx, comm->header_encryption_ctx, packet_header_encrypt(encbuf, encx, comm->header_encryption_ctx,
comm->header_iv_ctx, comm->header_iv_ctx,
time_stamp(), pearson_hash_16(encbuf, encx)); 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));
@ -1597,10 +1618,11 @@ static int process_udp(n2n_sn_t * sss,
encode_PEER_INFO(encbuf, &encx, &cmn2, &pi); encode_PEER_INFO(encbuf, &encx, &cmn2, &pi);
if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) {
packet_header_encrypt(encbuf, encx, comm->header_encryption_ctx, packet_header_encrypt(encbuf, encx, comm->header_encryption_ctx,
comm->header_iv_ctx, comm->header_iv_ctx,
time_stamp(), pearson_hash_16(encbuf, encx)); time_stamp(), pearson_hash_16(encbuf, encx));
}
if(cmn.flags & N2N_FLAGS_SOCKET) { if(cmn.flags & N2N_FLAGS_SOCKET) {
sendto_sock(sss, &query.sock, encbuf, encx); sendto_sock(sss, &query.sock, encbuf, encx);
@ -1630,10 +1652,11 @@ static int process_udp(n2n_sn_t * sss,
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, comm->header_encryption_ctx, packet_header_encrypt(encbuf, encx, comm->header_encryption_ctx,
comm->header_iv_ctx, comm->header_iv_ctx,
time_stamp(), pearson_hash_16(encbuf, encx)); time_stamp(), pearson_hash_16(encbuf, encx));
}
try_broadcast(sss, NULL, &cmn, query.srcMac, from_supernode, encbuf, encx); try_broadcast(sss, NULL, &cmn, query.srcMac, from_supernode, encbuf, encx);
} }
@ -1642,6 +1665,7 @@ static int process_udp(n2n_sn_t * sss,
break; break;
} }
default: default:
/* Not a known message type */ /* Not a known message type */
traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored", (signed int)msg_type); traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored", (signed int)msg_type);
@ -1652,8 +1676,8 @@ static int process_udp(n2n_sn_t * sss,
/** Long lived processing entry point. Split out from main to simply /** Long lived processing entry point. Split out from main to simply
* daemonisation on some platforms. */ * daemonisation on some platforms. */
int run_sn_loop(n2n_sn_t *sss, int *keep_running) int run_sn_loop (n2n_sn_t *sss, int *keep_running) {
{
uint8_t pktbuf[N2N_SN_PKTBUF_SIZE]; uint8_t pktbuf[N2N_SN_PKTBUF_SIZE];
time_t last_purge_edges = 0; time_t last_purge_edges = 0;
time_t last_sort_communities = 0; time_t last_sort_communities = 0;
@ -1661,8 +1685,7 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
sss->start_time = time(NULL); sss->start_time = time(NULL);
while (*keep_running) while(*keep_running) {
{
int rc; int rc;
ssize_t bread; ssize_t bread;
int max_sock; int max_sock;
@ -1682,10 +1705,8 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
now = time(NULL); now = time(NULL);
if (rc > 0) if(rc > 0) {
{ if(FD_ISSET(sss->sock, &socket_mask)) {
if (FD_ISSET(sss->sock, &socket_mask))
{
struct sockaddr_in sender_sock; struct sockaddr_in sender_sock;
socklen_t i; socklen_t i;
@ -1697,8 +1718,7 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
#ifdef WIN32 #ifdef WIN32
&& (WSAGetLastError() != WSAECONNRESET) && (WSAGetLastError() != WSAECONNRESET)
#endif #endif
) ) {
{
/* For UDP bread of zero just means no data (unlike TCP). */ /* For UDP bread of zero just means no data (unlike TCP). */
/* The fd is no good now. Maybe we lost our interface. */ /* The fd is no good now. Maybe we lost our interface. */
traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno));
@ -1710,15 +1730,13 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
} }
/* We have a datagram to process */ /* We have a datagram to process */
if (bread > 0) if(bread > 0) {
{
/* And the datagram has data (not just a header) */ /* And the datagram has data (not just a header) */
process_udp(sss, &sender_sock, pktbuf, bread, now); process_udp(sss, &sender_sock, pktbuf, bread, now);
} }
} }
if (FD_ISSET(sss->mgmt_sock, &socket_mask)) if(FD_ISSET(sss->mgmt_sock, &socket_mask)) {
{
struct sockaddr_in sender_sock; struct sockaddr_in sender_sock;
size_t i; size_t i;
@ -1726,8 +1744,7 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
bread = recvfrom(sss->mgmt_sock, pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/, bread = recvfrom(sss->mgmt_sock, pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/,
(struct sockaddr *)&sender_sock, (socklen_t *)&i); (struct sockaddr *)&sender_sock, (socklen_t *)&i);
if (bread <= 0) if(bread <= 0) {
{
traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno));
*keep_running = 0; *keep_running = 0;
break; break;
@ -1736,9 +1753,7 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
/* We have a datagram to process */ /* We have a datagram to process */
process_mgmt(sss, &sender_sock, pktbuf, bread, now); process_mgmt(sss, &sender_sock, pktbuf, bread, now);
} }
} } else {
else
{
traceEvent(TRACE_DEBUG, "timeout"); traceEvent(TRACE_DEBUG, "timeout");
} }