mirror of
https://github.com/ntop/n2n.git
synced 2024-09-19 16:41:11 +02:00
separated 'detect_local_ip_address()' function (#781)
This commit is contained in:
parent
7f1fe9a499
commit
b3bf36f867
|
@ -223,6 +223,8 @@ 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);
|
||||
|
|
|
@ -204,9 +204,8 @@ int supernode_connect(n2n_edge_t *eee) {
|
|||
|
||||
int sockopt;
|
||||
struct sockaddr_in sn_sock;
|
||||
struct sockaddr_in local_sock;
|
||||
int sock_len = sizeof(local_sock);
|
||||
SOCKET probe_sock;
|
||||
n2n_sock_t local_sock;
|
||||
n2n_sock_str_t sockbuf;
|
||||
|
||||
if((eee->conf.connect_tcp) && (eee->sock >= 0)) {
|
||||
closesocket(eee->sock);
|
||||
|
@ -266,25 +265,16 @@ int supernode_connect(n2n_edge_t *eee) {
|
|||
traceEvent(TRACE_INFO, "PMTU discovery %s", (eee->conf.disable_pmtu_discovery) ? "disabled" : "enabled");
|
||||
#endif
|
||||
|
||||
// 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))) {
|
||||
// ... and write to local preferred socket -- no matter if used or not
|
||||
eee->conf.preferred_sock.port = ntohs(local_sock.sin_port);
|
||||
// probe for & overwrite local address only if auto-detection mode
|
||||
memset(&local_sock, 0, sizeof(n2n_sock_t));
|
||||
if(detect_local_ip_address(&local_sock, eee) == 0) {
|
||||
// always overwrite local port even/especially if chosen by OS...
|
||||
eee->conf.preferred_sock.port = local_sock.port;
|
||||
// only if auto-detection mode, ...
|
||||
if(eee->conf.preferred_sock_auto) {
|
||||
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; hence, we use a temporary socket
|
||||
connect(probe_sock, (struct sockaddr *)&sn_sock, sizeof(sn_sock));
|
||||
if((getsockname(probe_sock, (struct sockaddr *)&local_sock, &sock_len) == 0)
|
||||
&& (local_sock.sin_family == AF_INET)
|
||||
&& (sock_len == sizeof(local_sock))) {
|
||||
memcpy(&(eee->conf.preferred_sock.addr.v4), &(local_sock.sin_addr.s_addr), IPV4_SIZE);
|
||||
}
|
||||
close(probe_sock);
|
||||
// ... overwrite IP address, too (whole socket struct here)
|
||||
memcpy(&eee->conf.preferred_sock, &local_sock, sizeof(n2n_sock_t));
|
||||
traceEvent(TRACE_INFO, "determined local socket [%s]",
|
||||
sock_to_cstr(sockbuf, &local_sock));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
48
src/n2n.c
48
src/n2n.c
|
@ -61,6 +61,54 @@ SOCKET open_socket (int local_port, in_addr_t address, int type /* 0 = UDP, TCP
|
|||
}
|
||||
|
||||
|
||||
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;
|
||||
int sock_len = sizeof(local_sock);
|
||||
int port = 0;
|
||||
SOCKET probe_sock;
|
||||
|
||||
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
|
||||
return -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(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
|
||||
return -4;
|
||||
} else
|
||||
return -3;
|
||||
close(probe_sock);
|
||||
} else
|
||||
return -2;
|
||||
|
||||
out_sock->family = AF_INET;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int traceLevel = 2 /* NORMAL */;
|
||||
static int useSyslog = 0, syslog_opened = 0;
|
||||
static FILE *traceFile = NULL;
|
||||
|
|
Loading…
Reference in New Issue
Block a user