diff --git a/include/sn_selection.h b/include/sn_selection.h index 333e969..82ff869 100644 --- a/include/sn_selection.h +++ b/include/sn_selection.h @@ -27,6 +27,7 @@ typedef char selection_criterion_str_t[SN_SELECTION_CRITERION_BUF_SIZE]; int sn_selection_criterion_init (peer_info_t *peer); int sn_selection_criterion_default (SN_SELECTION_CRITERION_DATA_TYPE *selection_criterion); int sn_selection_criterion_bad (SN_SELECTION_CRITERION_DATA_TYPE *selection_criterion); +int sn_selection_criterion_good (SN_SELECTION_CRITERION_DATA_TYPE *selection_criterion); int sn_selection_criterion_calculate (n2n_edge_t *eee, peer_info_t *peer, SN_SELECTION_CRITERION_DATA_TYPE *data); /* common data's functions */ diff --git a/src/edge.c b/src/edge.c index 68cb9f1..141161a 100644 --- a/src/edge.c +++ b/src/edge.c @@ -50,6 +50,7 @@ int supernode_disconnect (n2n_edge_t *eee); int fetch_and_eventually_process_data (n2n_edge_t *eee, SOCKET sock, uint8_t *pktbuf, uint16_t *expected, uint16_t *position, time_t now); + /* ***************************************************** */ /** Find the address and IP mode for the tuntap device. @@ -852,6 +853,7 @@ int main (int argc, char* argv[]) { macstr_t mac_buf; /* output mac address */ fd_set socket_mask; /* for supernode answer */ struct timeval wait_time; /* timeout for sn answer */ + peer_info_t *scan, *scan_tmp; /* supernode iteration */ uint16_t expected = sizeof(uint16_t); uint16_t position = 0; @@ -1095,6 +1097,14 @@ int main (int argc, char* argv[]) { // 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; + // shape supernode list; make current one the first on the list + HASH_ITER(hh, eee->conf.supernodes, scan, scan_tmp) { + if(scan == eee->curr_sn) + sn_selection_criterion_good(&(scan->selection_criterion)); + else + sn_selection_criterion_default(&(scan->selection_criterion)); + } + sn_selection_sort(&(eee->conf.supernodes)); // do not immediately ping again, allow some time eee->last_sweep = now - SWEEP_TIME + 2 * BOOTSTRAP_TIMEOUT; eee->sn_wait = 1; diff --git a/src/edge_utils.c b/src/edge_utils.c index d025334..0ed98fc 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -502,6 +502,7 @@ static void register_with_local_peers (n2n_edge_t * eee) { } /* ************************************** */ + static struct peer_info* find_peer_by_sock (const n2n_sock_t *sock, struct peer_info *peer_list) { struct peer_info *scan, *tmp, *ret = NULL; @@ -1146,7 +1147,10 @@ static int sort_supernodes (n2n_edge_t *eee, time_t now) { } HASH_ITER(hh, eee->conf.supernodes, scan, tmp) { - sn_selection_criterion_default(&(scan->selection_criterion)); + if(scan == eee->curr_sn) + sn_selection_criterion_good(&(scan->selection_criterion)); + else + sn_selection_criterion_default(&(scan->selection_criterion)); } sn_selection_criterion_common_data_default(eee); @@ -2383,9 +2387,11 @@ void process_udp (n2n_edge_t *eee, const struct sockaddr_in *sender_sock, const handle_remote_auth(eee, sn, &(ra.auth)); - HASH_DEL(eee->conf.supernodes, eee->curr_sn); - memcpy(&eee->curr_sn->mac_addr, ra.srcMac, N2N_MAC_SIZE); - HASH_ADD_PEER(eee->conf.supernodes, eee->curr_sn); + if(is_null_mac(eee->curr_sn->mac_addr)) { + HASH_DEL(eee->conf.supernodes, eee->curr_sn); + memcpy(&eee->curr_sn->mac_addr, ra.srcMac, N2N_MAC_SIZE); + HASH_ADD_PEER(eee->conf.supernodes, eee->curr_sn); + } payload = (n2n_REGISTER_SUPER_ACK_payload_t*)tmpbuf; diff --git a/src/sn_selection.c b/src/sn_selection.c index 2efc176..061cf8c 100644 --- a/src/sn_selection.c +++ b/src/sn_selection.c @@ -47,7 +47,15 @@ int sn_selection_criterion_default (SN_SELECTION_CRITERION_DATA_TYPE *selection_ /* Set selection_criterion field to 'bad' value (worse than default) according to selected strategy. */ int sn_selection_criterion_bad (SN_SELECTION_CRITERION_DATA_TYPE *selection_criterion) { - *selection_criterion = (SN_SELECTION_CRITERION_DATA_TYPE) UINT32_MAX >> 1; + *selection_criterion = (SN_SELECTION_CRITERION_DATA_TYPE) (UINT32_MAX >> 1); + + return 0; /* OK */ +} + +/* Set selection_criterion field to 'good' value (better than default) according to selected strategy. */ +int sn_selection_criterion_good (SN_SELECTION_CRITERION_DATA_TYPE *selection_criterion) { + + *selection_criterion = (SN_SELECTION_CRITERION_DATA_TYPE) (UINT32_MAX >> 1) - 2; return 0; /* OK */ }