|
@ -68,11 +68,10 @@ static int try_broadcast( n2n_sn_t * sss, |
|
|
const uint8_t * pktbuf, |
|
|
const uint8_t * pktbuf, |
|
|
size_t pktsize); |
|
|
size_t pktsize); |
|
|
|
|
|
|
|
|
|
|
|
static n2n_sn_t sss_node; |
|
|
|
|
|
|
|
|
/** Initialise the supernode structure */ |
|
|
/** Initialise the supernode structure */ |
|
|
static int init_sn( n2n_sn_t * sss ) |
|
|
static int init_sn(n2n_sn_t * sss) { |
|
|
{ |
|
|
|
|
|
#ifdef WIN32 |
|
|
#ifdef WIN32 |
|
|
initWin32(); |
|
|
initWin32(); |
|
|
#endif |
|
|
#endif |
|
@ -134,8 +133,7 @@ static int update_edge( n2n_sn_t * sss, |
|
|
|
|
|
|
|
|
scan = find_peer_by_mac(sss->edges, edgeMac); |
|
|
scan = find_peer_by_mac(sss->edges, edgeMac); |
|
|
|
|
|
|
|
|
if ( NULL == scan ) |
|
|
if(NULL == scan) { |
|
|
{ |
|
|
|
|
|
/* Not known */ |
|
|
/* Not known */ |
|
|
|
|
|
|
|
|
scan = (struct peer_info*)calloc(1, sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */ |
|
|
scan = (struct peer_info*)calloc(1, sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */ |
|
@ -151,9 +149,7 @@ static int update_edge( n2n_sn_t * sss, |
|
|
traceEvent(TRACE_INFO, "update_edge created %s ==> %s", |
|
|
traceEvent(TRACE_INFO, "update_edge created %s ==> %s", |
|
|
macaddr_str(mac_buf, edgeMac), |
|
|
macaddr_str(mac_buf, edgeMac), |
|
|
sock_to_cstr(sockbuf, sender_sock)); |
|
|
sock_to_cstr(sockbuf, sender_sock)); |
|
|
} |
|
|
} else { |
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
/* Known */ |
|
|
/* Known */ |
|
|
if((0 != memcmp(community, scan->community_name, sizeof(n2n_community_t))) || |
|
|
if((0 != memcmp(community, scan->community_name, sizeof(n2n_community_t))) || |
|
|
(0 != sock_equal(sender_sock, &(scan->sock)))) |
|
|
(0 != sock_equal(sender_sock, &(scan->sock)))) |
|
@ -417,15 +413,28 @@ static int load_allowed_n2n_communities(char *path) { |
|
|
free(s); |
|
|
free(s); |
|
|
|
|
|
|
|
|
while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) { |
|
|
while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) { |
|
|
if((strlen(line) < 2) || line[0] == '#') |
|
|
int len = strlen(line); |
|
|
|
|
|
|
|
|
|
|
|
if((len < 2) || line[0] == '#') |
|
|
continue; |
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
len--; |
|
|
|
|
|
while(len > 0) { |
|
|
|
|
|
if((line[len] == '\n') || (line[len] == '\r')) { |
|
|
|
|
|
line[len] = '\0'; |
|
|
|
|
|
len--; |
|
|
|
|
|
} else |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
s = (struct n2n_allowed_communities*)malloc(sizeof(struct n2n_allowed_communities)); |
|
|
s = (struct n2n_allowed_communities*)malloc(sizeof(struct n2n_allowed_communities)); |
|
|
|
|
|
|
|
|
if(s != NULL) { |
|
|
if(s != NULL) { |
|
|
strncpy((char*)s->community, line, N2N_COMMUNITY_SIZE); |
|
|
strncpy((char*)s->community, line, N2N_COMMUNITY_SIZE); |
|
|
HASH_ADD_STR(allowed_communities, community, s); |
|
|
HASH_ADD_STR(allowed_communities, community, s); |
|
|
num_communities++; |
|
|
num_communities++; |
|
|
|
|
|
traceEvent(TRACE_INFO, "Added allowed community '%s' [total: %u]", |
|
|
|
|
|
(char*)s->community, num_communities); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -454,9 +463,11 @@ static int process_udp( n2n_sn_t * sss, |
|
|
macstr_t mac_buf; |
|
|
macstr_t mac_buf; |
|
|
macstr_t mac_buf2; |
|
|
macstr_t mac_buf2; |
|
|
n2n_sock_str_t sockbuf; |
|
|
n2n_sock_str_t sockbuf; |
|
|
|
|
|
char buf[32]; |
|
|
|
|
|
|
|
|
|
|
|
traceEvent(TRACE_DEBUG, "Processing incoming UDP packet [len: %lu][sender: %s:%u]", |
|
|
traceEvent( TRACE_DEBUG, "process_udp(%lu)", udp_size ); |
|
|
udp_size, intoa(ntohl(sender_sock->sin_addr.s_addr), buf, sizeof(buf)), |
|
|
|
|
|
ntohs(sender_sock->sin_port)); |
|
|
|
|
|
|
|
|
/* Use decode_common() to determine the kind of packet then process it:
|
|
|
/* Use decode_common() to determine the kind of packet then process it:
|
|
|
* |
|
|
* |
|
@ -469,8 +480,7 @@ static int process_udp( n2n_sn_t * sss, |
|
|
|
|
|
|
|
|
rem = udp_size; /* Counts down bytes of packet to protect against buffer overruns. */ |
|
|
rem = udp_size; /* Counts down bytes of packet to protect against buffer overruns. */ |
|
|
idx = 0; /* marches through packet header as parts are decoded. */ |
|
|
idx = 0; /* marches through packet header as parts are decoded. */ |
|
|
if ( decode_common(&cmn, udp_buf, &rem, &idx) < 0 ) |
|
|
if(decode_common(&cmn, udp_buf, &rem, &idx) < 0) { |
|
|
{ |
|
|
|
|
|
traceEvent(TRACE_ERROR, "Failed to decode common section"); |
|
|
traceEvent(TRACE_ERROR, "Failed to decode common section"); |
|
|
return -1; /* failed to decode packet */ |
|
|
return -1; /* failed to decode packet */ |
|
|
} |
|
|
} |
|
@ -478,16 +488,14 @@ static int process_udp( n2n_sn_t * sss, |
|
|
msg_type = cmn.pc; /* packet code */ |
|
|
msg_type = cmn.pc; /* packet code */ |
|
|
from_supernode= cmn.flags & N2N_FLAGS_FROM_SUPERNODE; |
|
|
from_supernode= cmn.flags & N2N_FLAGS_FROM_SUPERNODE; |
|
|
|
|
|
|
|
|
if ( cmn.ttl < 1 ) |
|
|
if(cmn.ttl < 1) { |
|
|
{ |
|
|
|
|
|
traceEvent(TRACE_WARNING, "Expired TTL"); |
|
|
traceEvent(TRACE_WARNING, "Expired TTL"); |
|
|
return 0; /* Don't process further */ |
|
|
return 0; /* Don't process further */ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
--(cmn.ttl); /* The value copied into all forwarded packets. */ |
|
|
--(cmn.ttl); /* The value copied into all forwarded packets. */ |
|
|
|
|
|
|
|
|
if ( msg_type == MSG_TYPE_PACKET ) |
|
|
if(msg_type == 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
|
|
@ -505,14 +513,13 @@ static int process_udp( n2n_sn_t * sss, |
|
|
|
|
|
|
|
|
unicast = (0 == is_multi_broadcast(pkt.dstMac)); |
|
|
unicast = (0 == is_multi_broadcast(pkt.dstMac)); |
|
|
|
|
|
|
|
|
traceEvent( TRACE_DEBUG, "Rx PACKET (%s) %s -> %s %s", |
|
|
traceEvent(TRACE_DEBUG, "RX PACKET (%s) %s -> %s %s", |
|
|
(unicast?"unicast":"multicast"), |
|
|
(unicast?"unicast":"multicast"), |
|
|
macaddr_str(mac_buf, pkt.srcMac), |
|
|
macaddr_str(mac_buf, pkt.srcMac), |
|
|
macaddr_str(mac_buf2, pkt.dstMac), |
|
|
macaddr_str(mac_buf2, pkt.dstMac), |
|
|
(from_supernode?"from sn":"local")); |
|
|
(from_supernode?"from sn":"local")); |
|
|
|
|
|
|
|
|
if ( !from_supernode ) |
|
|
if(!from_supernode) { |
|
|
{ |
|
|
|
|
|
memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); |
|
|
memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); |
|
|
|
|
|
|
|
|
/* We are going to add socket even if it was not there before */ |
|
|
/* We are going to add socket even if it was not there before */ |
|
@ -529,9 +536,7 @@ 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)); |
|
|
} |
|
|
} else { |
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
/* Already from a supernode. Nothing to modify, just pass to
|
|
|
/* Already from a supernode. Nothing to modify, just pass to
|
|
|
* destination. */ |
|
|
* destination. */ |
|
|
|
|
|
|
|
@ -543,16 +548,11 @@ static int process_udp( n2n_sn_t * sss, |
|
|
|
|
|
|
|
|
/* Common section to forward the final product. */ |
|
|
/* Common section to forward the final product. */ |
|
|
if(unicast) |
|
|
if(unicast) |
|
|
{ |
|
|
|
|
|
try_forward(sss, &cmn, pkt.dstMac, rec_buf, encx); |
|
|
try_forward(sss, &cmn, pkt.dstMac, rec_buf, encx); |
|
|
} |
|
|
|
|
|
else |
|
|
else |
|
|
{ |
|
|
|
|
|
try_broadcast(sss, &cmn, pkt.srcMac, rec_buf, encx); |
|
|
try_broadcast(sss, &cmn, pkt.srcMac, rec_buf, encx); |
|
|
} |
|
|
|
|
|
}/* MSG_TYPE_PACKET */ |
|
|
}/* MSG_TYPE_PACKET */ |
|
|
else if ( msg_type == MSG_TYPE_REGISTER ) |
|
|
else if(msg_type == 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; |
|
@ -567,15 +567,13 @@ static int process_udp( n2n_sn_t * sss, |
|
|
|
|
|
|
|
|
unicast = (0 == is_multi_broadcast(reg.dstMac)); |
|
|
unicast = (0 == is_multi_broadcast(reg.dstMac)); |
|
|
|
|
|
|
|
|
if ( unicast ) |
|
|
if(unicast) { |
|
|
{ |
|
|
|
|
|
traceEvent(TRACE_DEBUG, "Rx REGISTER %s -> %s %s", |
|
|
traceEvent(TRACE_DEBUG, "Rx REGISTER %s -> %s %s", |
|
|
macaddr_str(mac_buf, reg.srcMac), |
|
|
macaddr_str(mac_buf, reg.srcMac), |
|
|
macaddr_str(mac_buf2, reg.dstMac), |
|
|
macaddr_str(mac_buf2, reg.dstMac), |
|
|
((cmn.flags & N2N_FLAGS_FROM_SUPERNODE)?"from sn":"local")); |
|
|
((cmn.flags & N2N_FLAGS_FROM_SUPERNODE)?"from sn":"local")); |
|
|
|
|
|
|
|
|
if ( 0 != (cmn.flags & N2N_FLAGS_FROM_SUPERNODE) ) |
|
|
if(0 != (cmn.flags & N2N_FLAGS_FROM_SUPERNODE)) { |
|
|
{ |
|
|
|
|
|
memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); |
|
|
memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); |
|
|
|
|
|
|
|
|
/* We are going to add socket even if it was not there before */ |
|
|
/* We are going to add socket even if it was not there before */ |
|
@ -592,9 +590,7 @@ 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)); |
|
|
} |
|
|
} else { |
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
/* Already from a supernode. Nothing to modify, just pass to
|
|
|
/* Already from a supernode. Nothing to modify, just pass to
|
|
|
* destination. */ |
|
|
* destination. */ |
|
|
|
|
|
|
|
@ -603,19 +599,11 @@ static int process_udp( n2n_sn_t * sss, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
try_forward(sss, &cmn, reg.dstMac, rec_buf, encx); /* unicast only */ |
|
|
try_forward(sss, &cmn, reg.dstMac, rec_buf, encx); /* unicast only */ |
|
|
} |
|
|
} else |
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination"); |
|
|
traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination"); |
|
|
} |
|
|
} else if(msg_type == MSG_TYPE_REGISTER_ACK) |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
else if ( msg_type == 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"); |
|
|
} |
|
|
else if(msg_type == MSG_TYPE_REGISTER_SUPER) { |
|
|
else if ( msg_type == 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_common_t cmn2; |
|
|
n2n_common_t cmn2; |
|
@ -664,6 +652,9 @@ static int process_udp( n2n_sn_t * sss, |
|
|
traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]", |
|
|
traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_ACK 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))); |
|
|
|
|
|
} else { |
|
|
|
|
|
traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", |
|
|
|
|
|
(char*)cmn.community); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -673,8 +664,7 @@ static int process_udp( n2n_sn_t * sss, |
|
|
/* *************************************************** */ |
|
|
/* *************************************************** */ |
|
|
|
|
|
|
|
|
/** 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" |
|
@ -682,12 +672,13 @@ static void help() |
|
|
); |
|
|
); |
|
|
printf("supernode "); |
|
|
printf("supernode "); |
|
|
printf("-l <lport> "); |
|
|
printf("-l <lport> "); |
|
|
printf("-c <community file path> "); |
|
|
printf("-c <path> "); |
|
|
printf("[-f] "); |
|
|
printf("[-f] "); |
|
|
printf("[-v] "); |
|
|
printf("[-v] "); |
|
|
printf("\n\n"); |
|
|
printf("\n\n"); |
|
|
|
|
|
|
|
|
printf("-l <lport>\tSet UDP main listen port to <lport>\n"); |
|
|
printf("-l <lport>\tSet UDP main listen port to <lport>\n"); |
|
|
|
|
|
printf("-c <path>\tFile containing the allowed communities.\n"); |
|
|
#if defined(N2N_HAVE_DAEMON) |
|
|
#if defined(N2N_HAVE_DAEMON) |
|
|
printf("-f \tRun in foreground.\n"); |
|
|
printf("-f \tRun in foreground.\n"); |
|
|
#endif /* #if defined(N2N_HAVE_DAEMON) */ |
|
|
#endif /* #if defined(N2N_HAVE_DAEMON) */ |
|
@ -705,44 +696,33 @@ static int run_loop( n2n_sn_t * sss ); |
|
|
/* *************************************************** */ |
|
|
/* *************************************************** */ |
|
|
|
|
|
|
|
|
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) { |
|
|
case 'l': /* local-port */ |
|
|
case 'l': /* local-port */ |
|
|
{ |
|
|
|
|
|
sss->lport = atoi(_optarg); |
|
|
sss->lport = atoi(_optarg); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case 'c': /* community file */ |
|
|
case 'c': /* community file */ |
|
|
load_allowed_n2n_communities(optarg); |
|
|
load_allowed_n2n_communities(optarg); |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case 'f': /* foreground */ |
|
|
case 'f': /* foreground */ |
|
|
{ |
|
|
|
|
|
sss->daemon = 0; |
|
|
sss->daemon = 0; |
|
|
break; |
|
|
break; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case 'h': /* help */ |
|
|
case 'h': /* help */ |
|
|
{ |
|
|
|
|
|
help(); |
|
|
help(); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case 'v': /* verbose */ |
|
|
case 'v': /* verbose */ |
|
|
{ |
|
|
traceLevel = 4; /* DEBUG */ |
|
|
++traceLevel; |
|
|
|
|
|
break; |
|
|
break; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
default: |
|
|
{ |
|
|
|
|
|
traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored.", (char)optkey); |
|
|
traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored.", (char)optkey); |
|
|
return(-1); |
|
|
return(-1); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return(0); |
|
|
return(0); |
|
|
} |
|
|
} |
|
@ -763,8 +743,7 @@ static const struct option long_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, |
|
|
while((c = getopt_long(argc, argv, "fl:c:vh", |
|
|
"fl:c:vh", |
|
|
|
|
|
long_options, NULL)) != '?') { |
|
|
long_options, NULL)) != '?') { |
|
|
if(c == 255) break; |
|
|
if(c == 255) break; |
|
|
setOption(c, optarg, sss); |
|
|
setOption(c, optarg, sss); |
|
@ -778,7 +757,9 @@ 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] == '\'')) s++; |
|
|
while(isspace(s[0]) || (s[0] == '"') || (s[0] == '\'')) |
|
|
|
|
|
s++; |
|
|
|
|
|
|
|
|
if(s[0] == 0) return s; |
|
|
if(s[0] == 0) return s; |
|
|
|
|
|
|
|
|
end = &s[strlen(s) - 1]; |
|
|
end = &s[strlen(s) - 1]; |
|
@ -856,36 +837,62 @@ static int loadFromFile(const char *path, n2n_sn_t *sss) { |
|
|
|
|
|
|
|
|
/* *************************************************** */ |
|
|
/* *************************************************** */ |
|
|
|
|
|
|
|
|
|
|
|
static void dump_registrations(int signo) { |
|
|
|
|
|
struct peer_info * list = sss_node.edges; |
|
|
|
|
|
char buf[32]; |
|
|
|
|
|
time_t now = time(NULL); |
|
|
|
|
|
u_int num = 0; |
|
|
|
|
|
|
|
|
|
|
|
traceEvent(TRACE_NORMAL, "===================================="); |
|
|
|
|
|
|
|
|
|
|
|
while(list != NULL) { |
|
|
|
|
|
if(list->sock.family == AF_INET) |
|
|
|
|
|
traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: %u.%u.%u.%u:%u][community: %s][last seen: %u sec ago]", |
|
|
|
|
|
++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.port, |
|
|
|
|
|
(char*)list->community_name, |
|
|
|
|
|
now-list->last_seen); |
|
|
|
|
|
else |
|
|
|
|
|
traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: IPv6:%u][community: %s][last seen: %u sec ago]", |
|
|
|
|
|
++num, macaddr_str(buf, list->mac_addr), list->sock.port, |
|
|
|
|
|
(char*)list->community_name, |
|
|
|
|
|
now-list->last_seen); |
|
|
|
|
|
|
|
|
|
|
|
list = list->next; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
traceEvent(TRACE_NORMAL, "===================================="); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* *************************************************** */ |
|
|
|
|
|
|
|
|
/** 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; |
|
|
n2n_sn_t sss; |
|
|
|
|
|
|
|
|
|
|
|
if(argc == 1) |
|
|
if(argc == 1) |
|
|
help(); |
|
|
help(); |
|
|
|
|
|
|
|
|
init_sn(&sss); |
|
|
init_sn(&sss_node); |
|
|
|
|
|
|
|
|
#ifndef WIN32 |
|
|
#ifndef WIN32 |
|
|
if((argc >= 2) && (argv[1][0] != '-')) |
|
|
if((argc >= 2) && (argv[1][0] != '-')) { |
|
|
{ |
|
|
rc = loadFromFile(argv[1], &sss_node); |
|
|
rc = loadFromFile(argv[1], &sss); |
|
|
|
|
|
if(argc > 2) |
|
|
if(argc > 2) |
|
|
rc = loadFromCLI(argc, argv, &sss); |
|
|
rc = loadFromCLI(argc, argv, &sss_node); |
|
|
} else |
|
|
} else |
|
|
#endif |
|
|
#endif |
|
|
rc = loadFromCLI(argc, argv, &sss); |
|
|
rc = loadFromCLI(argc, argv, &sss_node); |
|
|
|
|
|
|
|
|
if(rc < 0) |
|
|
if(rc < 0) |
|
|
return(-1); |
|
|
return(-1); |
|
|
|
|
|
|
|
|
#if defined(N2N_HAVE_DAEMON) |
|
|
#if defined(N2N_HAVE_DAEMON) |
|
|
if (sss.daemon) |
|
|
if(sss_node.daemon) { |
|
|
{ |
|
|
|
|
|
useSyslog=1; /* traceEvent output now goes to syslog. */ |
|
|
useSyslog=1; /* traceEvent output now goes to syslog. */ |
|
|
if ( -1 == daemon( 0, 0 ) ) |
|
|
|
|
|
{ |
|
|
if(-1 == daemon(0, 0)) { |
|
|
traceEvent(TRACE_ERROR, "Failed to become daemon."); |
|
|
traceEvent(TRACE_ERROR, "Failed to become daemon."); |
|
|
exit(-5); |
|
|
exit(-5); |
|
|
} |
|
|
} |
|
@ -894,45 +901,38 @@ int main( int argc, char * const argv[] ) |
|
|
|
|
|
|
|
|
traceEvent(TRACE_DEBUG, "traceLevel is %d", traceLevel); |
|
|
traceEvent(TRACE_DEBUG, "traceLevel is %d", traceLevel); |
|
|
|
|
|
|
|
|
sss.sock = open_socket(sss.lport, 1 /*bind ANY*/ ); |
|
|
sss_node.sock = open_socket(sss_node.lport, 1 /*bind ANY*/); |
|
|
if ( -1 == sss.sock ) |
|
|
if(-1 == sss_node.sock) { |
|
|
{ |
|
|
|
|
|
traceEvent(TRACE_ERROR, "Failed to open main socket. %s", strerror(errno)); |
|
|
traceEvent(TRACE_ERROR, "Failed to open main socket. %s", strerror(errno)); |
|
|
exit(-2); |
|
|
exit(-2); |
|
|
} |
|
|
} else { |
|
|
else |
|
|
traceEvent(TRACE_NORMAL, "supernode is listening on UDP %u (main)", sss_node.lport); |
|
|
{ |
|
|
|
|
|
traceEvent( TRACE_NORMAL, "supernode is listening on UDP %u (main)", sss.lport ); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
sss.mgmt_sock = open_socket(N2N_SN_MGMT_PORT, 0 /* bind LOOPBACK */ ); |
|
|
sss_node.mgmt_sock = open_socket(N2N_SN_MGMT_PORT, 0 /* bind LOOPBACK */); |
|
|
if ( -1 == sss.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)", N2N_SN_MGMT_PORT); |
|
|
traceEvent(TRACE_NORMAL, "supernode is listening on UDP %u (management)", N2N_SN_MGMT_PORT); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
traceEvent(TRACE_NORMAL, "supernode started"); |
|
|
traceEvent(TRACE_NORMAL, "supernode started"); |
|
|
|
|
|
|
|
|
return run_loop(&sss); |
|
|
signal(SIGHUP, dump_registrations); |
|
|
|
|
|
|
|
|
|
|
|
return run_loop(&sss_node); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 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. */ |
|
|
static int run_loop( n2n_sn_t * sss ) |
|
|
static int run_loop(n2n_sn_t * sss) { |
|
|
{ |
|
|
|
|
|
uint8_t pktbuf[N2N_SN_PKTBUF_SIZE]; |
|
|
uint8_t pktbuf[N2N_SN_PKTBUF_SIZE]; |
|
|
int keep_running=1; |
|
|
int keep_running=1; |
|
|
|
|
|
|
|
|
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; |
|
@ -951,10 +951,8 @@ static int run_loop( n2n_sn_t * sss ) |
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
@ -962,8 +960,8 @@ static int run_loop( n2n_sn_t * sss ) |
|
|
bread = recvfrom(sss->sock, pktbuf, N2N_SN_PKTBUF_SIZE, 0/*flags*/, |
|
|
bread = recvfrom(sss->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 ) /* For UDP bread of zero just means no data (unlike TCP). */ |
|
|
if(bread < 0) { |
|
|
{ |
|
|
/* 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)); |
|
|
keep_running=0; |
|
|
keep_running=0; |
|
@ -971,15 +969,13 @@ static int run_loop( n2n_sn_t * sss ) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* 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; |
|
|
|
|
|
|
|
@ -987,8 +983,7 @@ static int run_loop( n2n_sn_t * sss ) |
|
|
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; |
|
@ -997,9 +992,7 @@ static int run_loop( n2n_sn_t * sss ) |
|
|
/* 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"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|