improved socket handling (#650)

This commit is contained in:
Logan oos Even 2021-03-01 14:13:14 +05:45 committed by GitHub
parent d8ae2e89ca
commit 20133f599c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 12 deletions

View File

@ -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 */ #define N2N_TCP_BACKLOG_QUEUE_SIZE 3 /* number of concurrently pending connections to be accepted */
/* NOT the number of max. TCP connections */ /* 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 */ /* 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}; enum skip_add{SN_ADD = 0, SN_ADD_SKIP = 1, SN_ADD_ADDED = 2};

View File

@ -633,12 +633,13 @@ struct n2n_edge {
/* Sockets */ /* Sockets */
/* supernode socket is in eee->curr_sn->sock (of type n2n_sock_t) */ /* supernode socket is in eee->curr_sn->sock (of type n2n_sock_t) */
int sock; SOCKET sock;
int udp_mgmt_sock; /**< socket for status info. */ int close_socket_counter; /**< counter for close-event before re-opening */
SOCKET udp_mgmt_sock; /**< socket for status info. */
#ifndef SKIP_MULTICAST_PEERS_DISCOVERY #ifndef SKIP_MULTICAST_PEERS_DISCOVERY
n2n_sock_t multicast_peer; /**< Multicast peer group (for local edges) */ 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.*/ int multicast_joined; /**< 1 if the group has been joined.*/
#endif #endif
@ -716,6 +717,7 @@ typedef struct n2n_tcp_connection {
UT_hash_handle hh; /* makes this structure hashable */ UT_hash_handle hh; /* makes this structure hashable */
} n2n_tcp_connection_t; } n2n_tcp_connection_t;
typedef struct n2n_sn { typedef struct n2n_sn {
time_t start_time; /* Used to measure uptime. */ time_t start_time; /* Used to measure uptime. */
sn_stats_t stats; sn_stats_t stats;
@ -723,10 +725,10 @@ typedef struct n2n_sn {
n2n_mac_t mac_addr; n2n_mac_t mac_addr;
uint16_t lport; /* Local UDP port to bind to. */ uint16_t lport; /* Local UDP port to bind to. */
uint16_t mport; /* Management UDP port to bind to. */ uint16_t mport; /* Management UDP port to bind to. */
int sock; /* Main socket for UDP traffic with edges. */ SOCKET sock; /* Main socket for UDP traffic with edges. */
int tcp_sock; /* auxiliary socket for optional TCP connections */ SOCKET tcp_sock; /* auxiliary socket for optional TCP connections */
n2n_tcp_connection_t *tcp_connections;/* list of established 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 min_auto_ip_net; /* Address range of auto_ip service. */
n2n_ip_subnet_t max_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 #ifndef WIN32

View File

@ -191,7 +191,6 @@ void reset_sup_attempts (n2n_edge_t *eee) {
} }
// open socket, close it before if TCP // open socket, close it before if TCP
// in case of TCP, 'connect()' is required // in case of TCP, 'connect()' is required
int supernode_connect(n2n_edge_t *eee) { 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); reset_sup_attempts(eee);
// 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(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 // 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 // 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 port is sufficently high or unset. uncovered: privileged port and sufficent privileges
if((eee->conf.local_port == 0) || (eee->conf.local_port > 1024)) { if((eee->conf.local_port == 0) || (eee->conf.local_port > 1024)) {
if(edge_init_sockets(eee) < 0) { // do not explicitly disconnect every time as the condition descibed is rare
traceEvent(TRACE_ERROR, "update_supernode_reg failed while trying socket re-initiliaization"); (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); supernode_connect(eee);
traceEvent(TRACE_DEBUG, "update_supernode_reg disconnected and reconnected supernode "); traceEvent(TRACE_DEBUG, "update_supernode_reg reconnected to supernode");
} }
} else { } else {