relocated 'detect_local_ip_address()' (#791)

This commit is contained in:
Logan oos Even 2021-09-16 12:20:35 +05:45 committed by GitHub
parent 6b353141b4
commit 9c22d28562
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 2 deletions

View File

@ -223,8 +223,6 @@ char * ip_subnet_to_str (dec_ip_bit_str_t buf, const n2n_ip_subnet_t *ipaddr);
SOCKET open_socket (int local_port, in_addr_t address, int type);
int sock_equal (const n2n_sock_t * a,
const n2n_sock_t * b);
int detect_local_ip_address (n2n_sock_t* out_sock,
const n2n_edge_t* eee);
/* Header encryption */
uint64_t time_stamp (void);

View File

@ -198,6 +198,53 @@ void reset_sup_attempts (n2n_edge_t *eee) {
}
// detect local IP address by probing a connection to the supernode
static int detect_local_ip_address (n2n_sock_t* out_sock, const n2n_edge_t* eee) {
struct sockaddr_in local_sock;
struct sockaddr_in sn_sock;
socklen_t sock_len = sizeof(local_sock);
SOCKET probe_sock;
int ret = 0;
out_sock->family = AF_INVALID;
// always detetct local port even/especially if chosen by OS...
if((getsockname(eee->sock, (struct sockaddr *)&local_sock, &sock_len) == 0)
&& (local_sock.sin_family == AF_INET)
&& (sock_len == sizeof(local_sock)))
// remember the port number
out_sock->port = ntohs(local_sock.sin_port);
else
ret = -1;
// probe for local IP address
probe_sock = socket(PF_INET, SOCK_DGRAM, 0);
// connecting the UDP socket makes getsockname read the local address it uses to connect (to the sn in this case);
// we cannot do it with the real (eee->sock) socket because socket does not accept any conenction from elsewhere then,
// e.g. from another edge instead of the supernode; as re-connecting to AF_UNSPEC might not work to release the socket
// on non-UNIXoids, we use a temporary socket
if((int)probe_sock >= 0) {
fill_sockaddr((struct sockaddr*)&sn_sock, sizeof(sn_sock), &eee->curr_sn->sock);
if(connect(probe_sock, (struct sockaddr *)&sn_sock, sizeof(sn_sock)) == 0) {
if((getsockname(probe_sock, (struct sockaddr *)&local_sock, &sock_len) == 0)
&& (local_sock.sin_family == AF_INET)
&& (sock_len == sizeof(local_sock))) {
memcpy(&(out_sock->addr.v4), &(local_sock.sin_addr.s_addr), IPV4_SIZE);
} else
ret = -4;
} else
ret = -3;
closesocket(probe_sock);
} else
ret = -2;
out_sock->family = AF_INET;
return ret;
}
// open socket, close it before if TCP
// in case of TCP, 'connect()' is required
int supernode_connect(n2n_edge_t *eee) {