]> tinc-vpn.org Git - tinc/commitdiff
Replace MinGW with Windows to avoid ambiguities
authorKirill Isakov <bootctl@gmail.com>
Fri, 25 Mar 2022 17:29:07 +0000 (23:29 +0600)
committerKirill Isakov <bootctl@gmail.com>
Mon, 28 Mar 2022 15:38:29 +0000 (21:38 +0600)
36 files changed:
.ci/tidy/run.sh
src/control.c
src/dropin.c
src/dropin.h
src/event.c
src/event.h
src/fsck.c
src/have.h
src/ifconfig.c
src/invitation.c
src/keys.c
src/logger.c
src/logger.h
src/meson.build
src/mingw/common.h [deleted file]
src/mingw/device.c [deleted file]
src/mingw/meson.build [deleted file]
src/names.c
src/net.c
src/net.h
src/net_socket.c
src/nolegacy/crypto.c
src/openssl/crypto.c
src/process.c
src/process.h
src/script.c
src/sptps_test.c
src/tincctl.c
src/tincd.c
src/utils.c
src/utils.h
src/windows/common.h [new file with mode: 0644]
src/windows/device.c [new file with mode: 0644]
src/windows/meson.build [new file with mode: 0644]
src/xalloc.h
test/integration/splice.c

index 36700a2ef199d40ef39bfbc6de3888d21c7f89e8..bb975868a93f4bb17c3696f03952c54bc46a00c4 100755 (executable)
@@ -5,7 +5,7 @@ set -eu
 ./.ci/build.sh "$@"
 
 # Which paths to ignore.
-paths='src/solaris src/mingw src/gcrypt'
+paths='src/solaris src/windows src/gcrypt'
 
 case "$(uname -s)" in
 Linux)
index 175f2bd019f66771350086e560eb0f7d1e26713d..86e0f68a11cb358ae10a21a2f122ee323e7594de 100644 (file)
@@ -185,7 +185,7 @@ bool init_control(void) {
        free(localhost);
        fclose(f);
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0);
 
        if(unix_fd < 0) {
@@ -232,7 +232,7 @@ bool init_control(void) {
 }
 
 void exit_control(void) {
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        unlink(unixsocketname);
        io_del(&unix_socket);
        close(unix_socket.fd);
index 1489ee6c2949271f2acd8379a8af690449ca238b..d086ae1814dfdc3150744165f5b45991f9543a15 100644 (file)
@@ -130,7 +130,7 @@ int vasprintf(char **buf, const char *fmt, va_list ap) {
 
 #ifndef HAVE_GETTIMEOFDAY
 int gettimeofday(struct timeval *tv, void *tz) {
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        FILETIME ft;
        GetSystemTimeAsFileTime(&ft);
        uint64_t lt = (uint64_t)ft.dwLowDateTime | ((uint64_t)ft.dwHighDateTime << 32);
index 9b196b6d31c9423e535b1e3d51517abec1226c70..a1fb6c1b062e82ba57b400f888af8bf2211f9764 100644 (file)
@@ -52,7 +52,7 @@ extern int gettimeofday(struct timeval *, void *);
        } while (0)
 #endif
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 #define mkdir(a, b) mkdir(a)
 #ifndef SHUT_RDWR
 #define SHUT_RDWR SD_BOTH
index 5d0bcef0b265c6067157e2674b18a07f8d647e70..2710a8b85883035da99b6f08209ac87834e933e7 100644 (file)
@@ -30,7 +30,7 @@
 #include "net.h"
 
 struct timeval now;
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 
 #ifdef HAVE_SYS_EPOLL_H
 static int epollset = 0;
@@ -58,7 +58,7 @@ static inline int event_epoll_init(void) {
 #endif
 
 static int io_compare(const io_t *a, const io_t *b) {
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        return a->fd - b->fd;
 #else
 
@@ -114,7 +114,7 @@ void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) {
        }
 
        io->fd = fd;
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if(io->fd != -1) {
                io->event = WSACreateEvent();
@@ -141,7 +141,7 @@ void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) {
 #endif
 }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) {
        io->event = event;
        io_add(io, cb, data, -1, 0);
@@ -167,7 +167,7 @@ void io_set(io_t *io, int flags) {
                return;
        }
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 #ifdef HAVE_SYS_EPOLL_H
        epoll_ctl(epollset, EPOLL_CTL_DEL, io->fd, NULL);
 
@@ -230,7 +230,7 @@ void io_del(io_t *io) {
        }
 
        io_set(io, 0);
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if(io->fd != -1 && WSACloseEvent(io->event) == FALSE) {
                abort();
@@ -281,7 +281,7 @@ void timeout_del(timeout_t *timeout) {
        };
 }
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 
 // From Matz's Ruby
 #ifndef NSIG
@@ -379,7 +379,7 @@ static struct timeval *timeout_execute(struct timeval *diff) {
 bool event_loop(void) {
        running = true;
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 
 #ifdef HAVE_SYS_EPOLL_H
 
index d0f19118a33a094bd47682c8d9ccd8d2fdf51bfb..70d86f510f30a57f3698e3acc98011ed43ad05d5 100644 (file)
@@ -33,7 +33,7 @@ typedef void (*signal_cb_t)(void *data);
 typedef struct io_t {
        int fd;
        int flags;
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        WSAEVENT event;
 #endif
        io_cb_t cb;
@@ -57,7 +57,7 @@ typedef struct signal_t {
 extern struct timeval now;
 
 extern void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags);
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 extern void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event);
 #endif
 extern void io_del(io_t *io);
index fdd584e7e6ec1b424af41eee673eaea5f450f5e3..e7262727e67e85e5a328a65a65fcf034febe6bf1 100644 (file)
@@ -185,7 +185,7 @@ static void check_conffile(const char *nodename, bool server) {
        splay_empty_tree(&config);
 }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 typedef int uid_t;
 
 static uid_t getuid(void) {
@@ -219,7 +219,7 @@ static void check_key_file_mode(const char *fname) {
                }
        }
 }
-#endif // HAVE_MINGW
+#endif // HAVE_WINDOWS
 
 static char *read_node_name(void) {
        if(access(tinc_conf, R_OK) == 0) {
index f19c599288cc9bc7b100cf1980bb80efa9169653..36d17b6096d3cca7dbe65c68d70131d785c7d8c6 100644 (file)
@@ -21,7 +21,7 @@
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 #define WINVER 0x0600
 #define _WIN32_WINNT 0x0600
 #define WIN32_LEAN_AND_MEAN
@@ -51,7 +51,7 @@
 #define alloca(size) __builtin_alloca(size)
 #endif
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 #ifdef HAVE_W32API_H
 #include <w32api.h>
 #endif
@@ -65,7 +65,7 @@
 #include <process.h>
 #include <direct.h>
 #endif
-#endif // HAVE_MINGW
+#endif // HAVE_WINDOWS
 
 #ifdef HAVE_TERMIOS_H
 #include <termios.h>
 #undef STATUS
 #endif
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 #define SLASH "\\"
 #else
 #define SLASH "/"
index 59aa94c3815f1b85fae15de79630a61aa53248d6..f4ce313a482c197b83818616212931b09755dca0 100644 (file)
@@ -25,7 +25,7 @@
 
 static long start;
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 void ifconfig_header(FILE *out) {
        fprintf(out, "#!/bin/sh\n");
        start = ftell(out);
@@ -128,7 +128,7 @@ void ifconfig_address(FILE *out, const char *value) {
                return;
        }
 
-#elif defined(HAVE_MINGW)
+#elif defined(HAVE_WINDOWS)
 
        switch(address.type) {
        case SUBNET_MAC:
@@ -226,7 +226,7 @@ void ifconfig_route(FILE *out, const char *value) {
                }
        }
 
-#elif defined(HAVE_MINGW)
+#elif defined(HAVE_WINDOWS)
 
        if(*gateway_str) {
                switch(subnet.type) {
index d1e1e61d07cdf6ad830db6fb7f17fcf334d86ae1..22fd6146030b29cbb7d4e90f9bcec24da47535e8 100644 (file)
@@ -996,7 +996,7 @@ ask_netname:
        char filename2[PATH_MAX];
        snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up.invitation", confbase);
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        snprintf(filename2, sizeof(filename2), "%s" SLASH "tinc-up.bat", confbase);
 #else
        snprintf(filename2, sizeof(filename2), "%s" SLASH "tinc-up", confbase);
@@ -1028,7 +1028,7 @@ ask_netname:
 
                                if(response == 'e') {
                                        char *command;
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
                                        const char *editor = getenv("VISUAL");
 
                                        if(!editor) {
@@ -1358,7 +1358,7 @@ next:
                                continue;
                        }
 
-#if HAVE_MINGW
+#if HAVE_WINDOWS
 
                        // If socket has been shut down, recv() on Windows returns -1 and sets sockerrno
                        // to WSAESHUTDOWN, while on UNIX-like operating systems recv() returns 0, so we
index 5f93a5a976e97bc691818d8848e51c4a575b7a15..0485c761330119ac0975073ceb9c6c58e711eecb 100644 (file)
@@ -79,7 +79,7 @@ bool disable_old_keys(const char *filename, const char *what) {
                        return false;
                }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
                // We cannot atomically replace files on Windows.
                char bakfile[PATH_MAX] = "";
                snprintf(bakfile, sizeof(bakfile), "%s.bak", filename);
@@ -95,7 +95,7 @@ bool disable_old_keys(const char *filename, const char *what) {
                        return false;
                }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
                unlink(bakfile);
 #endif
                fprintf(stderr, "Warning: old key(s) found and disabled.\n");
@@ -128,7 +128,7 @@ ecdsa_t *read_ecdsa_private_key(splay_tree_t *config_tree, char **keyfile) {
                return NULL;
        }
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        struct stat s;
 
        if(fstat(fileno(fp), &s)) {
@@ -262,7 +262,7 @@ rsa_t *read_rsa_private_key(splay_tree_t *config_tree, char **keyfile) {
                return NULL;
        }
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        struct stat s;
 
        if(fstat(fileno(fp), &s)) {
index caaf038d3b350d679f0ad8b2a2652b2cff099aa9..390023bb8b7e62923b2e7730cacb4d557663da0f 100644 (file)
@@ -34,7 +34,7 @@ debug_t debug_level = DEBUG_NOTHING;
 static logmode_t logmode = LOGMODE_STDERR;
 static pid_t logpid;
 static FILE *logfile = NULL;
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 static HANDLE loghandle = NULL;
 #endif
 static const char *logident = NULL;
@@ -72,7 +72,7 @@ static void real_logger(debug_t level, int priority, const char *message) {
                        break;
 
                case LOGMODE_SYSLOG:
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
                        {
                                const char *messages[] = {message};
                                ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL);
@@ -195,7 +195,7 @@ void openlogger(const char *ident, logmode_t mode) {
                break;
 
        case LOGMODE_SYSLOG:
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
                loghandle = RegisterEventSource(NULL, logident);
 
                if(!loghandle) {
@@ -248,7 +248,7 @@ void closelogger(void) {
                break;
 
        case LOGMODE_SYSLOG:
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
                DeregisterEventSource(loghandle);
                break;
 #else
index 5302582b1a1b93d4acb0cc63a664129a95c1ef7c..e8e9a576a47517a404c867fbc78f54624a66c8c0 100644 (file)
@@ -44,7 +44,7 @@ typedef enum logmode_t {
        LOGMODE_SYSLOG
 } logmode_t;
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 #define LOG_EMERG EVENTLOG_ERROR_TYPE
 #define LOG_ALERT EVENTLOG_ERROR_TYPE
 #define LOG_CRIT EVENTLOG_ERROR_TYPE
index 92f42fa5c3810e3bbceebf9ba8067d754daa90a4..e37c2db0d4c38f648cf298ffdac9e232ec2bed26 100644 (file)
@@ -159,7 +159,7 @@ elif os_name.endswith('bsd') or os_name in ['dragonfly', 'darwin']
 elif os_name == 'sunos'
   subdir('solaris')
 elif os_name == 'windows'
-  subdir('mingw')
+  subdir('windows')
 endif
 
 foreach h : check_headers
@@ -228,9 +228,7 @@ if not opt_miniupnpc.disabled()
   endif
 endif
 
-if opt_curses.auto() and os_name == 'windows'
-  message('curses does not link under MinGW')
-else
+if not opt_curses.disabled()
   # The meta-dependency covers more alternatives, but is only available in 0.54+
   curses_name = meson_version.version_compare('>=0.54') ? 'curses' : 'ncurses'
   dep_curses = dependency(curses_name, required: opt_curses, static: static)
@@ -242,7 +240,7 @@ endif
 
 # Some distributions do not supply pkg-config files for readline
 if opt_readline.auto() and os_name == 'windows'
-  message('readline does not link under MinGW')
+  message('readline not available on Windows')
 else
   dep_readline = dependency('readline', required: opt_readline, static: static)
   if not dep_readline.found()
diff --git a/src/mingw/common.h b/src/mingw/common.h
deleted file mode 100644 (file)
index ff052c9..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef TINC_MINGW_COMMON_H
-#define TINC_MINGW_COMMON_H
-
-/*
- *  TAP-Win32 -- A kernel driver to provide virtual tap device functionality
- *               on Windows.  Originally derived from the CIPE-Win32
- *               project by Damion K. Wilson, with extensive modifications by
- *               James Yonan.
- *
- *  All source code which derives from the CIPE-Win32 project is
- *  Copyright (C) Damion K. Wilson, 2003, and is released under the
- *  GPL version 2 (see below).
- *
- *  All other source code is Copyright (C) James Yonan, 2003-2004,
- *  and is released under the GPL version 2 (see below).
- *
- *  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
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-//===============================================
-// This file is included both by OpenVPN and
-// the TAP-Win32 driver and contains definitions
-// common to both.
-//===============================================
-
-//=============
-// TAP IOCTLs
-//=============
-
-#define TAP_CONTROL_CODE(request,method) \
-       CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
-
-#define TAP_IOCTL_GET_MAC               TAP_CONTROL_CODE (1, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_VERSION           TAP_CONTROL_CODE (2, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_MTU               TAP_CONTROL_CODE (3, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_INFO              TAP_CONTROL_CODE (4, METHOD_BUFFERED)
-#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED)
-#define TAP_IOCTL_SET_MEDIA_STATUS      TAP_CONTROL_CODE (6, METHOD_BUFFERED)
-#define TAP_IOCTL_CONFIG_DHCP_MASQ      TAP_CONTROL_CODE (7, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_LOG_LINE          TAP_CONTROL_CODE (8, METHOD_BUFFERED)
-#define TAP_IOCTL_CONFIG_DHCP_SET_OPT   TAP_CONTROL_CODE (9, METHOD_BUFFERED)
-
-//=================
-// Registry keys
-//=================
-
-#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
-
-#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
-
-//======================
-// Filesystem prefixes
-//======================
-
-#define USERMODEDEVICEDIR "\\\\.\\Global\\"
-#define SYSDEVICEDIR      "\\Device\\"
-#define USERDEVICEDIR     "\\DosDevices\\Global\\"
-#define TAPSUFFIX         ".tap"
-
-//=========================================================
-// TAP_COMPONENT_ID -- This string defines the TAP driver
-// type -- different component IDs can reside in the system
-// simultaneously.
-//=========================================================
-
-#define TAP_COMPONENT_ID "tap0801"
-
-#endif
diff --git a/src/mingw/device.c b/src/mingw/device.c
deleted file mode 100644 (file)
index 03a1d48..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
-    device.c -- Interaction with Windows tap driver in a MinGW environment
-    Copyright (C) 2002-2005 Ivo Timmermans,
-                  2002-2022 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
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "../system.h"
-
-#include <windows.h>
-#include <winioctl.h>
-
-#include "../conf.h"
-#include "../device.h"
-#include "../logger.h"
-#include "../names.h"
-#include "../net.h"
-#include "../route.h"
-#include "../utils.h"
-#include "../xalloc.h"
-
-#include "common.h"
-
-int device_fd = -1;
-static HANDLE device_handle = INVALID_HANDLE_VALUE;
-static io_t device_read_io;
-static OVERLAPPED device_read_overlapped;
-static OVERLAPPED device_write_overlapped;
-static vpn_packet_t device_read_packet;
-static vpn_packet_t device_write_packet;
-char *device = NULL;
-char *iface = NULL;
-static const char *device_info = "Windows tap device";
-
-static void device_issue_read(void) {
-       int status;
-
-       for(;;) {
-               ResetEvent(device_read_overlapped.hEvent);
-
-               DWORD len;
-               status = ReadFile(device_handle, (void *)device_read_packet.data, MTU, &len, &device_read_overlapped);
-
-               if(!status) {
-                       if(GetLastError() != ERROR_IO_PENDING)
-                               logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
-                                      device, strerror(errno));
-
-                       break;
-               }
-
-               device_read_packet.len = len;
-               device_read_packet.priority = 0;
-               route(myself, &device_read_packet);
-       }
-}
-
-static void device_handle_read(void *data, int flags) {
-       (void)data;
-       (void)flags;
-
-       DWORD len;
-
-       if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, FALSE)) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Error getting read result from %s %s: %s", device_info,
-                      device, strerror(errno));
-
-               if(GetLastError() != ERROR_IO_INCOMPLETE) {
-                       /* Must reset event or it will keep firing. */
-                       ResetEvent(device_read_overlapped.hEvent);
-               }
-
-               return;
-       }
-
-       device_read_packet.len = len;
-       device_read_packet.priority = 0;
-       route(myself, &device_read_packet);
-       device_issue_read();
-}
-
-static bool setup_device(void) {
-       HKEY key, key2;
-       int i;
-
-       char regpath[1024];
-       char adapterid[1024];
-       char adaptername[1024];
-       char tapname[1024];
-       DWORD len;
-
-       bool found = false;
-
-       int err;
-
-       get_config_string(lookup_config(&config_tree, "Device"), &device);
-       get_config_string(lookup_config(&config_tree, "Interface"), &iface);
-
-       if(device && iface) {
-               logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected");
-       }
-
-       /* Open registry and look for network adapters */
-
-       if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read registry: %s", winerror(GetLastError()));
-               return false;
-       }
-
-       for(i = 0; ; i++) {
-               len = sizeof(adapterid);
-
-               if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) {
-                       break;
-               }
-
-               /* Find out more about this adapter */
-
-               snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid);
-
-               if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) {
-                       continue;
-               }
-
-               len = sizeof(adaptername);
-               err = RegQueryValueEx(key2, "Name", 0, 0, (LPBYTE)adaptername, &len);
-
-               RegCloseKey(key2);
-
-               if(err) {
-                       continue;
-               }
-
-               if(device) {
-                       if(!strcmp(device, adapterid)) {
-                               found = true;
-                               break;
-                       } else {
-                               continue;
-                       }
-               }
-
-               if(iface) {
-                       if(!strcmp(iface, adaptername)) {
-                               found = true;
-                               break;
-                       } else {
-                               continue;
-                       }
-               }
-
-               snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid);
-               device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
-
-               if(device_handle != INVALID_HANDLE_VALUE) {
-                       found = true;
-                       break;
-               }
-       }
-
-       RegCloseKey(key);
-
-       if(!found) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "No Windows tap device found!");
-               return false;
-       }
-
-       if(!device) {
-               device = xstrdup(adapterid);
-       }
-
-       if(!iface) {
-               iface = xstrdup(adaptername);
-       }
-
-       /* Try to open the corresponding tap device */
-
-       if(device_handle == INVALID_HANDLE_VALUE) {
-               snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device);
-               device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
-       }
-
-       if(device_handle == INVALID_HANDLE_VALUE) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "%s (%s) is not a usable Windows tap device: %s", device, iface, winerror(GetLastError()));
-               return false;
-       }
-
-       /* Get version information from tap device */
-
-       {
-               ULONG info[3] = {0};
-               DWORD len;
-
-               if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_VERSION, &info, sizeof(info), &info, sizeof(info), &len, NULL)) {
-                       logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get version information from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError()));
-               } else {
-                       logger(DEBUG_ALWAYS, LOG_INFO, "TAP-Windows driver version: %lu.%lu%s", info[0], info[1], info[2] ? " (DEBUG)" : "");
-
-                       /* Warn if using >=9.21. This is because starting from 9.21, TAP-Win32 seems to use a different, less efficient write path. */
-                       if(info[0] == 9 && info[1] >= 21)
-                               logger(DEBUG_ALWAYS, LOG_WARNING,
-                                      "You are using the newer (>= 9.0.0.21, NDIS6) series of TAP-Win32 drivers. "
-                                      "Using these drivers with tinc is not recommended as it can result in poor performance. "
-                                      "You might want to revert back to 9.0.0.9 instead.");
-               }
-       }
-
-       /* Get MAC address from tap device */
-
-       if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError()));
-               return false;
-       }
-
-       if(routing_mode == RMODE_ROUTER) {
-               overwrite_mac = 1;
-       }
-
-       device_info = "Windows tap device";
-
-       logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
-
-       device_read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-       device_write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-
-       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);
-
-       /* We don't use the write event directly, but GetOverlappedResult() does, internally. */
-
-       io_add_event(&device_read_io, device_handle_read, NULL, device_read_overlapped.hEvent);
-       device_issue_read();
-}
-
-static void disable_device(void) {
-       logger(DEBUG_ALWAYS, LOG_INFO, "Disabling %s", device_info);
-
-       io_del(&device_read_io);
-
-       ULONG status = 0;
-       DWORD len;
-       DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL);
-
-       /* Note that we don't try to cancel ongoing I/O here - we just stop listening.
-          This is because some TAP-Win32 drivers don't seem to handle cancellation very well,
-          especially when combined with other events such as the computer going to sleep - cases
-          were observed where the GetOverlappedResult() would just block indefinitely and never
-          return in that case. */
-}
-
-static void close_device(void) {
-       CancelIo(device_handle);
-
-       /* According to MSDN, CancelIo() does not necessarily wait for the operation to complete.
-          To prevent race conditions, make sure the operation is complete
-          before we close the event it's referencing. */
-
-       DWORD len;
-
-       if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s read to cancel: %s", device_info, device, winerror(GetLastError()));
-       }
-
-       if(device_write_packet.len > 0 && !GetOverlappedResult(device_handle, &device_write_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s write to cancel: %s", device_info, device, winerror(GetLastError()));
-       }
-
-       device_write_packet.len = 0;
-
-       CloseHandle(device_read_overlapped.hEvent);
-       CloseHandle(device_write_overlapped.hEvent);
-
-       CloseHandle(device_handle);
-       device_handle = INVALID_HANDLE_VALUE;
-
-       free(device);
-       device = NULL;
-       free(iface);
-       iface = NULL;
-       device_info = NULL;
-}
-
-static bool read_packet(vpn_packet_t *packet) {
-       (void)packet;
-       return false;
-}
-
-static bool write_packet(vpn_packet_t *packet) {
-       DWORD outlen;
-
-       logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s",
-              packet->len, device_info);
-
-       if(device_write_packet.len > 0) {
-               /* Make sure the previous write operation is finished before we start the next one;
-                  otherwise we end up with multiple write ops referencing the same OVERLAPPED structure,
-                  which according to MSDN is a no-no. */
-
-               if(!GetOverlappedResult(device_handle, &device_write_overlapped, &outlen, FALSE)) {
-                       if(GetLastError() != ERROR_IO_INCOMPLETE) {
-                               logger(DEBUG_ALWAYS, LOG_ERR, "Error completing previously queued write to %s %s: %s", device_info, device, winerror(GetLastError()));
-                       } else {
-                               logger(DEBUG_TRAFFIC, LOG_ERR, "Previous overlapped write to %s %s still in progress", device_info, device);
-                               // drop this packet
-                               return true;
-                       }
-               }
-       }
-
-       /* Copy the packet, since the write operation might still be ongoing after we return. */
-
-       memcpy(&device_write_packet, packet, sizeof(*packet));
-
-       ResetEvent(device_write_overlapped.hEvent);
-
-       if(WriteFile(device_handle, DATA(&device_write_packet), device_write_packet.len, &outlen, &device_write_overlapped)) {
-               // Write was completed immediately.
-               device_write_packet.len = 0;
-       } else if(GetLastError() != ERROR_IO_PENDING) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError()));
-               device_write_packet.len = 0;
-               return false;
-       }
-
-       return true;
-}
-
-const devops_t os_devops = {
-       .setup = setup_device,
-       .close = close_device,
-       .read = read_packet,
-       .write = write_packet,
-       .enable = enable_device,
-       .disable = disable_device,
-};
diff --git a/src/mingw/meson.build b/src/mingw/meson.build
deleted file mode 100644 (file)
index 5cd2c7b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-check_headers += 'w32api.h'
-
-win_common_libs = ['ws2_32', 'iphlpapi', 'threads']
-
-if opt_harden and cc_name != 'msvc'
-  win_common_libs += 'ssp'
-endif
-
-foreach libname : win_common_libs
-  dep = dependency(libname, required: false)
-  if not dep.found()
-    dep = cc.find_library(libname)
-  endif
-  deps_common += dep
-endforeach
-
-src_tincd += files('device.c')
-
-cdata.set('HAVE_MINGW', 1)
-
index c9318fafb544bb2d4c64a9bd430ac5e7a146bd6a..fa3574b0ea24c7d2ee047a5880900f02f6cc3d67 100644 (file)
@@ -39,7 +39,7 @@ char *program_name = NULL;
   Set all files and paths according to netname
 */
 void make_names(bool daemon) {
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        HKEY key;
        char installdir[1024] = "";
        DWORD len = sizeof(installdir);
@@ -58,7 +58,7 @@ void make_names(bool daemon) {
                identname = xstrdup("tinc");
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) {
                if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) {
@@ -94,7 +94,7 @@ void make_names(bool daemon) {
                }
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        (void)daemon;
 
        if(!logfilename) {
index 7f8442169de9b3d78fc75f29d373bbaaba74e630..9669bc971972488e80ba69391b3841da952f13dc 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -160,7 +160,7 @@ void terminate_connection(connection_t *c, bool report) {
                do_outgoing_connection(outgoing);
        }
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        /* Clean up dead proxy processes */
 
        while(waitpid(-1, NULL, WNOHANG) > 0);
@@ -308,7 +308,7 @@ void handle_meta_connection_data(connection_t *c) {
        }
 }
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 static void sigterm_handler(void *data) {
        logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
        event_exit();
@@ -487,7 +487,7 @@ int main_loop(void) {
                0, 0
        });
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        signal_t sighup = {0};
        signal_t sigterm = {0};
        signal_t sigquit = {0};
@@ -506,7 +506,7 @@ int main_loop(void) {
                return 1;
        }
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        signal_del(&sighup);
        signal_del(&sigterm);
        signal_del(&sigquit);
index 261d9c3cfb40c17e0f57897c19d3c576e6329073..1765b1cd891a560c19677c2918b1e2140a361157 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -215,7 +215,7 @@ extern void load_all_nodes(void);
 extern void try_tx(struct node_t *n, bool mtu);
 extern void tarpit(int fd);
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 #define closesocket(s) close(s)
 #endif
 
index a8e197b4c430f37dbb1833e31cfacc8b3dfd6ec2..dfee573cdff2ea47599f0b0e57a18e868875714a 100644 (file)
@@ -47,7 +47,7 @@ int fwmark;
 
 listen_socket_t listen_socket[MAXSOCKETS];
 int listen_sockets;
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 io_t unix_socket;
 #endif
 
@@ -425,7 +425,7 @@ void finish_connecting(connection_t *c) {
 }
 
 static void do_outgoing_pipe(connection_t *c, const char *command) {
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        int fd[2];
 
        if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
@@ -783,7 +783,7 @@ void handle_new_meta_connection(void *data, int flags) {
        c->allow_request = ID;
 }
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 /*
   accept a new UNIX socket connection
 */
index d9df82881c3fb8e8291e10276a7a03b83f2d5caa..6965218b16023274c639a6abe244757736de6638 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "../crypto.h"
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 
 static int random_fd = -1;
 
index c2df0af3e4cbae396742a6695f25c2aed2f1d618..fe5a599715c93c1c1317877bb45ab1d189af5087 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "../crypto.h"
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 
 static int random_fd = -1;
 
index 7deaadfcb3fa366be316e559bc6731c8208cf6e3..5e7b1db5979ca627d10d1567e9a0ca2abaafee31 100644 (file)
@@ -25,7 +25,7 @@
 #include "process.h"
 #include "version.h"
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 #include "utils.h"
 #endif
 
@@ -42,7 +42,7 @@ bool use_logfile = false;
 
 /* Some functions the less gifted operating systems might lack... */
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 static SC_HANDLE manager = NULL;
 static SC_HANDLE service = NULL;
 static SERVICE_STATUS status = {0};
@@ -202,7 +202,7 @@ bool init_service(void) {
 bool detach(void) {
        logmode_t logmode;
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        signal(SIGPIPE, SIG_IGN);
        signal(SIGUSR1, SIG_IGN);
        signal(SIGUSR2, SIG_IGN);
@@ -212,7 +212,7 @@ bool detach(void) {
 #endif
 
        if(do_detach) {
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 
                if(daemon(1, 0)) {
                        logger(DEBUG_ALWAYS, LOG_ERR, "Couldn't detach from terminal: %s", strerror(errno));
index 1aae6dea4237087210bbeea88e7c668397299121..70f1c5ca3cd977a1fd11e25e230f32d66e7e03db 100644 (file)
@@ -29,7 +29,7 @@ extern bool use_syslog;
 
 extern bool detach(void);
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 #include "event.h"
 
 extern io_t stop_io;
index b380931f2ea09c91b843eca9c3fd485ad0a8a3ba..0b16c861d8e4d5930b306b7f3e2df4adde0ed0fe 100644 (file)
@@ -37,7 +37,7 @@ static void unputenv(const char *p) {
 
        ptrdiff_t len = e - p;
 #ifndef HAVE_UNSETENV
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        // Windows requires putenv("FOO=") to unset %FOO%
        len++;
 #endif
@@ -148,7 +148,7 @@ bool execute_script(const char *name, environment_t *env) {
 
        /* First check if there is a script */
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if(!*scriptextension) {
                const char *pathext = getenv("PATHEXT");
index 1da0571c6fc8b2ee1c4ad54d49b3e99046d853b0..baca66b318f7e3c23d8ff181cd5532bac0191b07 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <getopt.h>
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 #include <pthread.h>
 #endif
 
@@ -37,7 +37,7 @@
 #include "utils.h"
 #include "names.h"
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 #define closesocket(s) close(s)
 #endif
 
@@ -160,7 +160,7 @@ static void usage(void) {
        fprintf(stderr, message, program_name);
 }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
 int stdin_sock_fd = -1;
 
@@ -308,7 +308,7 @@ server_err:
        return -1;
 }
 
-#endif // HAVE_MINGW
+#endif // HAVE_WINDOWS
 
 int main(int argc, char *argv[]) {
        program_name = argv[0];
@@ -428,7 +428,7 @@ int main(int argc, char *argv[]) {
 
 #endif
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        static struct WSAData wsa_state;
 
        if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
@@ -566,7 +566,7 @@ int main(int argc, char *argv[]) {
                return 1;
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if(!readonly) {
                in = start_input_reader();
@@ -607,7 +607,7 @@ int main(int argc, char *argv[]) {
                }
 
                if(FD_ISSET(in, &fds)) {
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
                        ssize_t len = recv(in, buf, readsize, 0);
 #else
                        ssize_t len = read(in, buf, readsize);
@@ -621,7 +621,7 @@ int main(int argc, char *argv[]) {
                        }
 
                        if(len == 0) {
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
                                shutdown(in, SD_SEND);
                                closesocket(in);
 #endif
index 946e7498e6fbf3d53e7490b60c3328c9f7409ace..c700f947779c7251d96e913a8391b11d36c2c742 100644 (file)
@@ -281,7 +281,7 @@ ask_filename:
                }
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if(filename[0] != '\\' && filename[0] != '/' && !strchr(filename, ':')) {
 #else
@@ -651,7 +651,7 @@ static bool stop_tincd(void) {
        return true;
 }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 static bool remove_service(void) {
        SC_HANDLE manager = NULL;
        SC_HANDLE service = NULL;
@@ -748,7 +748,7 @@ bool connect_tincd(bool verbose) {
 
        fclose(f);
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 
        if((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) {
                fprintf(stderr, "Could not find tincd running at pid %d\n", pid);
@@ -886,7 +886,7 @@ static int cmd_start(int argc, char *argv[]) {
        char *c;
        char *slash = strrchr(program_name, '/');
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if((c = strrchr(program_name, '\\')) > slash) {
                slash = c;
@@ -904,7 +904,7 @@ static int cmd_start(int argc, char *argv[]) {
        char **nargv = xzalloc((optind + argc) * sizeof(*nargv));
 
        char *arg0 = c;
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        /*
           Windows has no real concept of an "argv array". A command line is just one string.
           The CRT of the new process will decode the command line string to generate argv before calling main(), and (by convention)
@@ -925,7 +925,7 @@ static int cmd_start(int argc, char *argv[]) {
                nargv[nargc++] = argv[i];
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        int status = spawnvp(_P_WAIT, c, nargv);
 
        free(nargv);
@@ -1024,7 +1024,7 @@ static int cmd_stop(int argc, char *argv[]) {
                return 1;
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        return remove_service() ? EXIT_SUCCESS : EXIT_FAILURE;
 #else
 
@@ -2058,7 +2058,7 @@ static int cmd_config(int argc, char *argv[]) {
        }
 
        // Replace the configuration file with the new one
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if(remove(filename)) {
                fprintf(stderr, "Error replacing file %s: %s\n", filename, strerror(errno));
@@ -2234,7 +2234,7 @@ static int cmd_init(int argc, char *argv[]) {
 
        check_port(name);
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        char filename[PATH_MAX];
        snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up", confbase);
 
@@ -2396,7 +2396,7 @@ static int cmd_edit(int argc, char *argv[]) {
        }
 
        char *command;
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        const char *editor = getenv("VISUAL");
 
        if(!editor) {
@@ -3290,7 +3290,7 @@ int main(int argc, char *argv[]) {
                return 0;
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        static struct WSAData wsa_state;
 
        if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
index 1ee8769fcaf32d91f745ef9cfdbafd3c7075d3b1..9850eebb20190a64ccc88c4b7c8821dd4b6f700d 100644 (file)
@@ -37,7 +37,7 @@
 #include <lz4.h>
 #endif
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 #include <pwd.h>
 #include <grp.h>
 #include <time.h>
@@ -66,7 +66,7 @@ static bool show_version = false;
 static bool do_mlock = false;
 #endif
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 /* If nonzero, chroot to netdir after startup. */
 static bool do_chroot = false;
 
@@ -96,7 +96,7 @@ static struct option const long_options[] = {
        {NULL, 0, NULL, 0}
 };
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 static struct WSAData wsa_state;
 int main2(int argc, char **argv);
 #endif
@@ -121,7 +121,7 @@ static void usage(bool status) {
                        "      --pidfile=FILENAME        Write PID and control socket cookie to FILENAME.\n"
                        "      --bypass-security         Disables meta protocol security, for debugging.\n"
                        "  -o, --option[HOST.]KEY=VALUE  Set global/host configuration value.\n"
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
                        "  -R, --chroot                  chroot to NET dir at startup.\n"
                        "  -U, --user=USER               setuid to given USER at startup.\n"
 #endif
@@ -196,7 +196,7 @@ static bool parse_options(int argc, char **argv) {
                        list_insert_tail(&cmdline_conf, cfg);
                        break;
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
                case 'R':
                case 'U':
@@ -289,7 +289,7 @@ exit_fail:
 }
 
 static bool drop_privs(void) {
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        uid_t uid = 0;
 
        if(switchuser) {
@@ -342,7 +342,7 @@ static bool drop_privs(void) {
        return true;
 }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 # define setpriority(level) !SetPriorityClass(GetCurrentProcess(), (level))
 
 static void stop_handler(void *data, int flags) {
@@ -445,7 +445,7 @@ int main(int argc, char **argv) {
                return 1;
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
                logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError()));
@@ -511,7 +511,7 @@ int main(int argc, char **argv) {
 
 #endif
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        io_add_event(&stop_io, stop_handler, NULL, WSACreateEvent());
 
        if(stop_io.event == FALSE) {
index 8b0cd6edbedeed17ee21c33e9c94932c11362baf..4150d92bf8e5d8804e40800c004115c1a97f5189 100644 (file)
@@ -176,7 +176,7 @@ size_t b64encode_tinc_urlsafe(const void *src, char *dst, size_t length) {
        return b64encode_tinc_internal(src, dst, length, base64_urlsafe);
 }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 const char *winerror(int err) {
        static char buf[1024], *ptr;
 
index 9756a3e0c3ca893180ac792a728029d9ef886014..5f1bd8b8e8ac426e0cba16df91cfacb3893cc1b6 100644 (file)
@@ -34,7 +34,7 @@ extern size_t b64encode_tinc(const void *src, char *dst, size_t length);
 extern size_t b64encode_tinc_urlsafe(const void *src, char *dst, size_t length);
 extern size_t b64decode_tinc(const char *src, void *dst, size_t length);
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 extern const char *winerror(int);
 #define strerror(x) ((x)>0?strerror(x):winerror(GetLastError()))
 #define sockerrno WSAGetLastError()
diff --git a/src/windows/common.h b/src/windows/common.h
new file mode 100644 (file)
index 0000000..dd0e6dd
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef TINC_WINDOWS_COMMON_H
+#define TINC_WINDOWS_COMMON_H
+
+/*
+ *  TAP-Win32 -- A kernel driver to provide virtual tap device functionality
+ *               on Windows.  Originally derived from the CIPE-Win32
+ *               project by Damion K. Wilson, with extensive modifications by
+ *               James Yonan.
+ *
+ *  All source code which derives from the CIPE-Win32 project is
+ *  Copyright (C) Damion K. Wilson, 2003, and is released under the
+ *  GPL version 2 (see below).
+ *
+ *  All other source code is Copyright (C) James Yonan, 2003-2004,
+ *  and is released under the GPL version 2 (see below).
+ *
+ *  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
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+//===============================================
+// This file is included both by OpenVPN and
+// the TAP-Win32 driver and contains definitions
+// common to both.
+//===============================================
+
+//=============
+// TAP IOCTLs
+//=============
+
+#define TAP_CONTROL_CODE(request,method) \
+       CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
+
+#define TAP_IOCTL_GET_MAC               TAP_CONTROL_CODE (1, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_VERSION           TAP_CONTROL_CODE (2, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_MTU               TAP_CONTROL_CODE (3, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_INFO              TAP_CONTROL_CODE (4, METHOD_BUFFERED)
+#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED)
+#define TAP_IOCTL_SET_MEDIA_STATUS      TAP_CONTROL_CODE (6, METHOD_BUFFERED)
+#define TAP_IOCTL_CONFIG_DHCP_MASQ      TAP_CONTROL_CODE (7, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_LOG_LINE          TAP_CONTROL_CODE (8, METHOD_BUFFERED)
+#define TAP_IOCTL_CONFIG_DHCP_SET_OPT   TAP_CONTROL_CODE (9, METHOD_BUFFERED)
+
+//=================
+// Registry keys
+//=================
+
+#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+
+#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+
+//======================
+// Filesystem prefixes
+//======================
+
+#define USERMODEDEVICEDIR "\\\\.\\Global\\"
+#define SYSDEVICEDIR      "\\Device\\"
+#define USERDEVICEDIR     "\\DosDevices\\Global\\"
+#define TAPSUFFIX         ".tap"
+
+//=========================================================
+// TAP_COMPONENT_ID -- This string defines the TAP driver
+// type -- different component IDs can reside in the system
+// simultaneously.
+//=========================================================
+
+#define TAP_COMPONENT_ID "tap0801"
+
+#endif
diff --git a/src/windows/device.c b/src/windows/device.c
new file mode 100644 (file)
index 0000000..51d09f7
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+    device.c -- Interaction with the TAP-Windows driver
+    Copyright (C) 2002-2005 Ivo Timmermans,
+                  2002-2022 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "../system.h"
+
+#include <windows.h>
+#include <winioctl.h>
+
+#include "../conf.h"
+#include "../device.h"
+#include "../logger.h"
+#include "../names.h"
+#include "../net.h"
+#include "../route.h"
+#include "../utils.h"
+#include "../xalloc.h"
+
+#include "common.h"
+
+int device_fd = -1;
+static HANDLE device_handle = INVALID_HANDLE_VALUE;
+static io_t device_read_io;
+static OVERLAPPED device_read_overlapped;
+static OVERLAPPED device_write_overlapped;
+static vpn_packet_t device_read_packet;
+static vpn_packet_t device_write_packet;
+char *device = NULL;
+char *iface = NULL;
+static const char *device_info = "Windows tap device";
+
+static void device_issue_read(void) {
+       int status;
+
+       for(;;) {
+               ResetEvent(device_read_overlapped.hEvent);
+
+               DWORD len;
+               status = ReadFile(device_handle, (void *)device_read_packet.data, MTU, &len, &device_read_overlapped);
+
+               if(!status) {
+                       if(GetLastError() != ERROR_IO_PENDING)
+                               logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
+                                      device, strerror(errno));
+
+                       break;
+               }
+
+               device_read_packet.len = len;
+               device_read_packet.priority = 0;
+               route(myself, &device_read_packet);
+       }
+}
+
+static void device_handle_read(void *data, int flags) {
+       (void)data;
+       (void)flags;
+
+       DWORD len;
+
+       if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, FALSE)) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Error getting read result from %s %s: %s", device_info,
+                      device, strerror(errno));
+
+               if(GetLastError() != ERROR_IO_INCOMPLETE) {
+                       /* Must reset event or it will keep firing. */
+                       ResetEvent(device_read_overlapped.hEvent);
+               }
+
+               return;
+       }
+
+       device_read_packet.len = len;
+       device_read_packet.priority = 0;
+       route(myself, &device_read_packet);
+       device_issue_read();
+}
+
+static bool setup_device(void) {
+       HKEY key, key2;
+       int i;
+
+       char regpath[1024];
+       char adapterid[1024];
+       char adaptername[1024];
+       char tapname[1024];
+       DWORD len;
+
+       bool found = false;
+
+       int err;
+
+       get_config_string(lookup_config(&config_tree, "Device"), &device);
+       get_config_string(lookup_config(&config_tree, "Interface"), &iface);
+
+       if(device && iface) {
+               logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected");
+       }
+
+       /* Open registry and look for network adapters */
+
+       if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key)) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read registry: %s", winerror(GetLastError()));
+               return false;
+       }
+
+       for(i = 0; ; i++) {
+               len = sizeof(adapterid);
+
+               if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) {
+                       break;
+               }
+
+               /* Find out more about this adapter */
+
+               snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid);
+
+               if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) {
+                       continue;
+               }
+
+               len = sizeof(adaptername);
+               err = RegQueryValueEx(key2, "Name", 0, 0, (LPBYTE)adaptername, &len);
+
+               RegCloseKey(key2);
+
+               if(err) {
+                       continue;
+               }
+
+               if(device) {
+                       if(!strcmp(device, adapterid)) {
+                               found = true;
+                               break;
+                       } else {
+                               continue;
+                       }
+               }
+
+               if(iface) {
+                       if(!strcmp(iface, adaptername)) {
+                               found = true;
+                               break;
+                       } else {
+                               continue;
+                       }
+               }
+
+               snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid);
+               device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
+
+               if(device_handle != INVALID_HANDLE_VALUE) {
+                       found = true;
+                       break;
+               }
+       }
+
+       RegCloseKey(key);
+
+       if(!found) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "No Windows tap device found!");
+               return false;
+       }
+
+       if(!device) {
+               device = xstrdup(adapterid);
+       }
+
+       if(!iface) {
+               iface = xstrdup(adaptername);
+       }
+
+       /* Try to open the corresponding tap device */
+
+       if(device_handle == INVALID_HANDLE_VALUE) {
+               snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device);
+               device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
+       }
+
+       if(device_handle == INVALID_HANDLE_VALUE) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "%s (%s) is not a usable Windows tap device: %s", device, iface, winerror(GetLastError()));
+               return false;
+       }
+
+       /* Get version information from tap device */
+
+       {
+               ULONG info[3] = {0};
+               DWORD len;
+
+               if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_VERSION, &info, sizeof(info), &info, sizeof(info), &len, NULL)) {
+                       logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get version information from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError()));
+               } else {
+                       logger(DEBUG_ALWAYS, LOG_INFO, "TAP-Windows driver version: %lu.%lu%s", info[0], info[1], info[2] ? " (DEBUG)" : "");
+
+                       /* Warn if using >=9.21. This is because starting from 9.21, TAP-Win32 seems to use a different, less efficient write path. */
+                       if(info[0] == 9 && info[1] >= 21)
+                               logger(DEBUG_ALWAYS, LOG_WARNING,
+                                      "You are using the newer (>= 9.0.0.21, NDIS6) series of TAP-Win32 drivers. "
+                                      "Using these drivers with tinc is not recommended as it can result in poor performance. "
+                                      "You might want to revert back to 9.0.0.9 instead.");
+               }
+       }
+
+       /* Get MAC address from tap device */
+
+       if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError()));
+               return false;
+       }
+
+       if(routing_mode == RMODE_ROUTER) {
+               overwrite_mac = 1;
+       }
+
+       device_info = "Windows tap device";
+
+       logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
+
+       device_read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+       device_write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+       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);
+
+       /* We don't use the write event directly, but GetOverlappedResult() does, internally. */
+
+       io_add_event(&device_read_io, device_handle_read, NULL, device_read_overlapped.hEvent);
+       device_issue_read();
+}
+
+static void disable_device(void) {
+       logger(DEBUG_ALWAYS, LOG_INFO, "Disabling %s", device_info);
+
+       io_del(&device_read_io);
+
+       ULONG status = 0;
+       DWORD len;
+       DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL);
+
+       /* Note that we don't try to cancel ongoing I/O here - we just stop listening.
+          This is because some TAP-Win32 drivers don't seem to handle cancellation very well,
+          especially when combined with other events such as the computer going to sleep - cases
+          were observed where the GetOverlappedResult() would just block indefinitely and never
+          return in that case. */
+}
+
+static void close_device(void) {
+       CancelIo(device_handle);
+
+       /* According to MSDN, CancelIo() does not necessarily wait for the operation to complete.
+          To prevent race conditions, make sure the operation is complete
+          before we close the event it's referencing. */
+
+       DWORD len;
+
+       if(!GetOverlappedResult(device_handle, &device_read_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s read to cancel: %s", device_info, device, winerror(GetLastError()));
+       }
+
+       if(device_write_packet.len > 0 && !GetOverlappedResult(device_handle, &device_write_overlapped, &len, TRUE) && GetLastError() != ERROR_OPERATION_ABORTED) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Could not wait for %s %s write to cancel: %s", device_info, device, winerror(GetLastError()));
+       }
+
+       device_write_packet.len = 0;
+
+       CloseHandle(device_read_overlapped.hEvent);
+       CloseHandle(device_write_overlapped.hEvent);
+
+       CloseHandle(device_handle);
+       device_handle = INVALID_HANDLE_VALUE;
+
+       free(device);
+       device = NULL;
+       free(iface);
+       iface = NULL;
+       device_info = NULL;
+}
+
+static bool read_packet(vpn_packet_t *packet) {
+       (void)packet;
+       return false;
+}
+
+static bool write_packet(vpn_packet_t *packet) {
+       DWORD outlen;
+
+       logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s",
+              packet->len, device_info);
+
+       if(device_write_packet.len > 0) {
+               /* Make sure the previous write operation is finished before we start the next one;
+                  otherwise we end up with multiple write ops referencing the same OVERLAPPED structure,
+                  which according to MSDN is a no-no. */
+
+               if(!GetOverlappedResult(device_handle, &device_write_overlapped, &outlen, FALSE)) {
+                       if(GetLastError() != ERROR_IO_INCOMPLETE) {
+                               logger(DEBUG_ALWAYS, LOG_ERR, "Error completing previously queued write to %s %s: %s", device_info, device, winerror(GetLastError()));
+                       } else {
+                               logger(DEBUG_TRAFFIC, LOG_ERR, "Previous overlapped write to %s %s still in progress", device_info, device);
+                               // drop this packet
+                               return true;
+                       }
+               }
+       }
+
+       /* Copy the packet, since the write operation might still be ongoing after we return. */
+
+       memcpy(&device_write_packet, packet, sizeof(*packet));
+
+       ResetEvent(device_write_overlapped.hEvent);
+
+       if(WriteFile(device_handle, DATA(&device_write_packet), device_write_packet.len, &outlen, &device_write_overlapped)) {
+               // Write was completed immediately.
+               device_write_packet.len = 0;
+       } else if(GetLastError() != ERROR_IO_PENDING) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError()));
+               device_write_packet.len = 0;
+               return false;
+       }
+
+       return true;
+}
+
+const devops_t os_devops = {
+       .setup = setup_device,
+       .close = close_device,
+       .read = read_packet,
+       .write = write_packet,
+       .enable = enable_device,
+       .disable = disable_device,
+};
diff --git a/src/windows/meson.build b/src/windows/meson.build
new file mode 100644 (file)
index 0000000..8766bc1
--- /dev/null
@@ -0,0 +1,18 @@
+check_headers += 'w32api.h'
+
+win_common_libs = ['ws2_32', 'iphlpapi', 'threads']
+
+if opt_harden and cc_name != 'msvc'
+  win_common_libs += 'ssp'
+endif
+
+foreach libname : win_common_libs
+  dep = dependency(libname, required: false)
+  if not dep.found()
+    dep = cc.find_library(libname)
+  endif
+  deps_common += dep
+endforeach
+
+src_tincd += files('device.c')
+
index 33f30d02da744c418b3ad56eb033fedfe97c92d8..da74ce1fca201869965ef31b4f674a6f39cade83 100644 (file)
@@ -67,7 +67,7 @@ static inline char *xstrdup(const char *s) {
 }
 
 static inline int xvasprintf(char **strp, const char *fmt, va_list ap) {
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        char buf[1024];
        int result = vsnprintf(buf, sizeof(buf), fmt, ap);
 
index 07c350301b222682646ca42457dd3ae3d5bfc209..e72d0c7199b60a88e38ec49e6528106e6e23fb55 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "../../src/system.h"
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 static const char *winerror(int err) {
        static char buf[1024], *ptr;
 
@@ -59,7 +59,7 @@ int main(int argc, char *argv[]) {
                protocol = "17.7";
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        static struct WSAData wsa_state;
 
        if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {