diff --git a/README.md b/README.md index de45402..065d557 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ # n2n +NOTE: edge with `--persistent` flag will make the Linux TUNTAP device persistent, this is useful for routing. + n2n is a light VPN software which makes it easy to create virtual networks bypassing intermediate firewalls. In order to start using n2n, two elements are required: diff --git a/include/n2n_typedefs.h b/include/n2n_typedefs.h index 3ba65f2..b3204c2 100644 --- a/include/n2n_typedefs.h +++ b/include/n2n_typedefs.h @@ -222,6 +222,7 @@ typedef struct tuntap_dev { uint32_t device_mask; uint16_t mtu; char dev_name[N2N_IFNAMSIZ]; + int persistent; } tuntap_dev; #define SOCKET int @@ -676,6 +677,7 @@ typedef struct n2n_edge_conf { uint8_t sn_selection_strategy; /**< encodes currently chosen supernode selection strategy. */ uint8_t number_max_sn_pings; /**< Number of maximum concurrently allowed supernode pings. */ uint64_t mgmt_password_hash; /**< contains hash of managament port password. */ + uint8_t persistent; /**< Persistent TUNTAP */ } n2n_edge_conf_t; diff --git a/src/edge.c b/src/edge.c index 6ccdd28..cb53c39 100644 --- a/src/edge.c +++ b/src/edge.c @@ -305,6 +305,7 @@ static void help (int level) { " | '-m 10:20:30:40:50:60', random otherwise\n"); #if defined(N2N_CAN_NAME_IFACE) printf(" -d | TAP device name\n"); + printf(" --persistent | Persistent TAP device\n"); #endif printf(" -M | specify n2n MTU of TAP interface, default %d\n", DEFAULT_MTU); printf(" -r | enable packet forwarding through n2n community\n"); @@ -568,6 +569,11 @@ static int setOption (int optkey, char *optargument, n2n_tuntap_priv_config_t *e ec->tuntap_dev_name[N2N_IFNAMSIZ - 1] = '\0'; break; } + case '$': /* persistent TUNTAP */ { + traceEvent(TRACE_NORMAL, "persistent TUNTAP"); + conf->persistent = 1; + break; + } #endif case 'I': /* Device Description (hint) or username */ { strncpy((char *)conf->dev_desc, optargument, N2N_DESC_SIZE); @@ -807,6 +813,7 @@ static const struct option long_options[] = { "help", no_argument, NULL, '@' }, /* internal special character '@' to identify long help case */ { "select-rtt", no_argument, NULL, '[' }, /* '[' rtt selection strategy */ { "select-mac", no_argument, NULL, ']' }, /* ']' mac selection strategy */ + { "persistent", no_argument, NULL, '$'}, /* '$' persistent tap device */ { "management-password", required_argument, NULL, '{' }, /* '{' management port password */ { NULL, 0, NULL, 0 } }; @@ -1109,6 +1116,7 @@ int main (int argc, char* argv[]) { if(setuid(0) != 0) traceEvent(TRACE_ERROR, "unable to become root [%u/%s]", errno, strerror(errno)); /* setgid(0); */ + tuntap.persistent = conf.persistent; #endif if(conf.encrypt_key && !strcmp((char*)conf.community_name, conf.encrypt_key)) diff --git a/src/tuntap_linux.c b/src/tuntap_linux.c index cc23fac..3a5b16b 100644 --- a/src/tuntap_linux.c +++ b/src/tuntap_linux.c @@ -138,6 +138,14 @@ int tuntap_open (tuntap_dev *device, return -1; } + // persistent + rc = ioctl(device->fd, TUNSETPERSIST, device->persistent); + if (rc < 0) { + traceEvent(TRACE_ERROR, "tuntap ioctl(TUNSETPERSIST, IFF_TAP) error: %s[%d]\n", strerror(errno), rc); + close(device->fd); + return -1; + } + // store the device name for later reuse strncpy(device->dev_name, ifr.ifr_name, MIN(IFNAMSIZ, N2N_IFNAMSIZ)); @@ -251,7 +259,6 @@ int tuntap_write (struct tuntap_dev *tuntap, unsigned char *buf, int len) { void tuntap_close (struct tuntap_dev *tuntap) { - close(tuntap->fd); }