mirror of
https://github.com/ntop/n2n.git
synced 2024-09-19 16:41:11 +02:00
made n2n react more swiftly to (D)DNS changes (#705)
This commit is contained in:
parent
75ab1fc5aa
commit
1586ae62a7
|
@ -599,13 +599,16 @@ typedef struct n2n_resolve_ip_sock {
|
|||
|
||||
// structure to hold resolver thread's parameters
|
||||
typedef struct n2n_resolve_parameter {
|
||||
n2n_resolve_ip_sock_t *list; /* pointer to list of to be resolved nodes */
|
||||
uint8_t changed; /* indicates a change */
|
||||
n2n_resolve_ip_sock_t *list; /* pointer to list of to be resolved nodes */
|
||||
uint8_t changed; /* indicates a change */
|
||||
#ifdef HAVE_PTHREAD
|
||||
pthread_t id; /* thread id */
|
||||
pthread_mutex_t access; /* mutex for shared access */
|
||||
pthread_t id; /* thread id */
|
||||
pthread_mutex_t access; /* mutex for shared access */
|
||||
#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;
|
||||
|
||||
|
||||
|
@ -700,6 +703,7 @@ struct n2n_edge {
|
|||
struct n2n_edge_stats stats; /**< Statistics */
|
||||
|
||||
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 */
|
||||
|
||||
|
|
|
@ -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,
|
||||
time_t now);
|
||||
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;
|
||||
|
||||
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
|
||||
// to quicker get an inital 'supernode selection criterion overview'
|
||||
|
|
|
@ -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);
|
||||
|
||||
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));
|
||||
supernode_connect(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
|
||||
// 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);
|
||||
|
||||
resolve_check(eee->resolve_parameter, now);
|
||||
eee->resolution_request = resolve_check(eee->resolve_parameter, eee->resolution_request, now);
|
||||
|
||||
if(eee->cb.main_loop_period)
|
||||
eee->cb.main_loop_period(eee, now);
|
||||
|
|
78
src/n2n.c
78
src/n2n.c
|
@ -318,36 +318,47 @@ void *resolve_thread (void *p) {
|
|||
#ifdef HAVE_PTHREAD
|
||||
n2n_resolve_parameter_t *param = (n2n_resolve_parameter_t*)p;
|
||||
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) {
|
||||
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
|
||||
pthread_mutex_lock(¶m->access);
|
||||
|
||||
HASH_ITER(hh, param->list, entry, tmp_entry) {
|
||||
// resolve
|
||||
entry->error_code = supernode2sock(&entry->sock, entry->org_ip);
|
||||
// if socket changed and no error
|
||||
if(!sock_equal(&entry->sock, entry->org_sock)
|
||||
&& (!entry->error_code)) {
|
||||
// flag the change
|
||||
param->changed = 1;
|
||||
// is it time to resolve yet?
|
||||
if(((param->request)) || ((now - param->last_resolved) > rep_time)) {
|
||||
HASH_ITER(hh, param->list, entry, tmp_entry) {
|
||||
// resolve
|
||||
entry->error_code = supernode2sock(&entry->sock, entry->org_ip);
|
||||
// if socket changed and no error
|
||||
if(!sock_equal(&entry->sock, entry->org_sock)
|
||||
&& (!entry->error_code)) {
|
||||
// flag the change
|
||||
param->changed = 1;
|
||||
}
|
||||
}
|
||||
param->last_resolved = now;
|
||||
|
||||
// any request fulfilled
|
||||
param->request = 0;
|
||||
|
||||
// determine next resolver repetition (shorter time if resolver errors occured)
|
||||
rep_time = N2N_RESOLVE_INTERVAL;
|
||||
HASH_ITER(hh, param->list, entry, tmp_entry) {
|
||||
if(entry->error_code) {
|
||||
rep_time = N2N_RESOLVE_INTERVAL / 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unlock access
|
||||
pthread_mutex_unlock(¶m->access);
|
||||
|
||||
// determine next sleep duration (shorter if resolver errors occured)
|
||||
sleep_time = N2N_RESOLVE_INTERVAL;
|
||||
HASH_ITER(hh, param->list, entry, tmp_entry) {
|
||||
if(entry->error_code) {
|
||||
sleep_time = N2N_RESOLVE_INTERVAL / 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#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);
|
||||
}
|
||||
}
|
||||
(*param)->check_interval = N2N_RESOLVE_CHECK_INTERVAL;
|
||||
} else {
|
||||
traceEvent(TRACE_WARNING, "resolve_create_thread was unable to create list of supernodes");
|
||||
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
|
||||
n2n_resolve_ip_sock_t *entry, *tmp_entry;
|
||||
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
|
||||
if(pthread_mutex_trylock(¶m->access) == 0) {
|
||||
// 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
|
||||
HASH_ITER(hh, param->list, entry, tmp_entry) {
|
||||
memcpy(entry->org_sock, &entry->sock, sizeof(n2n_sock_t));
|
||||
traceEvent(TRACE_DEBUG, "resolve_check renews ip address of supernode '%s' to %s",
|
||||
entry->org_ip, sock_to_cstr(sock_buf, &(entry->sock)));
|
||||
traceEvent(TRACE_INFO, "resolve_check renews ip address of supernode '%s' to %s",
|
||||
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;
|
||||
|
||||
// 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
|
||||
pthread_mutex_unlock(¶m->access);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#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);
|
||||
|
||||
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);
|
||||
purge_expired_communities(sss, &last_purge_edges, 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 */
|
||||
|
||||
sn_term(sss);
|
||||
|
|
Loading…
Reference in New Issue
Block a user