mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
made n2n react more swiftly to (D)DNS changes (#705)
This commit is contained in:
parent
75ab1fc5aa
commit
1586ae62a7
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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
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(¶m->access);
|
pthread_mutex_lock(¶m->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(¶m->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(¶m->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(¶m->access) == 0) {
|
if(pthread_mutex_trylock(¶m->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(¶m->access);
|
pthread_mutex_unlock(¶m->access);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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…
Reference in New Issue
Block a user