diff --git a/include/n2n_define.h b/include/n2n_define.h index f9f707a..a4960e0 100644 --- a/include/n2n_define.h +++ b/include/n2n_define.h @@ -116,6 +116,9 @@ enum sn_purge{SN_PURGEABLE = 0, SN_UNPURGEABLE = 1}; #define N2N_TCP_BACKLOG_QUEUE_SIZE 3 /* number of concurrently pending connections to be accepted */ /* NOT the number of max. TCP connections */ +#define N2N_CLOSE_SOCKET_COUNTER_MAX 15 /* number of times of edge's reconnects to supernode after */ + /* which the socket explicitly is closed before reopening */ + /* flag used in add_sn_to_list_by_mac_or_sock */ enum skip_add{SN_ADD = 0, SN_ADD_SKIP = 1, SN_ADD_ADDED = 2}; diff --git a/include/n2n_typedefs.h b/include/n2n_typedefs.h index 1bb8c6a..372fdcb 100644 --- a/include/n2n_typedefs.h +++ b/include/n2n_typedefs.h @@ -633,12 +633,13 @@ struct n2n_edge { /* Sockets */ /* supernode socket is in eee->curr_sn->sock (of type n2n_sock_t) */ - int sock; - int udp_mgmt_sock; /**< socket for status info. */ + SOCKET sock; + int close_socket_counter; /**< counter for close-event before re-opening */ + SOCKET udp_mgmt_sock; /**< socket for status info. */ #ifndef SKIP_MULTICAST_PEERS_DISCOVERY n2n_sock_t multicast_peer; /**< Multicast peer group (for local edges) */ - int udp_multicast_sock; /**< socket for local multicast registrations. */ + SOCKET udp_multicast_sock; /**< socket for local multicast registrations. */ int multicast_joined; /**< 1 if the group has been joined.*/ #endif @@ -716,6 +717,7 @@ typedef struct n2n_tcp_connection { UT_hash_handle hh; /* makes this structure hashable */ } n2n_tcp_connection_t; + typedef struct n2n_sn { time_t start_time; /* Used to measure uptime. */ sn_stats_t stats; @@ -723,10 +725,10 @@ typedef struct n2n_sn { n2n_mac_t mac_addr; uint16_t lport; /* Local UDP port to bind to. */ uint16_t mport; /* Management UDP port to bind to. */ - int sock; /* Main socket for UDP traffic with edges. */ - int tcp_sock; /* auxiliary socket for optional TCP connections */ + SOCKET sock; /* Main socket for UDP traffic with edges. */ + SOCKET tcp_sock; /* auxiliary socket for optional TCP connections */ n2n_tcp_connection_t *tcp_connections;/* list of established TCP connections */ - int mgmt_sock; /* management socket. */ + SOCKET mgmt_sock; /* management socket. */ n2n_ip_subnet_t min_auto_ip_net; /* Address range of auto_ip service. */ n2n_ip_subnet_t max_auto_ip_net; /* Address range of auto_ip service. */ #ifndef WIN32 diff --git a/src/edge_utils.c b/src/edge_utils.c index a582e67..bf8f0f5 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -191,7 +191,6 @@ void reset_sup_attempts (n2n_edge_t *eee) { } - // open socket, close it before if TCP // in case of TCP, 'connect()' is required int supernode_connect(n2n_edge_t *eee) { @@ -1323,17 +1322,21 @@ void update_supernode_reg (n2n_edge_t * eee, time_t now) { reset_sup_attempts(eee); // in some multi-NATed scenarios communication gets stuck on losing connection to supernode - // closing and re-opening the socket(s) allows for re-establishing communication + // closing and re-opening the socket allows for re-establishing communication // this can only be done, if working on some unprivileged port and/or having sufficent // privileges. as we are not able to check for sufficent privileges here, we only do it // if port is sufficently high or unset. uncovered: privileged port and sufficent privileges if((eee->conf.local_port == 0) || (eee->conf.local_port > 1024)) { - if(edge_init_sockets(eee) < 0) { - traceEvent(TRACE_ERROR, "update_supernode_reg failed while trying socket re-initiliaization"); + // do not explicitly disconnect every time as the condition descibed is rare + (eee->close_socket_counter)++; + if(eee->close_socket_counter >= N2N_CLOSE_SOCKET_COUNTER_MAX) { + eee->close_socket_counter = 0; + supernode_disconnect(eee); + traceEvent(TRACE_DEBUG, "update_supernode_reg disconnected supernode"); } - supernode_disconnect(eee); + supernode_connect(eee); - traceEvent(TRACE_DEBUG, "update_supernode_reg disconnected and reconnected supernode "); + traceEvent(TRACE_DEBUG, "update_supernode_reg reconnected to supernode"); } } else {