mirror of
https://github.com/ntop/n2n.git
synced 2024-09-19 16:41:11 +02:00
Initialize the federation of supernodes (#460)
* Add supernode2sock() and add_sn_to_federation_by_mac_or_sock() * Update sn_utils.c * Update sn.c and sn_utils.c * Update REG_SUPER_ACK payload * Update add_sn_to_federation_by_mac_or_sock()
This commit is contained in:
parent
e3f64bfd1e
commit
c9eedd68f0
|
@ -190,24 +190,26 @@ typedef char macstr_t[N2N_MACSTR_SIZE];
|
|||
typedef char dec_ip_str_t[N2N_NETMASK_STR_SIZE];
|
||||
typedef char dec_ip_bit_str_t[N2N_NETMASK_STR_SIZE + 4];
|
||||
|
||||
typedef struct speck_context_t he_context_t;
|
||||
typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE];
|
||||
|
||||
|
||||
struct peer_info {
|
||||
n2n_mac_t mac_addr;
|
||||
n2n_ip_subnet_t dev_addr;
|
||||
n2n_sock_t sock;
|
||||
int timeout;
|
||||
uint8_t purgeable;
|
||||
time_t last_seen;
|
||||
time_t last_p2p;
|
||||
time_t last_sent_query;
|
||||
uint64_t last_valid_time_stamp;
|
||||
char *ip_addr;
|
||||
|
||||
UT_hash_handle hh; /* makes this structure hashable */
|
||||
};
|
||||
|
||||
|
||||
typedef struct speck_context_t he_context_t;
|
||||
typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE];
|
||||
|
||||
typedef struct n2n_route {
|
||||
in_addr_t net_addr;
|
||||
uint8_t net_bitlen;
|
||||
|
@ -396,7 +398,7 @@ typedef struct n2n_sn
|
|||
int lock_communities; /* If true, only loaded and matching communities can be used. */
|
||||
struct sn_community *communities;
|
||||
struct sn_community_regular_expression *rules;
|
||||
char federation[N2N_COMMUNITY_SIZE];
|
||||
struct sn_community *federation;
|
||||
} n2n_sn_t;
|
||||
|
||||
/* ************************************** */
|
||||
|
@ -443,6 +445,7 @@ uint32_t bitlen2mask(uint8_t bitlen);
|
|||
uint8_t mask2bitlen(uint32_t mask);
|
||||
char* macaddr_str(macstr_t buf, const n2n_mac_t mac);
|
||||
int str2mac( uint8_t * outmac /* 6 bytes */, const char * s );
|
||||
int supernode2sock(n2n_sock_t * sn, const n2n_sn_name_t addrIn);
|
||||
uint8_t is_multi_broadcast(const uint8_t * dest_mac);
|
||||
char* msg_type2str(uint16_t msg_type);
|
||||
void hexdump(const uint8_t * buf, size_t len);
|
||||
|
@ -497,6 +500,7 @@ int quick_edge_init(char *device_name, char *community_name,
|
|||
int comm_init(struct sn_community *comm, char *cmn);
|
||||
int sn_init(n2n_sn_t *sss);
|
||||
void sn_term(n2n_sn_t *sss);
|
||||
struct peer_info* add_sn_to_federation_by_mac_or_sock(n2n_sn_t *sss, n2n_sock_t *sock, n2n_mac_t *mac);
|
||||
int run_sn_loop(n2n_sn_t *sss, int *keep_running);
|
||||
int assign_one_ip_subnet(n2n_sn_t *sss, struct sn_community *comm);
|
||||
const char* compression_str(uint8_t cmpr);
|
||||
|
|
|
@ -169,8 +169,6 @@ typedef struct n2n_REGISTER_SUPER_ACK {
|
|||
uint8_t num_sn; /**< Number of supernodes that were send
|
||||
* even if we cannot store them all. If
|
||||
* non-zero then sn_bak is valid. */
|
||||
n2n_sock_t sn_bak; /**< Socket of the first backup supernode */
|
||||
n2n_mac_t mac_addr;
|
||||
} n2n_REGISTER_SUPER_ACK_t;
|
||||
|
||||
|
||||
|
|
82
src/sn.c
82
src/sn.c
|
@ -24,6 +24,7 @@
|
|||
#define HASH_FIND_COMMUNITY(head, name, out) HASH_FIND_STR(head, name, out)
|
||||
|
||||
static n2n_sn_t sss_node;
|
||||
static const n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0};
|
||||
|
||||
/** Load the list of allowed communities. Existing/previous ones will be removed
|
||||
*
|
||||
|
@ -176,8 +177,9 @@ static void help() {
|
|||
"or\n"
|
||||
);
|
||||
printf("supernode ");
|
||||
printf("-l <local port> ");
|
||||
printf("-p <local port> ");
|
||||
printf("-c <path> ");
|
||||
printf("-l <supernode:port> ");
|
||||
#if defined(N2N_HAVE_DAEMON)
|
||||
printf("[-f] ");
|
||||
#endif
|
||||
|
@ -191,8 +193,9 @@ static void help() {
|
|||
printf("[-v] ");
|
||||
printf("\n\n");
|
||||
|
||||
printf("-l <port> | Set UDP main listen port to <port>\n");
|
||||
printf("-p <port> | Set UDP main listen port to <port>\n");
|
||||
printf("-c <path> | File containing the allowed communities.\n");
|
||||
printf("-l <sn:port> | Supernode IP:port.\n");
|
||||
#if defined(N2N_HAVE_DAEMON)
|
||||
printf("-f | Run in foreground.\n");
|
||||
#endif /* #if defined(N2N_HAVE_DAEMON) */
|
||||
|
@ -219,7 +222,7 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
|||
//traceEvent(TRACE_NORMAL, "Option %c = %s", optkey, _optarg ? _optarg : "");
|
||||
|
||||
switch (optkey) {
|
||||
case 'l': /* local-port */
|
||||
case 'p': /* local-port */
|
||||
sss->lport = atoi(_optarg);
|
||||
break;
|
||||
|
||||
|
@ -227,6 +230,45 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
|||
sss->mport = atoi(_optarg);
|
||||
break;
|
||||
|
||||
case 'l': { /* supernode:port */
|
||||
n2n_sock_t *socket;
|
||||
struct peer_info *anchor_sn;
|
||||
size_t length;
|
||||
int rv;
|
||||
|
||||
length = strlen(_optarg);
|
||||
if(length >= N2N_EDGE_SN_HOST_SIZE) {
|
||||
traceEvent(TRACE_WARNING, "Size of -l argument too long: %zu. Maximum size is %d",length,N2N_EDGE_SN_HOST_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
if(sss->federation != NULL) {
|
||||
socket = (n2n_sock_t *)calloc(1,sizeof(n2n_sock_t));
|
||||
|
||||
anchor_sn = add_sn_to_federation_by_mac_or_sock(sss,socket, (n2n_mac_t*) null_mac);
|
||||
|
||||
if(anchor_sn != NULL){
|
||||
anchor_sn->ip_addr = calloc(1,N2N_EDGE_SN_HOST_SIZE);
|
||||
if(anchor_sn->ip_addr){
|
||||
strncpy(anchor_sn->ip_addr,_optarg,N2N_EDGE_SN_HOST_SIZE-1);
|
||||
rv = supernode2sock(socket,_optarg);
|
||||
|
||||
if(rv != 0){
|
||||
traceEvent(TRACE_WARNING, "Invalid socket");
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(&(anchor_sn->sock), socket, sizeof(n2n_sock_t));
|
||||
memcpy(&(anchor_sn->mac_addr),null_mac,sizeof(n2n_mac_t));
|
||||
anchor_sn->purgeable = SN_UNPURGEABLE;
|
||||
anchor_sn->last_valid_time_stamp = initial_time_stamp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'a': {
|
||||
dec_ip_str_t ip_min_str = {'\0'};
|
||||
dec_ip_str_t ip_max_str = {'\0'};
|
||||
|
@ -280,15 +322,12 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
|||
#endif
|
||||
|
||||
case 'F': { /* federation name */
|
||||
struct sn_community *fed;
|
||||
|
||||
HASH_FIND_COMMUNITY(sss->communities, FEDERATION_NAME, fed);
|
||||
|
||||
if(fed != NULL){
|
||||
snprintf(fed->community,N2N_COMMUNITY_SIZE-1,"*%s",_optarg);
|
||||
strncpy(sss->federation, fed->community, N2N_COMMUNITY_SIZE-1);
|
||||
sss->federation[N2N_COMMUNITY_SIZE-1] = '\0';
|
||||
if(sss->federation->community != NULL){
|
||||
snprintf(sss->federation->community,N2N_COMMUNITY_SIZE-1,"*%s",_optarg);
|
||||
sss->federation->community[N2N_COMMUNITY_SIZE-1] = '\0';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -327,7 +366,7 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
|||
static const struct option long_options[] = {
|
||||
{"communities", required_argument, NULL, 'c'},
|
||||
{"foreground", no_argument, NULL, 'f'},
|
||||
{"local-port", required_argument, NULL, 'l'},
|
||||
{"local-port", required_argument, NULL, 'p'},
|
||||
{"mgmt-port", required_argument, NULL, 't'},
|
||||
{"autoip", required_argument, NULL, 'a'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
|
@ -341,7 +380,7 @@ static const struct option long_options[] = {
|
|||
static int loadFromCLI(int argc, char * const argv[], n2n_sn_t *sss) {
|
||||
u_char c;
|
||||
|
||||
while((c = getopt_long(argc, argv, "fl: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)) != '?') {
|
||||
if(c == 255) break;
|
||||
setOption(c, optarg, sss);
|
||||
|
@ -437,26 +476,15 @@ static int loadFromFile(const char *path, n2n_sn_t *sss) {
|
|||
|
||||
/* Add the federation to the communities list of a supernode */
|
||||
static int add_federation_to_communities(n2n_sn_t *sss){
|
||||
struct sn_community *fed;
|
||||
uint32_t num_communities = 0;
|
||||
|
||||
fed = (struct sn_community *)calloc(1,sizeof(struct sn_community));
|
||||
comm_init(fed,sss->federation);
|
||||
|
||||
if(fed != NULL) {
|
||||
/* enable the flag for federation */
|
||||
fed->is_federation = IS_FEDERATION;
|
||||
fed->purgeable = COMMUNITY_UNPURGEABLE;
|
||||
/* header encryption enabled by default */
|
||||
fed->header_encryption = HEADER_ENCRYPTION_ENABLED;
|
||||
/*setup the encryption key */
|
||||
packet_header_setup_key(fed->community, &(fed->header_encryption_ctx), &(fed->header_iv_ctx));
|
||||
HASH_ADD_STR(sss->communities, community, fed);
|
||||
if(sss->federation != NULL) {
|
||||
HASH_ADD_STR(sss->communities, community, sss->federation);
|
||||
|
||||
num_communities = HASH_COUNT(sss->communities);
|
||||
|
||||
traceEvent(TRACE_INFO, "Added federation '%s' to the list of communities [total: %u]",
|
||||
(char*)fed->community, num_communities);
|
||||
(char*)sss->federation->community, num_communities);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -615,5 +643,3 @@ int main(int argc, char * const argv[]) {
|
|||
keep_running = 1;
|
||||
return run_sn_loop(&sss_node, &keep_running);
|
||||
}
|
||||
|
||||
|
||||
|
|
147
src/sn_utils.c
147
src/sn_utils.c
|
@ -52,10 +52,6 @@ static int update_edge(n2n_sn_t *sss,
|
|||
const n2n_sock_t *sender_sock,
|
||||
time_t now);
|
||||
|
||||
static int re_register_and_purge_supernodes(n2n_sn_t *sss,
|
||||
struct sn_community *comm,
|
||||
time_t now);
|
||||
|
||||
static int purge_expired_communities(n2n_sn_t *sss,
|
||||
time_t* p_last_purge,
|
||||
time_t now);
|
||||
|
@ -70,16 +66,14 @@ static int process_mgmt(n2n_sn_t *sss,
|
|||
size_t mgmt_size,
|
||||
time_t now);
|
||||
|
||||
static int add_sn_to_federation_from_register_super_ack(n2n_sn_t *sss,
|
||||
n2n_REGISTER_SUPER_ACK_t ack,
|
||||
time_t now);
|
||||
|
||||
static int process_udp(n2n_sn_t *sss,
|
||||
const struct sockaddr_in *sender_sock,
|
||||
uint8_t *udp_buf,
|
||||
size_t udp_size,
|
||||
time_t now);
|
||||
|
||||
static const n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0};
|
||||
|
||||
/* ************************************** */
|
||||
|
||||
static int try_forward(n2n_sn_t * sss,
|
||||
|
@ -244,8 +238,20 @@ int sn_init(n2n_sn_t *sss) {
|
|||
sss->max_auto_ip_net.net_addr = inet_addr(N2N_SN_MAX_AUTO_IP_NET_DEFAULT);
|
||||
sss->max_auto_ip_net.net_addr = ntohl(sss->max_auto_ip_net.net_addr);
|
||||
sss->max_auto_ip_net.net_bitlen = N2N_SN_AUTO_IP_NET_BIT_DEFAULT;
|
||||
strncpy(sss->federation, (char*)FEDERATION_NAME, N2N_COMMUNITY_SIZE-1);
|
||||
sss->federation[N2N_COMMUNITY_SIZE-1] = '\0';
|
||||
sss->federation = (struct sn_community *)calloc(1,sizeof(struct sn_community));
|
||||
|
||||
/* Initialize the federation */
|
||||
if(sss->federation){
|
||||
strncpy(sss->federation->community, (char*)FEDERATION_NAME, N2N_COMMUNITY_SIZE-1);
|
||||
sss->federation->community[N2N_COMMUNITY_SIZE-1] = '\0';
|
||||
/* enable the flag for federation */
|
||||
sss->federation->is_federation = IS_FEDERATION;
|
||||
sss->federation->purgeable = COMMUNITY_UNPURGEABLE;
|
||||
/* header encryption enabled by default */
|
||||
sss->federation->header_encryption = HEADER_ENCRYPTION_ENABLED;
|
||||
/*setup the encryption key */
|
||||
packet_header_setup_key(sss->federation->community, &(sss->federation->header_encryption_ctx), &(sss->federation->header_iv_ctx));
|
||||
}
|
||||
|
||||
n2n_srand (n2n_seed());
|
||||
|
||||
|
@ -513,7 +519,7 @@ static int re_register_and_purge_supernodes(n2n_sn_t *sss, struct sn_community *
|
|||
HASH_ITER(hh,comm->edges,peer,tmp){
|
||||
time = now - peer->last_seen;
|
||||
if(time <= ALLOWED_TIME) continue;
|
||||
if((time > ALLOWED_TIME) && (time < PURGE_FEDERATION_NODE_INTERVAL)){ /* re-regitser (send REGISTER_SUPER) */
|
||||
if((time < PURGE_FEDERATION_NODE_INTERVAL) || (peer->purgeable == SN_UNPURGEABLE)){ /* re-regitser (send REGISTER_SUPER) */
|
||||
uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0};
|
||||
size_t idx;
|
||||
/* ssize_t sent; */
|
||||
|
@ -724,43 +730,45 @@ static int sendto_mgmt(n2n_sn_t *sss,
|
|||
}
|
||||
|
||||
|
||||
/** Iterate through REGISTER_SUPER_ACK payload and add new supernodes with a legal timestamp
|
||||
* (half of the difference between the adjustable 20 seconds and 90 seconds limit) to the federation list
|
||||
/** Search for a node in the federation list. If it has to add a new node, it creates a new peer_info and initializes it
|
||||
* Evaluate first the MAC parameter and if it's zero-MAC, then it can skip HASH_FIND_PEER by MAC and search by socket
|
||||
*/
|
||||
static int add_sn_to_federation_from_register_super_ack(n2n_sn_t *sss, n2n_REGISTER_SUPER_ACK_t ack, time_t now){
|
||||
struct sn_community *fed;
|
||||
struct peer_info *peer;
|
||||
n2n_sock_t *tmp_sock;
|
||||
n2n_mac_t *tmp_mac;
|
||||
int i;
|
||||
struct peer_info* add_sn_to_federation_by_mac_or_sock(n2n_sn_t *sss,n2n_sock_t *sock, n2n_mac_t *mac){
|
||||
struct peer_info *scan, *tmp, *peer;
|
||||
int found = 0;
|
||||
|
||||
HASH_FIND_COMMUNITY(sss->communities, sss->federation, fed);
|
||||
if(sss->federation != NULL){
|
||||
if(memcmp(mac,null_mac,sizeof(n2n_mac_t)) != 0){ /* not zero MAC */
|
||||
HASH_FIND_PEER(sss->federation->edges, mac, peer);
|
||||
|
||||
//REVISIT: make this dependent from last_seen and update socket
|
||||
}
|
||||
|
||||
if(peer == NULL){ /* zero MAC, search by socket */
|
||||
HASH_ITER(hh,sss->federation->edges,scan,tmp){
|
||||
if(memcmp(&(scan->sock), sock, sizeof(n2n_sock_t))){
|
||||
memcpy(&(scan->mac_addr), sock, sizeof(n2n_mac_t));
|
||||
peer = scan;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(fed != NULL){
|
||||
tmp_sock = &(ack.sn_bak);
|
||||
tmp_mac = &(ack.mac_addr);
|
||||
for(i=0; i<ack.num_sn; i++){
|
||||
HASH_FIND_PEER(fed->edges, &tmp_mac, peer);
|
||||
if(peer == NULL){
|
||||
peer = (struct peer_info*)calloc(1,sizeof(struct peer_info));
|
||||
memcpy(&(peer->sock),tmp_sock,sizeof(n2n_sock_t));
|
||||
memcpy(&(peer->mac_addr), &tmp_mac, sizeof(n2n_mac_t));
|
||||
peer->dev_addr.net_addr = ntohs(ack.dev_addr.net_addr);
|
||||
peer->dev_addr.net_bitlen = mask2bitlen(ntohl(ack.dev_addr.net_bitlen));
|
||||
peer->last_seen = now - TEST_TIME;
|
||||
HASH_ADD_PEER(fed->edges, peer);
|
||||
if(peer){
|
||||
memcpy(&(peer->sock),sock,sizeof(n2n_sock_t));
|
||||
memcpy(&(peer->mac_addr),mac, sizeof(n2n_mac_t));
|
||||
HASH_ADD_PEER(sss->federation->edges,peer);
|
||||
}
|
||||
}
|
||||
tmp_sock += sizeof(n2n_mac_t);
|
||||
tmp_mac += sizeof(n2n_sock_t);
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* OK */
|
||||
return peer;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Examine a datagram and determine what to do with it.
|
||||
*
|
||||
*/
|
||||
|
@ -1044,6 +1052,7 @@ static int process_udp(n2n_sn_t * sss,
|
|||
n2n_REGISTER_SUPER_ACK_t ack;
|
||||
n2n_common_t cmn2;
|
||||
uint8_t ackbuf[N2N_SN_PKTBUF_SIZE];
|
||||
uint8_t tmpbuf[MAX_AVAILABLE_SPACE_FOR_ENTRIES];
|
||||
size_t encx=0;
|
||||
struct sn_community *fed;
|
||||
struct sn_community_regular_expression *re, *tmp_re;
|
||||
|
@ -1122,7 +1131,6 @@ static int process_udp(n2n_sn_t * sss,
|
|||
}
|
||||
|
||||
if(comm) {
|
||||
HASH_FIND_COMMUNITY(sss->communities, sss->federation, fed);
|
||||
cmn2.ttl = N2N_DEFAULT_TTL;
|
||||
cmn2.pc = n2n_register_super_ack;
|
||||
cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE;
|
||||
|
@ -1143,24 +1151,28 @@ static int process_udp(n2n_sn_t * sss,
|
|||
ack.sock.port = ntohs(sender_sock->sin_port);
|
||||
memcpy(ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE);
|
||||
|
||||
if(fed != NULL){
|
||||
HASH_FIND_PEER(fed->edges, reg.edgeMac, p);
|
||||
if(p != NULL){
|
||||
p->last_seen = now;
|
||||
tmp_sock = &(ack.sn_bak);
|
||||
tmp_mac = &(ack.mac_addr);
|
||||
/* Add sender's data to federation (or update it) */
|
||||
if(comm->is_federation == IS_FEDERATION){
|
||||
p = add_sn_to_federation_by_mac_or_sock(sss,&(ack.sock),&(reg.edgeMac));
|
||||
if(p) p->last_seen = now;
|
||||
}
|
||||
|
||||
HASH_ITER(hh, fed->edges, peer, tmp_peer) {
|
||||
tmp_sock = (void*)tmpbuf;
|
||||
tmp_mac = (void*)tmpbuf + sizeof(n2n_sock_t);
|
||||
|
||||
// REVISIT: consider adding last_seen
|
||||
|
||||
/* Assembling supernode list for REGISTER_SUPER_ACK payload */
|
||||
HASH_ITER(hh, sss->federation->edges, peer, tmp_peer) {
|
||||
if((now - peer->last_seen) >= ALLOWED_TIME) continue; /* skip long-time-not-seen supernodes */
|
||||
if(((++num)*ENTRY_SIZE) > MAX_AVAILABLE_SPACE_FOR_ENTRIES) break; /* no more space available in REGISTER_SUPER_ACK payload */
|
||||
memcpy(tmp_sock, &(peer->sock), sizeof(n2n_sock_t));
|
||||
memcpy(tmp_mac, &(peer->mac_addr), sizeof(n2n_mac_t));
|
||||
tmp_sock += sizeof(n2n_mac_t);
|
||||
tmp_mac += sizeof(n2n_sock_t);
|
||||
memcpy((void*)tmpbuf, (void*)&(peer->sock), sizeof(n2n_sock_t));
|
||||
memcpy((void*)tmpbuf, (void*)&(peer->mac_addr), sizeof(n2n_mac_t));
|
||||
tmp_sock += ENTRY_SIZE;
|
||||
tmp_mac += ENTRY_SIZE;
|
||||
}
|
||||
ack.num_sn = num;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]",
|
||||
macaddr_str(mac_buf, reg.edgeMac),
|
||||
|
@ -1171,6 +1183,7 @@ static int process_udp(n2n_sn_t * sss,
|
|||
}
|
||||
|
||||
encode_REGISTER_SUPER_ACK(ackbuf, &encx, &cmn2, &ack);
|
||||
encode_buf(ackbuf,&encx,tmpbuf,(num*ENTRY_SIZE));
|
||||
|
||||
if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED)
|
||||
packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx,
|
||||
|
@ -1194,12 +1207,15 @@ static int process_udp(n2n_sn_t * sss,
|
|||
n2n_REGISTER_SUPER_ACK_t ack;
|
||||
size_t encx=0;
|
||||
struct sn_community *fed;
|
||||
struct peer_info *scan;
|
||||
struct peer_info *scan, *tmp;
|
||||
n2n_sock_str_t sockbuf1;
|
||||
n2n_sock_str_t sockbuf2;
|
||||
macstr_t mac_buf1;
|
||||
n2n_sock_t sender;
|
||||
n2n_sock_t *orig_sender;
|
||||
n2n_sock_t *tmp_sock;
|
||||
n2n_mac_t *tmp_mac;
|
||||
int i;
|
||||
|
||||
sender.family = AF_INET;
|
||||
sender.port = ntohs(sender_sock->sin_port);
|
||||
|
@ -1208,6 +1224,11 @@ static int process_udp(n2n_sn_t * sss,
|
|||
|
||||
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
||||
|
||||
if(!comm) {
|
||||
traceEvent(TRACE_DEBUG, "process_udp REGISTER_SUPER_ACK with unknown community %s", cmn.community);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(from_supernode != comm->is_federation){
|
||||
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK: from_supernode value doesn't correspond to the internal federation marking.");
|
||||
return -1;
|
||||
|
@ -1226,20 +1247,33 @@ static int process_udp(n2n_sn_t * sss,
|
|||
}
|
||||
|
||||
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK myMAC=%s [%s] (external %s)",
|
||||
macaddr_str(mac_buf1, ack.mac_addr),
|
||||
macaddr_str(mac_buf1, ack.edgeMac),
|
||||
sock_to_cstr(sockbuf1, &sender),
|
||||
sock_to_cstr(sockbuf2, orig_sender));
|
||||
|
||||
HASH_FIND_COMMUNITY(sss->communities, sss->federation, fed);
|
||||
|
||||
if(fed != NULL) {
|
||||
HASH_FIND_PEER(fed->edges, ack.edgeMac, scan);
|
||||
if(comm->is_federation == IS_FEDERATION) {
|
||||
HASH_FIND_PEER(sss->federation->edges, ack.edgeMac, scan);
|
||||
if(scan != NULL){
|
||||
scan->last_seen = now;
|
||||
} else {
|
||||
traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_ACK due to an unknown supernode.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(ack.num_sn > 0) add_sn_to_federation_from_register_super_ack(sss,ack,now);
|
||||
tmp_sock = (void*)&(ack.num_sn) + sizeof(ack.num_sn);
|
||||
tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t);
|
||||
|
||||
for(i=0; i<ack.num_sn; i++){
|
||||
tmp = add_sn_to_federation_by_mac_or_sock(sss,tmp_sock,tmp_mac);
|
||||
|
||||
if(tmp){
|
||||
tmp->last_seen = now - TEST_TIME;
|
||||
}
|
||||
|
||||
tmp_sock += ENTRY_SIZE;
|
||||
tmp_mac += ENTRY_SIZE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1400,6 +1434,7 @@ int run_sn_loop(n2n_sn_t *sss, int *keep_running)
|
|||
traceEvent(TRACE_DEBUG, "timeout");
|
||||
}
|
||||
|
||||
re_register_and_purge_supernodes(sss, sss->federation, now);
|
||||
purge_expired_communities(sss, &last_purge_edges, now);
|
||||
sort_communities (sss, &last_sort_communities, now);
|
||||
} /* while */
|
||||
|
|
Loading…
Reference in New Issue
Block a user