Browse Source

made n2n react more swiftly to (D)DNS changes (#705)

pull/706/head
Logan oos Even 3 years ago
committed by GitHub
parent
commit
1586ae62a7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      include/n2n_typedefs.h
  2. 4
      src/edge.c
  3. 6
      src/edge_utils.c
  4. 52
      src/n2n.c
  5. 4
      src/sn_utils.c

6
include/n2n_typedefs.h

@ -605,7 +605,10 @@ typedef struct n2n_resolve_parameter {
pthread_t id; /* thread id */ pthread_t id; /* thread id */
pthread_mutex_t access; /* mutex for shared access */ pthread_mutex_t access; /* mutex for shared access */
#endif #endif
time_t last_checked; /* last time the resolver completed */ uint8_t request; /* flags main thread's need for intermediate resolution */
time_t check_interval;/* interval to checik resolover results */
time_t last_checked; /* last time the resolver results were cheked */
time_t last_resolved; /* last time the resolver completed */
} n2n_resolve_parameter_t; } n2n_resolve_parameter_t;
@ -700,6 +703,7 @@ struct n2n_edge {
struct n2n_edge_stats stats; /**< Statistics */ struct n2n_edge_stats stats; /**< Statistics */
n2n_resolve_parameter_t *resolve_parameter; /**< Pointer to name resolver's parameter block */ n2n_resolve_parameter_t *resolve_parameter; /**< Pointer to name resolver's parameter block */
uint8_t resolution_request; /**< Flag an immediate DNS resolution request */
n2n_tuntap_priv_config_t tuntap_priv_conf; /**< Tuntap config */ n2n_tuntap_priv_config_t tuntap_priv_conf; /**< Tuntap config */

4
src/edge.c

@ -51,7 +51,7 @@ int fetch_and_eventually_process_data (n2n_edge_t *eee, SOCKET sock,
uint8_t *pktbuf, uint16_t *expected, uint16_t *position, uint8_t *pktbuf, uint16_t *expected, uint16_t *position,
time_t now); time_t now);
int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn_list); int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn_list);
int resolve_check (n2n_resolve_parameter_t *param, time_t now); int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, time_t now);
/* ***************************************************** */ /* ***************************************************** */
@ -1174,7 +1174,7 @@ int main (int argc, char* argv[]) {
} }
seek_answer = 1; seek_answer = 1;
resolve_check(eee->resolve_parameter, now); resolve_check(eee->resolve_parameter, 0 /* no intermediate resolution requirement at this point */, now);
} }
// allow a higher number of pings for first regular round of ping // allow a higher number of pings for first regular round of ping
// to quicker get an inital 'supernode selection criterion overview' // to quicker get an inital 'supernode selection criterion overview'

6
src/edge_utils.c

@ -26,7 +26,7 @@ static HEAP_ALLOC (wrkmem, LZO1X_1_MEM_COMPRESS);
/* ************************************** */ /* ************************************** */
int resolve_check (n2n_resolve_parameter_t *param, time_t now); int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, time_t now);
int resolve_cancel_thread (n2n_resolve_parameter_t *param); int resolve_cancel_thread (n2n_resolve_parameter_t *param);
static const char * supernode_ip (const n2n_edge_t * eee); static const char * supernode_ip (const n2n_edge_t * eee);
@ -1429,6 +1429,8 @@ void update_supernode_reg (n2n_edge_t * eee, time_t now) {
traceEvent(TRACE_WARNING, "Supernode not responding, now trying %s", supernode_ip(eee)); traceEvent(TRACE_WARNING, "Supernode not responding, now trying %s", supernode_ip(eee));
supernode_connect(eee); supernode_connect(eee);
reset_sup_attempts(eee); reset_sup_attempts(eee);
// trigger out-of-schedule DNS resolution
eee->resolution_request = 1;
// in some multi-NATed scenarios communication gets stuck on losing connection to supernode // in some multi-NATed scenarios communication gets stuck on losing connection to supernode
// closing and re-opening the socket allows for re-establishing communication // closing and re-opening the socket allows for re-establishing communication
@ -2959,7 +2961,7 @@ int run_edge_loop (n2n_edge_t *eee, int *keep_running) {
sort_supernodes(eee, now); sort_supernodes(eee, now);
resolve_check(eee->resolve_parameter, now); eee->resolution_request = resolve_check(eee->resolve_parameter, eee->resolution_request, now);
if(eee->cb.main_loop_period) if(eee->cb.main_loop_period)
eee->cb.main_loop_period(eee, now); eee->cb.main_loop_period(eee, now);

52
src/n2n.c

@ -318,14 +318,20 @@ void *resolve_thread (void *p) {
#ifdef HAVE_PTHREAD #ifdef HAVE_PTHREAD
n2n_resolve_parameter_t *param = (n2n_resolve_parameter_t*)p; n2n_resolve_parameter_t *param = (n2n_resolve_parameter_t*)p;
n2n_resolve_ip_sock_t *entry, *tmp_entry; n2n_resolve_ip_sock_t *entry, *tmp_entry;
int sleep_time = N2N_RESOLVE_INTERVAL / 10; /* initially shorter sleep */ time_t rep_time = N2N_RESOLVE_INTERVAL / 10;
time_t now;
while(1) { while(1) {
sleep(sleep_time); sleep(N2N_RESOLVE_INTERVAL / 60); /* wake up in-between to check for signaled requests */
// what's the time?
now = time(NULL);
// lock access // lock access
pthread_mutex_lock(&param->access); pthread_mutex_lock(&param->access);
// is it time to resolve yet?
if(((param->request)) || ((now - param->last_resolved) > rep_time)) {
HASH_ITER(hh, param->list, entry, tmp_entry) { HASH_ITER(hh, param->list, entry, tmp_entry) {
// resolve // resolve
entry->error_code = supernode2sock(&entry->sock, entry->org_ip); entry->error_code = supernode2sock(&entry->sock, entry->org_ip);
@ -336,19 +342,24 @@ void *resolve_thread (void *p) {
param->changed = 1; param->changed = 1;
} }
} }
param->last_resolved = now;
// unlock access // any request fulfilled
pthread_mutex_unlock(&param->access); param->request = 0;
// determine next sleep duration (shorter if resolver errors occured) // determine next resolver repetition (shorter time if resolver errors occured)
sleep_time = N2N_RESOLVE_INTERVAL; rep_time = N2N_RESOLVE_INTERVAL;
HASH_ITER(hh, param->list, entry, tmp_entry) { HASH_ITER(hh, param->list, entry, tmp_entry) {
if(entry->error_code) { if(entry->error_code) {
sleep_time = N2N_RESOLVE_INTERVAL / 10; rep_time = N2N_RESOLVE_INTERVAL / 10;
break; break;
} }
} }
} }
// unlock access
pthread_mutex_unlock(&param->access);
}
#endif #endif
} }
@ -376,6 +387,7 @@ int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn
traceEvent(TRACE_WARNING, "resolve_create_thread was unable to add list entry for supernode '%s'", sn->ip_addr); traceEvent(TRACE_WARNING, "resolve_create_thread was unable to add list entry for supernode '%s'", sn->ip_addr);
} }
} }
(*param)->check_interval = N2N_RESOLVE_CHECK_INTERVAL;
} else { } else {
traceEvent(TRACE_WARNING, "resolve_create_thread was unable to create list of supernodes"); traceEvent(TRACE_WARNING, "resolve_create_thread was unable to create list of supernodes");
return -1; return -1;
@ -404,13 +416,18 @@ void resolve_cancel_thread (n2n_resolve_parameter_t *param) {
} }
void resolve_check (n2n_resolve_parameter_t *param, time_t now) { uint8_t resolve_check (n2n_resolve_parameter_t *param, uint8_t requires_resolution, time_t now) {
uint8_t ret = requires_resolution; /* if trylock fails, it still requires resolution */
#ifdef HAVE_PTHREAD #ifdef HAVE_PTHREAD
n2n_resolve_ip_sock_t *entry, *tmp_entry; n2n_resolve_ip_sock_t *entry, *tmp_entry;
n2n_sock_str_t sock_buf; n2n_sock_str_t sock_buf;
if(now - param->last_checked > N2N_RESOLVE_CHECK_INTERVAL) { // check_interval and last_check do not need to be guarded by the mutex because
// their values get changed and evaluated only here
if((now - param->last_checked > param->check_interval) || (requires_resolution)) {
// try to lock access // try to lock access
if(pthread_mutex_trylock(&param->access) == 0) { if(pthread_mutex_trylock(&param->access) == 0) {
// any changes? // any changes?
@ -421,17 +438,32 @@ void resolve_check (n2n_resolve_parameter_t *param, time_t now) {
// sockets do not get overwritten in case of error in resolve_thread) from list to supernode list // sockets do not get overwritten in case of error in resolve_thread) from list to supernode list
HASH_ITER(hh, param->list, entry, tmp_entry) { HASH_ITER(hh, param->list, entry, tmp_entry) {
memcpy(entry->org_sock, &entry->sock, sizeof(n2n_sock_t)); memcpy(entry->org_sock, &entry->sock, sizeof(n2n_sock_t));
traceEvent(TRACE_DEBUG, "resolve_check renews ip address of supernode '%s' to %s", traceEvent(TRACE_INFO, "resolve_check renews ip address of supernode '%s' to %s",
entry->org_ip, sock_to_cstr(sock_buf, &(entry->sock))); entry->org_ip, sock_to_cstr(sock_buf, &(entry->sock)));
} }
} }
// let the resolver thread know eventual difficulties in reaching the supernode
if(requires_resolution) {
param->request = 1;
ret = 0;
}
param->last_checked = now; param->last_checked = now;
// next appointment
if(param->request)
// earlier if resolver still working on fulfilling a request
param->check_interval = N2N_RESOLVE_CHECK_INTERVAL / 10;
else
param->check_interval = N2N_RESOLVE_CHECK_INTERVAL;
// unlock access // unlock access
pthread_mutex_unlock(&param->access); pthread_mutex_unlock(&param->access);
} }
} }
#endif #endif
return ret;
} }

4
src/sn_utils.c

@ -20,7 +20,7 @@
#define HASH_FIND_COMMUNITY(head, name, out) HASH_FIND_STR(head, name, out) #define HASH_FIND_COMMUNITY(head, name, out) HASH_FIND_STR(head, name, out)
int resolve_check (n2n_resolve_parameter_t *param, time_t now); int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, time_t now);
int resolve_cancel_thread (n2n_resolve_parameter_t *param); int resolve_cancel_thread (n2n_resolve_parameter_t *param);
static ssize_t sendto_peer (n2n_sn_t *sss, static ssize_t sendto_peer (n2n_sn_t *sss,
@ -2364,7 +2364,7 @@ int run_sn_loop (n2n_sn_t *sss, int *keep_running) {
re_register_and_purge_supernodes(sss, sss->federation, &last_re_reg_and_purge, now); re_register_and_purge_supernodes(sss, sss->federation, &last_re_reg_and_purge, now);
purge_expired_communities(sss, &last_purge_edges, now); purge_expired_communities(sss, &last_purge_edges, now);
sort_communities(sss, &last_sort_communities, now); sort_communities(sss, &last_sort_communities, now);
resolve_check(sss->resolve_parameter, now); resolve_check(sss->resolve_parameter, 0 /* presumably, no special resolution requirement */, now);
} /* while */ } /* while */
sn_term(sss); sn_term(sss);

Loading…
Cancel
Save