Make DeviceStandby control network interface link status on Windows.
authorEtienne Dechamps <etienne@edechamps.fr>
Sun, 22 Jun 2014 09:48:34 +0000 (10:48 +0100)
committerEtienne Dechamps <etienne@edechamps.fr>
Sun, 22 Jun 2014 14:04:15 +0000 (15:04 +0100)
Besides controlling when tinc-up and tinc-down get called, this commit makes
DeviceStandby control when the virtual network interface "cable" is "plugged"
on Windows. This is more user-friendly as the status of the tinc network can
be seen just by looking at the state of the network interface, and it makes
Windows behave better when isolated.

doc/tinc.conf.5.in
src/device.h
src/mingw/device.c
src/net_setup.c

index 5fee403..7e066bb 100644 (file)
@@ -199,6 +199,7 @@ When disabled,
 calls tinc-up on startup, and tinc-down on shutdown. When enabled,
 .Nm tinc
 will only call tinc-up when at least one node is reachable, and will call tinc-down as soon as no nodes are reachable.
+On Windows, this also determines when the virtual network interface "cable" is "plugged".
 .It Va DeviceType Li = Ar type Pq platform dependent
 The type of the virtual network device.
 Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used.
index 85112ff..ad91a0e 100644 (file)
@@ -37,6 +37,8 @@ typedef struct devops_t {
        void (*close)(void);
        bool (*read)(struct vpn_packet_t *);
        bool (*write)(struct vpn_packet_t *);
+       void (*enable)(void);   /* optional */
+       void (*disable)(void);  /* optional */
 } devops_t;
 
 extern const devops_t os_devops;
index 85c0c7b..a765ce3 100644 (file)
@@ -94,7 +94,6 @@ static bool setup_device(void) {
        char adaptername[1024];
        char tapname[1024];
        DWORD len;
-       unsigned long status;
 
        bool found = false;
 
@@ -200,11 +199,6 @@ static bool setup_device(void) {
                return false;
        }
 
-       /* Set media status for newer TAP-Win32 devices */
-
-       status = true;
-       DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL);
-
        device_info = "Windows tap device";
 
        logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
@@ -212,6 +206,20 @@ static bool setup_device(void) {
        return true;
 }
 
+static void enable_device(void) {
+       logger(DEBUG_ALWAYS, LOG_INFO, "Enabling %s", device_info);
+       ULONG status = 1;
+       DWORD len;
+       DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL);
+}
+
+static void disable_device(void) {
+       logger(DEBUG_ALWAYS, LOG_INFO, "Disabling %s", device_info);
+       ULONG status = 0;
+       DWORD len;
+       DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof status, &status, sizeof status, &len, NULL);
+}
+
 static void close_device(void) {
        CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE;
 
@@ -246,4 +254,6 @@ const devops_t os_devops = {
        .close = close_device,
        .read = read_packet,
        .write = write_packet,
+       .enable = enable_device,
+       .disable = disable_device,
 };
index 8c04d00..eec1711 100644 (file)
@@ -728,6 +728,9 @@ static bool add_listen_address(char *address, bool bindto) {
 }
 
 void device_enable(void) {
+       if (devops.enable)
+               devops.enable();
+
        /* Run tinc-up script to further initialize the tap interface */
 
        char *envp[5] = {NULL};
@@ -753,6 +756,9 @@ void device_disable(void) {
 
        for(int i = 0; i < 4; i++)
                free(envp[i]);
+
+       if (devops.disable)
+               devops.disable();
 }
 
 /*