Browse Source

Add the -i option to specify registration interval on edge nodes

Registration is bound to UDP NAT hole punching, so the edges should choose their own value.
pull/110/head
emanuele-f 6 years ago
parent
commit
d5387945b4
  1. 20
      doc/HACKING
  2. 6
      edge.8
  3. 11
      edge.c
  4. 28
      edge_utils.c
  5. 1
      n2n.h

20
doc/HACKING

@ -35,10 +35,22 @@ socket to which the initiating UDP packets were sent. This means that when an
inside host sends UDP to some outside socket; other hosts cannot piggyback on inside host sends UDP to some outside socket; other hosts cannot piggyback on
this opening in the firewall to send data to the inside host. this opening in the firewall to send data to the inside host.
When two inside hosts are both behind symmetric NAT, peer-to-peer packet For example, an asymmetric NAT would keep the mapping:
exchange is not possible via n2n. These hosts will require the supernode to <UDP,ExtPort> -> <IntIP, IntPort>
relay packets. and would redirect all the packets on external port ExtPort to the internal host
regardless of the remote IP.
Whereas a symmetric NAT would keep the mapping:
<UDP,RemoteIP,ExtPort> -> <IntIP, IntPort>
so only RemoteIP can send packets to the internal host. RemoteIP is the supernode
IP in case of n2n, to which the internal host has registered.
In n2n, P2P can work monodirecitonally if only one of the two peers is behind a symmetric
NAT. For example, if A is behind symmetric NAT and B is behind asymmetric NAT
- A->B packets are P2P (will have the B public IP as destination)
- B->A packets must go through the supernode
If both the peers are behind symmetric NAT, then no P2P communication is possible.
ARP CACHE ARP CACHE
--------- ---------

6
edge.8

@ -39,6 +39,12 @@ truncated to take the first 16 bytes.
\-h \-h
write usage then exit. write usage then exit.
.TP .TP
\-i <register_interval>
Supernode registration interval. It specifies the interval in seconds
between consecutive REGISTER_SUPER packets and it's used to keep NAT hole
open via the UDP NAT hole punching technique. This only works for asymmetric
NATs and allows for P2P communication.
.TP
\-k <keystring> \-k <keystring>
sets the twofish encryption key from ASCII text (see also N2N_KEY in sets the twofish encryption key from ASCII text (see also N2N_KEY in
ENVIRONMENT). All edges communicating must use the same key and community ENVIRONMENT). All edges communicating must use the same key and community

11
edge.c

@ -120,7 +120,7 @@ static void help() {
#endif /* #if defined(N2N_CAN_NAME_IFACE) */ #endif /* #if defined(N2N_CAN_NAME_IFACE) */
"-a [static:|dhcp:]<tun IP address> " "-a [static:|dhcp:]<tun IP address> "
"-c <community> " "-c <community> "
"[-k <encrypt key> | -K <key file>]\n" "[-k <encrypt key>]\n"
" " " "
"[-s <netmask>] " "[-s <netmask>] "
#ifndef WIN32 #ifndef WIN32
@ -134,7 +134,7 @@ static void help() {
"-l <supernode host:port>\n" "-l <supernode host:port>\n"
" " " "
"[-p <local port>] [-M <mtu>] " "[-p <local port>] [-M <mtu>] "
"[-r] [-E] [-v] [-t <mgmt port>] [-b] [-A] [-h]\n\n"); "[-r] [-E] [-v] [-i <reg_interval>] [-t <mgmt port>] [-b] [-A] [-h]\n\n");
#ifdef __linux__ #ifdef __linux__
printf("-d <tun device> | tun device name\n"); printf("-d <tun device> | tun device name\n");
@ -145,6 +145,7 @@ static void help() {
printf("-k <encrypt key> | Encryption key (ASCII) - also N2N_KEY=<encrypt key>.\n"); printf("-k <encrypt key> | Encryption key (ASCII) - also N2N_KEY=<encrypt key>.\n");
printf("-s <netmask> | Edge interface netmask in dotted decimal notation (255.255.255.0).\n"); printf("-s <netmask> | Edge interface netmask in dotted decimal notation (255.255.255.0).\n");
printf("-l <supernode host:port> | Supernode IP:port\n"); printf("-l <supernode host:port> | Supernode IP:port\n");
printf("-i <reg_interval> | Registration interval, for NAT hole punching (default 20 seconds)\n");
printf("-b | Periodically resolve supernode IP\n"); printf("-b | Periodically resolve supernode IP\n");
printf(" | (when supernodes are running on dynamic IPs)\n"); printf(" | (when supernodes are running on dynamic IPs)\n");
printf("-p <local port> | Fixed local UDP port.\n"); printf("-p <local port> | Fixed local UDP port.\n");
@ -265,6 +266,10 @@ static int setOption(int optkey, char *optargument, n2n_priv_config_t *ec, n2n_e
break; break;
} }
case 'i': /* supernode registration interval */
conf->register_interval = atoi(optarg);
break;
#if defined(N2N_CAN_NAME_IFACE) #if defined(N2N_CAN_NAME_IFACE)
case 'd': /* TUNTAP name */ case 'd': /* TUNTAP name */
{ {
@ -341,7 +346,7 @@ static int loadFromCLI(int argc, char *argv[], n2n_edge_conf_t *conf, n2n_priv_c
u_char c; u_char c;
while((c = getopt_long(argc, argv, while((c = getopt_long(argc, argv,
"K:k:a:bc:Eu:g:m:M:s:d:l:p:fvhrt:" "K:k:a:bc:Eu:g:m:M:s:d:l:p:fvhrt:i:"
#ifdef N2N_HAVE_AES #ifdef N2N_HAVE_AES
"A" "A"
#endif #endif

28
edge_utils.c

@ -28,16 +28,9 @@
#include <tun2tap/tun2tap.h> #include <tun2tap/tun2tap.h>
#endif /* __ANDROID_NDK__ */ #endif /* __ANDROID_NDK__ */
#if defined(DEBUG)
#define SOCKET_TIMEOUT_INTERVAL_SECS 5
#define REGISTER_SUPER_INTERVAL_DFL 20 /* sec */
#else /* #if defined(DEBUG) */
#define SOCKET_TIMEOUT_INTERVAL_SECS 10
#define REGISTER_SUPER_INTERVAL_DFL 60 /* sec */
#endif /* #if defined(DEBUG) */
#define REGISTER_SUPER_INTERVAL_MIN 5 /* sec */ #define SOCKET_TIMEOUT_INTERVAL_SECS 10
#define REGISTER_SUPER_INTERVAL_MAX 3600 /* sec */ #define REGISTER_SUPER_INTERVAL_DFL 20 /* sec, usually UDP NAT entries in a firewall expire after 30 seconds */
#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */ #define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */
#define TRANSOP_TICK_INTERVAL (10) /* sec */ #define TRANSOP_TICK_INTERVAL (10) /* sec */
@ -75,6 +68,9 @@ int edge_verify_conf(const n2n_edge_conf_t *conf) {
if(conf->sn_num == 0) if(conf->sn_num == 0)
return(-2); return(-2);
if(conf->register_interval < 1)
return(-3);
return(0); return(0);
} }
@ -104,7 +100,6 @@ struct n2n_edge {
/* Timers */ /* Timers */
time_t last_register_req; /**< Check if time to re-register with super*/ time_t last_register_req; /**< Check if time to re-register with super*/
size_t register_lifetime; /**< Time distance after last_register_req at which to re-register. */
time_t last_p2p; /**< Last time p2p traffic was received. */ time_t last_p2p; /**< Last time p2p traffic was received. */
time_t last_sup; /**< Last time a packet arrived from supernode. */ time_t last_sup; /**< Last time a packet arrived from supernode. */
time_t start_time; /**< For calculating uptime */ time_t start_time; /**< For calculating uptime */
@ -151,7 +146,6 @@ n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *r
eee->known_peers = NULL; eee->known_peers = NULL;
eee->pending_peers = NULL; eee->pending_peers = NULL;
eee->register_lifetime = REGISTER_SUPER_INTERVAL_DFL;
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS;
#ifdef NOT_USED #ifdef NOT_USED
@ -673,10 +667,10 @@ static void send_register_ack(n2n_edge_t * eee,
static void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) { static void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) {
u_int sn_idx; u_int sn_idx;
if(eee->sn_wait && (nowTime > (eee->last_register_req + (eee->register_lifetime/10)))) { if(eee->sn_wait && (nowTime > (eee->last_register_req + (eee->conf.register_interval/10)))) {
/* fall through */ /* fall through */
traceEvent(TRACE_DEBUG, "update_supernode_reg: doing fast retry."); traceEvent(TRACE_DEBUG, "update_supernode_reg: doing fast retry.");
} else if(nowTime < (eee->last_register_req + eee->register_lifetime)) } else if(nowTime < (eee->last_register_req + eee->conf.register_interval))
return; /* Too early */ return; /* Too early */
if(0 == eee->sup_attempts) { if(0 == eee->sup_attempts) {
@ -1403,10 +1397,9 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
eee->sn_wait=0; eee->sn_wait=0;
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */ eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */
/* REVISIT: store sn_back */ /* NOTE: the register_interval should be chosen by the edge node
eee->register_lifetime = ra.lifetime; * based on its NAT configuration. */
eee->register_lifetime = MAX(eee->register_lifetime, REGISTER_SUPER_INTERVAL_MIN); //eee->conf.register_interval = ra.lifetime;
eee->register_lifetime = MIN(eee->register_lifetime, REGISTER_SUPER_INTERVAL_MAX);
} }
else else
{ {
@ -1639,6 +1632,7 @@ void edge_init_conf_defaults(n2n_edge_conf_t *conf) {
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_TWOFISH; /* use twofish for compatibility */ conf->transop_id = N2N_TRANSFORM_ID_TWOFISH; /* use twofish for compatibility */
conf->drop_multicast = 1; conf->drop_multicast = 1;
conf->register_interval = REGISTER_SUPER_INTERVAL_DFL;
if(getenv("N2N_KEY")) if(getenv("N2N_KEY"))
conf->encrypt_key = strdup(getenv("N2N_KEY")); conf->encrypt_key = strdup(getenv("N2N_KEY"));

1
n2n.h

@ -193,6 +193,7 @@ typedef struct n2n_edge_conf {
uint8_t drop_multicast; /**< Multicast ethernet addresses. */ uint8_t drop_multicast; /**< Multicast ethernet addresses. */
uint8_t sn_num; /**< Number of supernode addresses defined. */ uint8_t sn_num; /**< Number of supernode addresses defined. */
char *encrypt_key; char *encrypt_key;
int register_interval; /**< Interval for supernode registration, also used for UDP NAT hole punching. */
int local_port; int local_port;
int mgmt_port; int mgmt_port;
} n2n_edge_conf_t; } n2n_edge_conf_t;

Loading…
Cancel
Save