limited number of concurrently pinged supernodes (#619)

This commit is contained in:
Logan oos Even 2021-02-01 18:31:36 +05:45 committed by GitHub
parent b7c69f8f61
commit 09e8d5e730
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 4 deletions

View File

@ -48,6 +48,9 @@
#define SWEEP_TIME 30 /* sec, indicates the value after which we have to sort the hash list of supernodes in edges
* and when we send out packets to query selection-relevant informations from supernodes. */
#define NUMBER_SN_PINGS_INITIAL 15 /* number of supernodes to concurrently ping during bootstrap and immediately afterwards */
#define NUMBER_SN_PINGS_REGULAR 5 /* number of supernodes to concurrently ping during regular edge operation */
/* Timeouts used in re_register_and_purge_supernodes. LAST_SEEN_SN_ACTIVE and LAST_SEEN_SN_INACTIVE
* values should be at least 3*SOCKET_TIMEOUT_INTERVAL_SECS apart. */
#define LAST_SEEN_SN_ACTIVE 20 /* sec, indicates supernodes that are proven to be active */

View File

@ -601,6 +601,7 @@ typedef struct n2n_edge_conf {
n2n_auth_t auth;
filter_rule_t *network_traffic_filter_rules;
int metric; /**< Network interface metric (Windows only). */
uint8_t number_max_sn_pings; /**< Number of maximum concurrently allowed supernode pings. */
} n2n_edge_conf_t;

View File

@ -962,6 +962,8 @@ int main (int argc, char* argv[]) {
if(runlevel == 0) { /* PING to all known supernodes */
last_action = now_time;
eee->sn_pong = 0;
// (re-)initialize the number of max concurrent pings (decreases by calling send_query_peer)
eee->conf.number_max_sn_pings = NUMBER_SN_PINGS_INITIAL;
send_query_peer(eee, null_mac);
traceEvent(TRACE_NORMAL, "Send PING to supernodes.");
runlevel++;
@ -975,8 +977,7 @@ int main (int argc, char* argv[]) {
eee->curr_sn = eee->conf.supernodes;
traceEvent(TRACE_NORMAL, "Received first PONG from supernode [%s].", eee->curr_sn->ip_addr);
runlevel++;
}
if(last_action <= (now_time - BOOTSTRAP_TIMEOUT)) {
} else if(last_action <= (now_time - BOOTSTRAP_TIMEOUT)) {
// timeout
runlevel--;
// skip waiting for answer to direcly go to send PING again
@ -1017,8 +1018,7 @@ int main (int argc, char* argv[]) {
runlevel++;
traceEvent(TRACE_NORMAL, "Received REGISTER_SUPER_ACK from supernode for IP address asignment.");
// it should be from curr_sn, but we can't determine definitely here, so no details to output
}
if(last_action <= (now_time - BOOTSTRAP_TIMEOUT)) {
} else if(last_action <= (now_time - BOOTSTRAP_TIMEOUT)) {
// timeout, so try next supernode
if(eee->curr_sn->hh.next)
eee->curr_sn = eee->curr_sn->hh.next;
@ -1065,6 +1065,11 @@ int main (int argc, char* argv[]) {
}
seek_answer = 1;
}
// allow a higher number of pings for first regular round of ping
// to quicker get an inital 'supernode selection criterion overview'
eee->conf.number_max_sn_pings = NUMBER_SN_PINGS_INITIAL;
// do not immediately ping again, allow some time
eee->last_sweep = now_time - SWEEP_TIME + 2 * BOOTSTRAP_TIMEOUT;
eee->sn_wait = 1;
eee->last_register_req = 0;
eee->last_sup = 0; /* to allow gratuitous arp packet after regular REGISTER_SUPER_ACK */

View File

@ -770,6 +770,10 @@ void send_query_peer (n2n_edge_t * eee,
n2n_QUERY_PEER_t query = {{0}};
struct peer_info *peer, *tmp;
uint8_t tmp_pkt[N2N_PKT_BUF_SIZE];
int n_o_pings = 0;
int n_o_top_sn = 0;
int n_o_rest_sn = 0;
int n_o_skip_sn = 0;
cmn.ttl = N2N_DEFAULT_TTL;
cmn.pc = n2n_query_peer;
@ -806,7 +810,32 @@ void send_query_peer (n2n_edge_t * eee,
time_stamp ());
}
n_o_pings = eee->conf.number_max_sn_pings;
eee->conf.number_max_sn_pings = NUMBER_SN_PINGS_REGULAR;
// ping the 'floor(n/2)' top supernodes and 'ceiling(n/2)' of the remaining
n_o_top_sn = n_o_pings >> 1;
n_o_rest_sn = (n_o_pings + 1) >> 1;
// skip a random number of supernodes between top and remaining
n_o_skip_sn = HASH_COUNT(eee->conf.supernodes) - n_o_pings;
n_o_skip_sn = (n_o_skip_sn < 0) ? 0 : n2n_rand_sqr(n_o_skip_sn);
HASH_ITER(hh, eee->conf.supernodes, peer, tmp) {
if(n_o_top_sn) {
n_o_top_sn--;
// fall through (send to top supernode)
} else if(n_o_skip_sn) {
n_o_skip_sn--;
// skip (do not send)
continue;
} else if(n_o_rest_sn) {
n_o_rest_sn--;
// fall through (send to remaining supernode)
} else {
// done with the remaining (do not send anymore)
break;
}
sendto_sock(eee->udp_sock, pktbuf, idx, &(peer->sock));
}
}