Browse Source

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

pull/754/head
Logan oos Even 3 years ago
committed by GitHub
parent
commit
c21accc2a1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      edge.8
  2. 2
      include/n2n.h
  3. 1
      include/n2n_typedefs.h
  4. 21
      src/edge.c
  5. 8
      src/edge_utils.c
  6. 4
      src/example_sn_embed.c
  7. 11
      src/n2n.c
  8. 6
      src/sn.c

4
edge.8

@ -40,6 +40,10 @@ 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\-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 \fB\-S1\fR ... \fB\-S2\fR
do not connect p2p, always use the supernode, do not connect p2p, always use the supernode,
\-S1 = via UDP, \-S2 = via TCP \-S1 = via UDP, \-S2 = via TCP

2
include/n2n.h

@ -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, char* sock_to_cstr (n2n_sock_str_t out,
const n2n_sock_t * sock); const n2n_sock_t * sock);
char * ip_subnet_to_str (dec_ip_bit_str_t buf, const n2n_ip_subnet_t *ipaddr); 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, int sock_equal (const n2n_sock_t * a,
const n2n_sock_t * b); const n2n_sock_t * b);

1
include/n2n_typedefs.h

@ -646,6 +646,7 @@ typedef struct n2n_edge_conf {
char *encrypt_key; char *encrypt_key;
int register_interval; /**< Interval for supernode registration, also used for UDP NAT hole punching. */ 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. */ 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 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 */

21
src/edge.c

@ -177,7 +177,7 @@ static void help (int level) {
"[-H] " "[-H] "
"[-z<compression>]" "[-z<compression>]"
"\n " "\n "
"[-S<level of solitude>]" "[-b <bind IP address>][-S<level of solitude>]"
"\n\n tap device and " "\n\n tap device and "
"[-a [static:|dhcp:]<tap IP address>[/<cidr suffix>]] " "[-a [static:|dhcp:]<tap IP address>[/<cidr suffix>]] "
"\n overlay network " "\n overlay network "
@ -252,6 +252,8 @@ static void help (int level) {
printf(" -D | enable PMTU discovery, it can reduce fragmentation but\n" printf(" -D | enable PMTU discovery, it can reduce fragmentation but\n"
" | causes connections to stall if not properly supported\n"); " | causes connections to stall if not properly supported\n");
#endif #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" printf(" -S1 ... -S2 | do not connect p2p, always use the supernode,\n"
" | -S1 = via UDP" " | -S1 = via UDP"
@ -589,6 +591,20 @@ static int setOption (int optkey, char *optargument, n2n_tuntap_priv_config_t *e
break; 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': { case 't': {
conf->mgmt_port = atoi(optargument); conf->mgmt_port = atoi(optargument);
break; break;
@ -711,6 +727,7 @@ static const struct option long_options[] =
{ "tap-device", required_argument, NULL, 'd' }, { "tap-device", required_argument, NULL, 'd' },
{ "euid", required_argument, NULL, 'u' }, { "euid", required_argument, NULL, 'u' },
{ "egid", required_argument, NULL, 'g' }, { "egid", required_argument, NULL, 'g' },
{ "bind", required_argument, NULL, 'b' },
{ "help" , no_argument, NULL, '@' }, /* special character '@' to identify long help case */ { "help" , no_argument, NULL, '@' }, /* special character '@' to identify long help case */
{ "verbose", no_argument, NULL, 'v' }, { "verbose", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 } { 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; u_char c;
while ((c = getopt_long(argc, argv, 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__ #ifdef __linux__
"T:" "T:"
#endif #endif

8
src/edge_utils.c

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

4
src/example_sn_embed.c

@ -29,12 +29,12 @@ int main () {
sss_node.daemon = 0; // Whether to daemonize sss_node.daemon = 0; // Whether to daemonize
sss_node.lport = 1234; // Main UDP listen port 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) { if(-1 == sss_node.sock) {
exit(-2); 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) { if(-1 == sss_node.mgmt_sock) {
exit(-2); exit(-2);
} }

11
src/n2n.c

@ -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; SOCKET sock_fd;
struct sockaddr_in local_address; 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)); memset(&local_address, 0, sizeof(local_address));
local_address.sin_family = AF_INET; local_address.sin_family = AF_INET;
local_address.sin_port = htons(local_port); 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) { 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)); traceEvent(TRACE_ERROR, "Bind error on local port %u [%s]\n", local_port, strerror(errno));

6
src/sn.c

@ -577,7 +577,7 @@ int main (int argc, char * const argv[]) {
traceEvent(TRACE_DEBUG, "traceLevel is %d", getTraceLevel()); 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) { if(-1 == sss_node.sock) {
traceEvent(TRACE_ERROR, "Failed to open main socket. %s", strerror(errno)); traceEvent(TRACE_ERROR, "Failed to open main socket. %s", strerror(errno));
exit(-2); exit(-2);
@ -586,7 +586,7 @@ int main (int argc, char * const argv[]) {
} }
#ifdef N2N_HAVE_TCP #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) { if(-1 == sss_node.tcp_sock) {
traceEvent(TRACE_ERROR, "Failed to open auxiliary TCP socket. %s", strerror(errno)); traceEvent(TRACE_ERROR, "Failed to open auxiliary TCP socket. %s", strerror(errno));
exit(-2); exit(-2);
@ -602,7 +602,7 @@ int main (int argc, char * const argv[]) {
} }
#endif #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) { if(-1 == sss_node.mgmt_sock) {
traceEvent(TRACE_ERROR, "Failed to open management socket. %s", strerror(errno)); traceEvent(TRACE_ERROR, "Failed to open management socket. %s", strerror(errno));
exit(-2); exit(-2);

Loading…
Cancel
Save