@ -403,7 +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 , sizeof ( struct peer_info ) ) ; /* deallocated in purge_expired_registration s */
scan = ( struct peer_info * ) calloc ( 1 , sizeof ( struct peer_info ) ) ; /* deallocated in purge_expired_node s */
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 ;
@ -658,67 +658,66 @@ static int re_register_and_purge_supernodes (n2n_sn_t *sss, struct sn_community
return 0 ;
return 0 ;
}
}
// purge long-time-not-seen supernodes
purge_expired_nodes ( & ( comm - > edges ) , p_last_re_reg_and_purge ,
RE_REG_AND_PURGE_FREQUENCY , LAST_SEEN_SN_INACTIVE ) ;
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 ) {
if ( time < = LAST_SEEN_SN_ACTIVE ) {
continue ;
continue ;
}
}
if ( ( time < LAST_SEEN_SN_INACTIVE )
/* re-register (send REGISTER_SUPER) */
| | ( peer - > purgeable = = SN_UNPURGEABLE ) ) {
uint8_t pktbuf [ N2N_PKT_BUF_SIZE ] = { 0 } ;
/* re-regitser (send REGISTER_SUPER) */
size_t idx ;
uint8_t pktbuf [ N2N_PKT_BUF_SIZE ] = { 0 } ;
/* ssize_t sent; */
size_t idx ;
n2n_common_t cmn ;
/* ssize_t sent; */
n2n_cookie_t cookie ;
n2n_common_t cmn ;
n2n_REGISTER_SUPER_t reg ;
n2n_cookie_t cookie ;
n2n_sock_str_t sockbuf ;
n2n_REGISTER_SUPER_t reg ;
n2n_sock_str_t sockbuf ;
memset ( & cmn , 0 , sizeof ( cmn ) ) ;
memset ( & reg , 0 , sizeof ( reg ) ) ;
memset ( & cmn , 0 , sizeof ( cmn ) ) ;
memset ( & reg , 0 , sizeof ( reg ) ) ;
cmn . ttl = N2N_DEFAULT_TTL ;
cmn . pc = n2n_register_super ;
cmn . ttl = N2N_DEFAULT_TTL ;
cmn . flags = N2N_FLAGS_FROM_SUPERNODE ;
cmn . pc = n2n_register_super ;
memcpy ( cmn . community , comm - > community , N2N_COMMUNITY_SIZE ) ;
cmn . flags = N2N_FLAGS_FROM_SUPERNODE ;
memcpy ( cmn . community , comm - > community , N2N_COMMUNITY_SIZE ) ;
for ( idx = 0 ; idx < N2N_COOKIE_SIZE ; + + idx ) {
cookie [ idx ] = n2n_rand ( ) % 0xff ;
for ( idx = 0 ; idx < N2N_COOKIE_SIZE ; + + idx ) {
}
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 ) ;
reg . dev_addr . net_bitlen = mask2bitlen ( ntohl ( peer - > dev_addr . net_bitlen ) ) ;
reg . dev_addr . net_bitlen = mask2bitlen ( ntohl ( peer - > dev_addr . net_bitlen ) ) ;
memcpy ( & ( reg . auth ) , & ( sss - > auth ) , sizeof ( n2n_auth_t ) ) ;
memcpy ( & ( reg . auth ) , & ( sss - > auth ) , sizeof ( n2n_auth_t ) ) ;
idx = 0 ;
idx = 0 ;
encode_mac ( reg . edgeMac , & idx , sss - > mac_addr ) ;
encode_mac ( reg . edgeMac , & idx , sss - > mac_addr ) ;
idx = 0 ;
idx = 0 ;
encode_REGISTER_SUPER ( pktbuf , & idx , & cmn , & reg ) ;
encode_REGISTER_SUPER ( pktbuf , & idx , & cmn , & reg ) ;
traceEvent ( TRACE_DEBUG , " send REGISTER_SUPER to %s " ,
traceEvent ( TRACE_DEBUG , " send REGISTER_SUPER to %s " ,
sock_to_cstr ( sockbuf , & ( peer - > sock ) ) ) ;
sock_to_cstr ( sockbuf , & ( peer - > sock ) ) ) ;
packet_header_encrypt ( pktbuf , idx , idx ,
packet_header_encrypt ( pktbuf , idx , idx ,
comm - > header_encryption_ctx , comm - > header_iv_ctx ,
comm - > header_encryption_ctx , comm - > header_iv_ctx ,
time_stamp ( ) ) ;
time_stamp ( ) ) ;
/* 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*/
}
}
}
}
}
( * p_last_re_reg_and_purge ) = now ;
return 0 ; /* OK */
return 0 ; /* OK */
}
}
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 ) {
@ -733,6 +732,10 @@ static int purge_expired_communities (n2n_sn_t *sss,
traceEvent ( TRACE_DEBUG , " Purging old communities and edges " ) ;
traceEvent ( TRACE_DEBUG , " Purging old communities and edges " ) ;
HASH_ITER ( hh , sss - > communities , comm , tmp ) {
HASH_ITER ( hh , sss - > communities , comm , tmp ) {
// federation is taken care of in re_register_and_purge_supernodes()
if ( comm - > is_federation = = IS_FEDERATION )
continue ;
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 ) ;
@ -1306,8 +1309,6 @@ static int process_udp (n2n_sn_t * sss,
p = add_sn_to_list_by_mac_or_sock ( & ( sss - > federation - > edges ) , & ( ack . sock ) , reg . edgeMac , & skip_add ) ;
p = add_sn_to_list_by_mac_or_sock ( & ( sss - > federation - > edges ) , & ( ack . sock ) , reg . edgeMac , & skip_add ) ;
}
}
// REVISIT: consider adding last_seen
/* Skip random numbers of supernodes before payload assembling, calculating an appropriate random_number.
/* Skip random numbers of supernodes before payload assembling, calculating an appropriate random_number.
* That way , all supernodes have a chance to be propagated with REGISTER_SUPER_ACK . */
* That way , all supernodes have a chance to be propagated with REGISTER_SUPER_ACK . */
skip = HASH_COUNT ( sss - > federation - > edges ) - ( int ) ( REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE / REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE ) ;
skip = HASH_COUNT ( sss - > federation - > edges ) - ( int ) ( REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE / REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE ) ;
@ -1321,9 +1322,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 ) > = LAST_SEEN_SN_NEW ) 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 ) ) ;