mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
allowed edge to optionally auto-detetct local IP address ('-e auto') for advertising as preferred (#776)
This commit is contained in:
parent
defad50f87
commit
7f1fe9a499
5
edge.8
5
edge.8
|
@ -44,10 +44,11 @@ TOS for packets, e.g. 0x48 for SSH like priority
|
||||||
enable PMTU discovery, it can reduce fragmentation but
|
enable PMTU discovery, it can reduce fragmentation but
|
||||||
causes connections to stall if not properly supported
|
causes connections to stall if not properly supported
|
||||||
.TP
|
.TP
|
||||||
\fB\-e \fR<\fIlocal ip\fR>
|
\fB\-e \fR<\fIlocal_ip_address\fR>
|
||||||
advertises the provided local IP address as preferred,
|
advertises the provided local IP address as preferred,
|
||||||
useful if multicast peer detection is not available, e.g.
|
useful if multicast peer detection is not available, e.g.
|
||||||
disabled on routers
|
disabled on routers. \fB\-e auto\fR tries auto-detection of
|
||||||
|
local IP address.
|
||||||
.TP
|
.TP
|
||||||
\fB\-S1\fR ... \fB\-S2\fR
|
\fB\-S1\fR ... \fB\-S2\fR
|
||||||
do not connect p2p, always use the supernode,
|
do not connect p2p, always use the supernode,
|
||||||
|
|
|
@ -652,6 +652,7 @@ typedef struct n2n_edge_conf {
|
||||||
int register_ttl; /**< TTL for registration packet when UDP NAT hole punching through supernode. */
|
int register_ttl; /**< TTL for registration packet when UDP NAT hole punching through supernode. */
|
||||||
in_addr_t bind_address; /**< The address to bind to if provided (-b) */
|
in_addr_t bind_address; /**< The address to bind to if provided (-b) */
|
||||||
n2n_sock_t preferred_sock; /**< propagated local sock for better p2p in LAN (-e) */
|
n2n_sock_t preferred_sock; /**< propagated local sock for better p2p in LAN (-e) */
|
||||||
|
uint8_t preferred_sock_auto; /**< indicates desired auto detect for preferred sock */
|
||||||
int local_port;
|
int local_port;
|
||||||
int mgmt_port;
|
int mgmt_port;
|
||||||
uint8_t connect_tcp; /** connection to supernode 0 = UDP; 1 = TCP */
|
uint8_t connect_tcp; /** connection to supernode 0 = UDP; 1 = TCP */
|
||||||
|
|
14
src/edge.c
14
src/edge.c
|
@ -255,7 +255,8 @@ static void help (int level) {
|
||||||
" | causes connections to stall if not properly supported\n");
|
" | causes connections to stall if not properly supported\n");
|
||||||
#endif
|
#endif
|
||||||
printf(" -e <local ip> | advertises the provided local IP address as preferred,\n"
|
printf(" -e <local ip> | advertises the provided local IP address as preferred,\n"
|
||||||
" | useful if multicast peer detection is not available\n");
|
" | useful if multicast peer detection is not available,\n"
|
||||||
|
" | '-e auto' tries IP address auto-detection\n");
|
||||||
printf(" -S1 ... -S2 | do not connect p2p, always use the supernode,\n"
|
printf(" -S1 ... -S2 | do not connect p2p, always use the supernode,\n"
|
||||||
" | -S1 = via UDP"
|
" | -S1 = via UDP"
|
||||||
|
|
||||||
|
@ -615,8 +616,16 @@ static int setOption (int optkey, char *optargument, n2n_tuntap_priv_config_t *e
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'e': {
|
case 'e': {
|
||||||
|
in_addr_t address_tmp;
|
||||||
|
|
||||||
if(optargument) {
|
if(optargument) {
|
||||||
in_addr_t address_tmp = inet_addr(optargument);
|
|
||||||
|
if(!strcmp(optargument, "auto")) {
|
||||||
|
address_tmp = INADDR_ANY;
|
||||||
|
conf->preferred_sock_auto = 1;
|
||||||
|
} else {
|
||||||
|
address_tmp = inet_addr(optargument);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&(conf->preferred_sock.addr.v4), &(address_tmp), IPV4_SIZE);
|
memcpy(&(conf->preferred_sock.addr.v4), &(address_tmp), IPV4_SIZE);
|
||||||
|
|
||||||
|
@ -1098,7 +1107,6 @@ int main (int argc, char* argv[]) {
|
||||||
eee->last_sup = 0; /* if it wasn't zero yet */
|
eee->last_sup = 0; /* if it wasn't zero yet */
|
||||||
eee->curr_sn = eee->conf.supernodes;
|
eee->curr_sn = eee->conf.supernodes;
|
||||||
supernode_connect(eee);
|
supernode_connect(eee);
|
||||||
|
|
||||||
while(runlevel < 5) {
|
while(runlevel < 5) {
|
||||||
|
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
|
|
|
@ -203,8 +203,10 @@ void reset_sup_attempts (n2n_edge_t *eee) {
|
||||||
int supernode_connect(n2n_edge_t *eee) {
|
int supernode_connect(n2n_edge_t *eee) {
|
||||||
|
|
||||||
int sockopt;
|
int sockopt;
|
||||||
struct sockaddr_in sock;
|
struct sockaddr_in sn_sock;
|
||||||
int sock_len = sizeof(sock);
|
struct sockaddr_in local_sock;
|
||||||
|
int sock_len = sizeof(local_sock);
|
||||||
|
SOCKET probe_sock;
|
||||||
|
|
||||||
if((eee->conf.connect_tcp) && (eee->sock >= 0)) {
|
if((eee->conf.connect_tcp) && (eee->sock >= 0)) {
|
||||||
closesocket(eee->sock);
|
closesocket(eee->sock);
|
||||||
|
@ -227,18 +229,7 @@ int supernode_connect(n2n_edge_t *eee) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// detetct local port, even/especially if chosen by OS...
|
fill_sockaddr((struct sockaddr*)&sn_sock, sizeof(sn_sock), &eee->curr_sn->sock);
|
||||||
if((getsockname(eee->sock, (struct sockaddr *)&sock, &sock_len) == 0)
|
|
||||||
&& (sock.sin_family == AF_INET)
|
|
||||||
&& (sock_len == sizeof(sock))) {
|
|
||||||
// ... and write to local preferred socket -- no matter if used or not
|
|
||||||
eee->conf.preferred_sock.port = ntohs(sock.sin_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
// variable 'sock' gets re-used from here on (for sn)
|
|
||||||
sock.sin_family = eee->curr_sn->sock.family;
|
|
||||||
sock.sin_port = htons(eee->curr_sn->sock.port);
|
|
||||||
memcpy(&(sock.sin_addr.s_addr), &(eee->curr_sn->sock.addr.v4), IPV4_SIZE);
|
|
||||||
|
|
||||||
// set tcp socket to O_NONBLOCK so connect does not hang
|
// set tcp socket to O_NONBLOCK so connect does not hang
|
||||||
// requires checking the socket for readiness before sending and receving
|
// requires checking the socket for readiness before sending and receving
|
||||||
|
@ -249,7 +240,7 @@ int supernode_connect(n2n_edge_t *eee) {
|
||||||
#else
|
#else
|
||||||
fcntl(eee->sock, F_SETFL, O_NONBLOCK);
|
fcntl(eee->sock, F_SETFL, O_NONBLOCK);
|
||||||
#endif
|
#endif
|
||||||
if((connect(eee->sock, (struct sockaddr*)&(sock), sizeof(struct sockaddr)) < 0)
|
if((connect(eee->sock, (struct sockaddr*)&(sn_sock), sizeof(struct sockaddr)) < 0)
|
||||||
&& (errno != EINPROGRESS)) {
|
&& (errno != EINPROGRESS)) {
|
||||||
eee->sock = -1;
|
eee->sock = -1;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -275,6 +266,28 @@ int supernode_connect(n2n_edge_t *eee) {
|
||||||
traceEvent(TRACE_INFO, "PMTU discovery %s", (eee->conf.disable_pmtu_discovery) ? "disabled" : "enabled");
|
traceEvent(TRACE_INFO, "PMTU discovery %s", (eee->conf.disable_pmtu_discovery) ? "disabled" : "enabled");
|
||||||
#endif
|
#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
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(eee->cb.sock_opened)
|
if(eee->cb.sock_opened)
|
||||||
eee->cb.sock_opened(eee);
|
eee->cb.sock_opened(eee);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user