enabled edge to bind to a specified IP address (-b) (#753)

This commit is contained in:
Logan oos Even 2021-08-27 23:23:23 +02:00 committed by GitHub
parent ecedcdcb58
commit c21accc2a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 44 additions and 13 deletions

4
edge.8
View File

@ -40,6 +40,10 @@ TOS for packets, e.g. 0x48 for SSH like priority
enable PMTU discovery, it can reduce fragmentation but
causes connections to stall if not properly supported
.TP
\fB\-b \fR<\fIbind ip\fR>
binds edge to the provided local IP address only, defaults to 'any' ip address
if not provided
.TP
\fB\-S1\fR ... \fB\-S2\fR
do not connect p2p, always use the supernode,
\-S1 = via UDP, \-S2 = via TCP

View File

@ -220,7 +220,7 @@ int memxor (uint8_t *destination, const uint8_t *source, size_t len);
char* sock_to_cstr (n2n_sock_str_t out,
const n2n_sock_t * sock);
char * ip_subnet_to_str (dec_ip_bit_str_t buf, const n2n_ip_subnet_t *ipaddr);
SOCKET open_socket (int local_port, int bind_any, int type);
SOCKET open_socket (int local_port, int bind_any, in_addr_t address, int type);
int sock_equal (const n2n_sock_t * a,
const n2n_sock_t * b);

View File

@ -646,6 +646,7 @@ typedef struct n2n_edge_conf {
char *encrypt_key;
int register_interval; /**< Interval for supernode registration, also used for UDP NAT hole punching. */
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) */
int local_port;
int mgmt_port;
uint8_t connect_tcp; /** connection to supernode 0 = UDP; 1 = TCP */

View File

@ -177,7 +177,7 @@ static void help (int level) {
"[-H] "
"[-z<compression>]"
"\n "
"[-S<level of solitude>]"
"[-b <bind IP address>][-S<level of solitude>]"
"\n\n tap device and "
"[-a [static:|dhcp:]<tap IP address>[/<cidr suffix>]] "
"\n overlay network "
@ -252,6 +252,8 @@ static void help (int level) {
printf(" -D | enable PMTU discovery, it can reduce fragmentation but\n"
" | causes connections to stall if not properly supported\n");
#endif
printf(" -b <bind ip> | bind the edge to the provided local IP address only,\n"
" | defaults to 'any' ip address if not provided\n");
printf(" -S1 ... -S2 | do not connect p2p, always use the supernode,\n"
" | -S1 = via UDP"
@ -589,6 +591,20 @@ static int setOption (int optkey, char *optargument, n2n_tuntap_priv_config_t *e
break;
}
case 'b': {
if(optargument) {
conf->bind_address = inet_addr(optargument);
if(conf->bind_address == INADDR_NONE) {
traceEvent(TRACE_WARNING, "Bad address to bind to, binding to any IP address.");
conf->bind_address = INADDR_ANY;
break;
}
}
break;
}
case 't': {
conf->mgmt_port = atoi(optargument);
break;
@ -711,6 +727,7 @@ static const struct option long_options[] =
{ "tap-device", required_argument, NULL, 'd' },
{ "euid", required_argument, NULL, 'u' },
{ "egid", required_argument, NULL, 'g' },
{ "bind", required_argument, NULL, 'b' },
{ "help" , no_argument, NULL, '@' }, /* special character '@' to identify long help case */
{ "verbose", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 }
@ -724,7 +741,7 @@ static int loadFromCLI (int argc, char *argv[], n2n_edge_conf_t *conf, n2n_tunta
u_char c;
while ((c = getopt_long(argc, argv,
"k:a:bc:Eu:g:m:M:s:d:l:p:fvhrt:i:I:J:P:S::DL:z::A::Hn:R:"
"k:a:b:c:Eu:g:m:M:s:d:l:p:fvhrt:i:I:J:P:S::DL:z::A::Hn:R:"
#ifdef __linux__
"T:"
#endif

View File

@ -214,7 +214,8 @@ int supernode_connect(n2n_edge_t *eee) {
(eee->conf.connect_tcp) ? 0 : eee->conf.local_port);
eee->sock = open_socket((eee->conf.connect_tcp) ? 0 : eee->conf.local_port,
1 /* bind ANY */, eee->conf.connect_tcp);
2 /* bind as provided with next parameter */, eee->conf.bind_address,
eee->conf.connect_tcp);
if(eee->sock < 0) {
traceEvent(TRACE_ERROR, "Failed to bind main UDP port %u",
@ -3090,7 +3091,7 @@ static int edge_init_sockets (n2n_edge_t *eee) {
closesocket(eee->udp_multicast_sock);
#endif
eee->udp_mgmt_sock = open_socket(eee->conf.mgmt_port, 0 /* bind LOOPBACK */, 0 /* UDP */);
eee->udp_mgmt_sock = open_socket(eee->conf.mgmt_port, 0 /* bind LOOPBACK */, 0, 0 /* UDP */);
if(eee->udp_mgmt_sock < 0) {
traceEvent(TRACE_ERROR, "Failed to bind management UDP port %u", eee->conf.mgmt_port);
return(-2);
@ -3105,7 +3106,7 @@ static int edge_init_sockets (n2n_edge_t *eee) {
eee->multicast_peer.addr.v4[2] = 0;
eee->multicast_peer.addr.v4[3] = 68;
eee->udp_multicast_sock = open_socket(N2N_MULTICAST_PORT, 1 /* bind ANY */, 0 /* UDP */);
eee->udp_multicast_sock = open_socket(N2N_MULTICAST_PORT, 1 /* bind ANY */, 0, 0 /* UDP */);
if(eee->udp_multicast_sock < 0)
return(-3);
else {
@ -3523,6 +3524,7 @@ void edge_init_conf_defaults (n2n_edge_conf_t *conf) {
memset(conf, 0, sizeof(*conf));
conf->bind_address = INADDR_ANY; /* any address */
conf->local_port = 0 /* any port */;
conf->mgmt_port = N2N_EDGE_MGMT_PORT; /* 5644 by default */
conf->transop_id = N2N_TRANSFORM_ID_NULL;

View File

@ -29,12 +29,12 @@ int main () {
sss_node.daemon = 0; // Whether to daemonize
sss_node.lport = 1234; // Main UDP listen port
sss_node.sock = open_socket(sss_node.lport, 1, 0);
sss_node.sock = open_socket(sss_node.lport, 1, 0, 0);
if(-1 == sss_node.sock) {
exit(-2);
}
sss_node.mgmt_sock = open_socket(5645, 0, 0); // Main UDP management port
sss_node.mgmt_sock = open_socket(5645, 0, 0, 0); // Main UDP management port
if(-1 == sss_node.mgmt_sock) {
exit(-2);
}

View File

@ -28,7 +28,7 @@
/* ************************************** */
SOCKET open_socket (int local_port, int bind_any, int type /* 0 = UDP, TCP otherwise */) {
SOCKET open_socket (int local_port, int bind_any, in_addr_t address, int type /* 0 = UDP, TCP otherwise */) {
SOCKET sock_fd;
struct sockaddr_in local_address;
@ -50,7 +50,14 @@ SOCKET open_socket (int local_port, int bind_any, int type /* 0 = UDP, TCP other
memset(&local_address, 0, sizeof(local_address));
local_address.sin_family = AF_INET;
local_address.sin_port = htons(local_port);
local_address.sin_addr.s_addr = htonl(bind_any ? INADDR_ANY : INADDR_LOOPBACK);
if(bind_any == 2) {
// use the provided address for binding
// REVISIT: allow for multiple addresses to be provided, i.e. through several '-b' at cli,
// internally requires a list of in_addr_t addresses
local_address.sin_addr.s_addr = address;
} else {
local_address.sin_addr.s_addr = htonl(bind_any ? INADDR_ANY : INADDR_LOOPBACK);
}
if(bind(sock_fd,(struct sockaddr*) &local_address, sizeof(local_address)) == -1) {
traceEvent(TRACE_ERROR, "Bind error on local port %u [%s]\n", local_port, strerror(errno));

View File

@ -577,7 +577,7 @@ int main (int argc, char * const argv[]) {
traceEvent(TRACE_DEBUG, "traceLevel is %d", getTraceLevel());
sss_node.sock = open_socket(sss_node.lport, 1 /*bind ANY*/, 0 /* UDP */);
sss_node.sock = open_socket(sss_node.lport, 1 /*bind ANY*/, 0, 0 /* UDP */);
if(-1 == sss_node.sock) {
traceEvent(TRACE_ERROR, "Failed to open main socket. %s", strerror(errno));
exit(-2);
@ -586,7 +586,7 @@ int main (int argc, char * const argv[]) {
}
#ifdef N2N_HAVE_TCP
sss_node.tcp_sock = open_socket(sss_node.lport, 1 /*bind ANY*/, 1 /* TCP */);
sss_node.tcp_sock = open_socket(sss_node.lport, 1 /*bind ANY*/, 0, 1 /* TCP */);
if(-1 == sss_node.tcp_sock) {
traceEvent(TRACE_ERROR, "Failed to open auxiliary TCP socket. %s", strerror(errno));
exit(-2);
@ -602,7 +602,7 @@ int main (int argc, char * const argv[]) {
}
#endif
sss_node.mgmt_sock = open_socket(sss_node.mport, 0 /* bind LOOPBACK */, 0 /* UDP */);
sss_node.mgmt_sock = open_socket(sss_node.mport, 0 /* bind LOOPBACK */, 0, 0 /* UDP */);
if(-1 == sss_node.mgmt_sock) {
traceEvent(TRACE_ERROR, "Failed to open management socket. %s", strerror(errno));
exit(-2);