Make DeviceStandby control network interface link status on Windows.
[tinc] / src / mingw / device.c
index 0e748f8..a765ce3 100644 (file)
@@ -1,7 +1,7 @@
 /*
     device.c -- Interaction with Windows tap driver in a MinGW environment
     Copyright (C) 2002-2005 Ivo Timmermans,
-                  2002-2014 Guus Sliepen <guus@tinc-vpn.org>
+                  2002-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -40,6 +40,9 @@ char *device = NULL;
 char *iface = NULL;
 static char *device_info = NULL;
 
+static uint64_t device_total_in = 0;
+static uint64_t device_total_out = 0;
+
 extern char *myport;
 
 static DWORD WINAPI tapreader(void *bla) {
@@ -47,7 +50,6 @@ static DWORD WINAPI tapreader(void *bla) {
        DWORD len;
        OVERLAPPED overlapped;
        vpn_packet_t packet;
-       int errors;
 
        logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader running");
 
@@ -70,22 +72,13 @@ static DWORD WINAPI tapreader(void *bla) {
                        } else {
                                logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
                                           device, strerror(errno));
-                               errors++;
-                               if(errors >= 10) {
-                                       EnterCriticalSection(&mutex);
-                                       running = false;
-                                       LeaveCriticalSection(&mutex);
-                               }
-                               usleep(1000000);
-                               continue;
+                               return -1;
                        }
                }
 
-               errors = 0;
+               EnterCriticalSection(&mutex);
                packet.len = len;
                packet.priority = 0;
-
-               EnterCriticalSection(&mutex);
                route(myself, &packet);
                event_flush_output();
                LeaveCriticalSection(&mutex);
@@ -101,7 +94,6 @@ static bool setup_device(void) {
        char adaptername[1024];
        char tapname[1024];
        DWORD len;
-       unsigned long status;
 
        bool found = false;
 
@@ -207,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);
@@ -219,11 +206,26 @@ 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);
+       CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE;
 
-       free(device);
-       free(iface);
+       free(device); device = NULL;
+       free(iface); iface = NULL;
+       device_info = NULL;
 }
 
 static bool read_packet(vpn_packet_t *packet) {
@@ -242,6 +244,8 @@ static bool write_packet(vpn_packet_t *packet) {
                return false;
        }
 
+       device_total_out += packet->len;
+
        return true;
 }
 
@@ -250,4 +254,6 @@ const devops_t os_devops = {
        .close = close_device,
        .read = read_packet,
        .write = write_packet,
+       .enable = enable_device,
+       .disable = disable_device,
 };