diff --git a/include/n2n_typedefs.h b/include/n2n_typedefs.h index 44b6daf..3bb417e 100644 --- a/include/n2n_typedefs.h +++ b/include/n2n_typedefs.h @@ -599,6 +599,7 @@ typedef struct n2n_edge_conf { int mgmt_port; n2n_auth_t auth; filter_rule_t *network_traffic_filter_rules; + int metric; /**< Network interface metric (Windows only). */ } n2n_edge_conf_t; diff --git a/src/edge.c b/src/edge.c index 898c287..da38b81 100644 --- a/src/edge.c +++ b/src/edge.c @@ -182,6 +182,9 @@ static void help (int level) { "[-I ] " "\n " "[-R ] " +#ifdef WIN32 + "[-x ] " +#endif "\n\n local options " #ifndef WIN32 "[-f] " @@ -275,6 +278,10 @@ static void help (int level) { printf(" | rule format: 'src_ip/n:[s_port,e_port],...\n" " | |on same| ...dst_ip/n:[s_port,e_port],...\n" " | | line | ...TCP+/-,UDP+/-,ICMP+/-'\n"); +#ifdef WIN32 + printf(" -x | set TAP interface metric, defaults to 0 (auto),\n" + " | e.g. set to 1 for better multiplayer game detection\n"); +#endif printf ("\n"); printf (" LOCAL OPTIONS\n"); printf (" -------------\n\n"); @@ -617,7 +624,13 @@ static int setOption (int optkey, char *optargument, n2n_tuntap_priv_config_t *e } break; } - +#ifdef WIN32 + case 'x': { + conf->metric = atoi(optargument); + ec->metric = atoi(optargument); + break; + } +#endif default: { traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored", (char)optkey); return(-1); @@ -653,6 +666,9 @@ static int loadFromCLI (int argc, char *argv[], n2n_edge_conf_t *conf, n2n_tunta "k:a:bc:Eu:g:m:M:s:d:l:p:fvhrt:i:I:SDL:z::A::Hn:R:" #ifdef __linux__ "T:" +#endif +#ifdef WIN32 + "x:" #endif , long_options, NULL)) != '?') { @@ -848,6 +864,7 @@ int main (int argc, char* argv[]) { #ifdef WIN32 ec.tuntap_dev_name[0] = '\0'; + ec.metric = 0; #else snprintf(ec.tuntap_dev_name, sizeof(ec.tuntap_dev_name), N2N_EDGE_DEFAULT_DEV_NAME); #endif @@ -1015,6 +1032,9 @@ int main (int argc, char* argv[]) { } if(runlevel == 4) { /* configure the TUNTAP device */ +#ifdef WIN32 + tuntap.metric = eee->tuntap_priv_conf.metric; +#endif if(tuntap_open(&tuntap, eee->tuntap_priv_conf.tuntap_dev_name, eee->tuntap_priv_conf.ip_mode, eee->tuntap_priv_conf.ip_addr, eee->tuntap_priv_conf.netmask, eee->tuntap_priv_conf.device_mac, eee->tuntap_priv_conf.mtu) < 0) diff --git a/src/edge_utils.c b/src/edge_utils.c index bf28977..878f99b 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -2964,6 +2964,8 @@ void edge_init_conf_defaults (n2n_edge_conf_t *conf) { conf->encrypt_key = strdup(getenv("N2N_KEY")); conf->transop_id = N2N_TRANSFORM_ID_AES; } + + conf->metric = 0; } /* ************************************** */ diff --git a/win32/n2n_win32.h b/win32/n2n_win32.h index f8b3a5a..1630372 100644 --- a/win32/n2n_win32.h +++ b/win32/n2n_win32.h @@ -74,6 +74,7 @@ typedef struct tuntap_dev { uint32_t ip_addr; uint32_t device_mask; unsigned int mtu; + unsigned int metric; } tuntap_dev; #define index(a, b) strchr(a, b) diff --git a/win32/wintap.c b/win32/wintap.c index 7a50b58..719f375 100644 --- a/win32/wintap.c +++ b/win32/wintap.c @@ -299,14 +299,14 @@ int open_wintap(struct tuntap_dev *device, /* ****************** */ - /* MTU */ + /* MTU and network metric */ _snprintf(cmd, sizeof(cmd), - "netsh interface ipv4 set subinterface \"%s\" mtu=%d store=persistent > nul", - device->ifName, mtu); + "netsh interface ipv4 set subinterface \"%s\" mtu=%d metric=%d store=persistent > nul", + device->ifName, mtu, device->metric); if(system(cmd) != 0) - printf("WARNING: Unable to set device %s MTU [%s]\n", - device->ifName, cmd); + printf("WARNING: Unable to set device %s parameters MTU=%d metric=%d store=persistent [%s]\n", + device->ifName, mtu, device->metric, cmd); /* set driver media status to 'connected' (i.e. set the interface up) */ if (!DeviceIoControl (device->device_handle, TAP_IOCTL_SET_MEDIA_STATUS,