From patchwork Thu Sep 15 00:40:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lev Stipakov X-Patchwork-Id: 2759 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director14.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id WN9UMlcBI2NAbQAAIUCqbw (envelope-from ) for ; Thu, 15 Sep 2022 06:41:27 -0400 Received: from proxy10.mail.ord1d.rsapps.net ([172.30.191.6]) by director14.mail.ord1d.rsapps.net with LMTP id MDEDMlcBI2MeHgAAeJ7fFg (envelope-from ) for ; Thu, 15 Sep 2022 06:41:27 -0400 Received: from smtp30.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy10.mail.ord1d.rsapps.net with LMTPS id oIzOMVcBI2NzEAAAfSg8FQ (envelope-from ) for ; Thu, 15 Sep 2022 06:41:27 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp30.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=gmail.com; dmarc=fail (p=none; dis=none) header.from=gmail.com X-Suspicious-Flag: YES X-Classification-ID: f35206da-34e2-11ed-9d5e-5254001e8e38-1-1 Received: from [216.105.38.7] ([216.105.38.7:46892] helo=lists.sourceforge.net) by smtp30.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 4B/4B-14438-75103236; Thu, 15 Sep 2022 06:41:27 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1oYmIR-00031m-J8; Thu, 15 Sep 2022 10:40:52 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1oYmIO-00031g-V4 for openvpn-devel@lists.sourceforge.net; Thu, 15 Sep 2022 10:40:49 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=M4/rDraDUnl9tJ/AQxTVJoPdIeqGE7sMHMe9yv/xbxI=; b=gpdr0UqkgVXTXlgu9COOcvC29K 0ruQxW7LuC7L+c1mHvZyVjRWPFXRZek84dEMBJlZuE2TsFp/pNnmQhDPN5SJZWk2kuaXC069sQbkX xfZ2au+CqixcnpKfxt9LMfbYRwu4LdfiIN5ypIJ9G8v7r/X7Px2FBZtm61P3Shlg9Kys=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=M4/rDraDUnl9tJ/AQxTVJoPdIeqGE7sMHMe9yv/xbxI=; b=NWISd3nHG7si+gWRerMHrxfoG4 Pg5VfrlFUU6lKQX7lS451au3fg37nCTTmC0u0iO2rN0x16wZ+HbhiY8+rxvxK2VbYIXMF6Lu9mItX 8l2EUcnqqKdn71Wi4JHA+EB7gpN8dVHHn5qKAFKonyInDVzZLzvKSJjdZbs6UTfR44Y0=; Received: from mail-lf1-f49.google.com ([209.85.167.49]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1oYmIa-0090fy-OM for openvpn-devel@lists.sourceforge.net; Thu, 15 Sep 2022 10:40:49 +0000 Received: by mail-lf1-f49.google.com with SMTP id z25so29713941lfr.2 for ; Thu, 15 Sep 2022 03:40:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=M4/rDraDUnl9tJ/AQxTVJoPdIeqGE7sMHMe9yv/xbxI=; b=XBIDPf2ivwuDXJ+8FiseYyXnrN8QI8oAnA7SW8bdZaY9R0+pBk88tkJPr5NzBHszSk So7SUoqlToojLJymLPy9RvmlHhFtUSYVhaCbCQLQSkDjQ7LlQBljeexX3acQgxwOmix8 DwoX0UGEh5qYRrjJfMXNOJgNJ4xh6PBrrCWuIHOJlZxuI4oLs2t/XaB4o5wZ1SM+TYSj uxNCcy2gmdrT/pBQBosUX7dLwhl1FVr7nL5ioxVzIRbco9g3yjlNQdfEenXw/XOJ+ZmL R/fqirqN3MJeAz8GGwNDQA1O1zv+aX+wuGU9E4cgx6CbXrF9yYUe+XoXt0vzFw0Ux1hf JJoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=M4/rDraDUnl9tJ/AQxTVJoPdIeqGE7sMHMe9yv/xbxI=; b=Ptc+q4L0WziFAS5ZYpnSQ5QtgERxZnyJjJElJArA5Y+KvCp5ttcqclmRqs/DneRCEX scJqW3Yht8nY3CcEl3kYlSlaCw0nCk1rMrzbzY/+Pbp6vO1prvd9kL8Yw5drGaC0OVRt JRZTCzmePX73ixVQg4bW0tiFq+CnIBwekyg8ykkKUd91F7fLA4xD15iptLaHEyX7FP2Y +5gmuvvU2v8Ybd0xNkNS1trYv5VVsGKq2QMSGa1rellAJQIvtQd8hD3/ff71gdfw0FgO n7SNki085QaauJWn+Am1fLwplPbEflz8iNNRO1hUESkjBXIXWt2VDO3Opeo/MsFvqjjD DjsA== X-Gm-Message-State: ACgBeo2GCX6wVxMRTnnr3ax5x3hZr8g47S7WVNgsKdbcCpT9tmA0pPlJ SRqwmvkGLoM9fwiANo1Be+1wvnytkBJYpw== X-Google-Smtp-Source: AA6agR5trY7twQo63lf/F+1qe0Uiib1UOjt9a52bDK1b6k7Fgr7lFGOZ2qDJ7y9t0tMrVp02HZFk9g== X-Received: by 2002:a05:6512:798:b0:497:aa2b:8b10 with SMTP id x24-20020a056512079800b00497aa2b8b10mr14226729lfr.636.1663238441792; Thu, 15 Sep 2022 03:40:41 -0700 (PDT) Received: from LAPTOP-4L3N7KFS.localdomain (nat2.panoulu.net. [185.38.2.2]) by smtp.gmail.com with ESMTPSA id q16-20020a194310000000b004946aef1814sm2910480lfa.137.2022.09.15.03.40.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Sep 2022 03:40:41 -0700 (PDT) From: Lev Stipakov To: openvpn-devel@lists.sourceforge.net Date: Thu, 15 Sep 2022 13:40:28 +0300 Message-Id: <20220915104028.188-1-lstipakov@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Report: Spam detection software, running on the system "util-spamd-2.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Lev Stipakov On startup, check following conditions: - ovpn-dco-win driver is installed. Perform this check by trying to open adapter by symbolic name. Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [lstipakov[at]gmail.com] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.167.49 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.167.49 listed in wl.mailspike.net] -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1oYmIa-0090fy-OM Subject: [Openvpn-devel] [PATCH v4] Use DCO on Windows by default X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lev Stipakov Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: Lev Stipakov On startup, check following conditions: - ovpn-dco-win driver is installed. Perform this check by trying to open adapter by symbolic name. - options are compatible with dco. Same checks as on Linux and FreeBSD. In addition, check that --mode server is not used and --windows-driver is not set to tap-windows6/wintun. If both checks are passed, use DCO. Move options_postprocess_mutate_invariant() call below since it depends on selected windows driver. dco_check_option() has side effect on Windows - if dco is not used, it might complain "cipher chachapoly not supported by dco, disabling dco" if chachapoly support is missing system-wide. To not to see this, check dco options only if dco is enabled. This means moving dco_enabled() from dco_check_startup_option() to one level above. We do similar thing in multi_connection_established() before checking ccd options. Signed-off-by: Lev Stipakov Acked-by: Frank Lichtenheld --- v4: - simplify #ifdef in usage_message() in options.c - simplify #ifdef in show_settings() in options.c v3: - Simplify #ifdefs, as per Frank suggestions v2: - initialize disable_dco to true if ENABLE_DCO is not set, this allows yo get rid of "else" branch in options_postprocess_mutate() - use dco_enabled() wrapper instead of accessing o->tt.disable_dco src/openvpn/dco.c | 19 +++++++++++------ src/openvpn/dco_win.c | 23 ++++++++++++++++++++- src/openvpn/options.c | 48 ++++++++++++++++++++++++++++--------------- src/openvpn/options.h | 6 ++---- src/openvpn/tun.c | 19 ----------------- src/openvpn/tun.h | 20 ++++++++++++++++++ 6 files changed, 88 insertions(+), 47 deletions(-) diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c index d9e49781..a76cdd0c 100644 --- a/src/openvpn/dco.c +++ b/src/openvpn/dco.c @@ -257,11 +257,11 @@ dco_check_option_ce(const struct connection_entry *ce, int msglevel) bool dco_check_startup_option(int msglevel, const struct options *o) { - /* check if DCO was already disabled by the user or if no dev name was - * specified at all. In the latter case, later logic will most likely stop - * OpenVPN, so no need to print any message here. + /* check if no dev name was specified at all. In the case, + * later logic will most likely stop OpenVPN, so no need to + * print any message here. */ - if (!dco_enabled(o) || !o->dev) + if (!o->dev) { return false; } @@ -294,8 +294,15 @@ dco_check_startup_option(int msglevel, const struct options *o) #if defined(_WIN32) if (o->mode == MODE_SERVER) { - msg(msglevel, "Only client and p2p data channel offload is supported " - "with ovpn-dco."); + msg(msglevel, "--mode server is set. Disabling Data Channel Offload"); + return false; + } + + if ((o->windows_driver == WINDOWS_DRIVER_WINTUN) + || (o->windows_driver == WINDOWS_DRIVER_TAP_WINDOWS6)) + { + msg(msglevel, "--windows-driver is set to '%s'. Disabling Data Channel Offload", + print_windows_driver(o->windows_driver)); return false; } diff --git a/src/openvpn/dco_win.c b/src/openvpn/dco_win.c index 22f30280..48a1755a 100644 --- a/src/openvpn/dco_win.c +++ b/src/openvpn/dco_win.c @@ -359,7 +359,28 @@ dco_swap_keys(dco_context_t *dco, unsigned int peer_id) bool dco_available(int msglevel) { - return true; + /* try to open device by symbolic name */ + HANDLE h = CreateFile("\\\\.\\ovpn-dco", GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, NULL); + + if (h != INVALID_HANDLE_VALUE) + { + CloseHandle(h); + return true; + } + + DWORD err = GetLastError(); + if (err == ERROR_ACCESS_DENIED) + { + /* this likely means that device exists but is already in use, + * don't bail out since later we try to open all existing dco + * devices and then bail out if all devices are in use + */ + return true; + } + + msg(msglevel, "Note: ovpn-dco-win driver is missing, disabling data channel offload."); + return false; } int diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 2e567571..25f9dbee 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -183,7 +183,7 @@ static const char usage_message[] = " does not begin with \"tun\" or \"tap\".\n" "--dev-node node : Explicitly set the device node rather than using\n" " /dev/net/tun, /dev/tun, /dev/tap, etc.\n" -#if defined(ENABLE_DCO) && (defined(TARGET_LINUX) || defined(TARGET_FREEBSD)) +#if defined(ENABLE_DCO) "--disable-dco : Do not attempt using Data Channel Offload.\n" #endif "--lladdr hw : Set the link layer address of the tap device.\n" @@ -851,7 +851,7 @@ init_options(struct options *o, const bool init_gc) o->tuntap_options.dhcp_masq_offset = 0; /* use network address as internal DHCP server address */ o->route_method = ROUTE_METHOD_ADAPTIVE; o->block_outside_dns = false; - o->windows_driver = WINDOWS_DRIVER_TAP_WINDOWS6; + o->windows_driver = WINDOWS_DRIVER_UNSPECIFIED; #endif o->vlan_accept = VLAN_ALL; o->vlan_pvid = 1; @@ -903,6 +903,10 @@ init_options(struct options *o, const bool init_gc) } #endif /* _WIN32 */ o->allow_recursive_routing = false; + +#ifndef ENABLE_DCO + o->tuntap_options.disable_dco = true; +#endif /* ENABLE_DCO */ } void @@ -1796,7 +1800,7 @@ show_settings(const struct options *o) SHOW_STR(dev); SHOW_STR(dev_type); SHOW_STR(dev_node); -#if defined(ENABLE_DCO) && (defined(TARGET_LINUX) || defined(TARGET_FREEBSD)) +#if defined(ENABLE_DCO) SHOW_BOOL(tuntap_options.disable_dco); #endif SHOW_STR(lladdr); @@ -3606,8 +3610,6 @@ options_postprocess_mutate(struct options *o, struct env_set *es) options_set_backwards_compatible_options(o); options_postprocess_cipher(o); - options_postprocess_mutate_invariant(o); - o->ncp_ciphers = mutate_ncp_cipher_list(o->ncp_ciphers, &o->gc); if (o->ncp_ciphers == NULL) { @@ -3683,18 +3685,29 @@ options_postprocess_mutate(struct options *o, struct env_set *es) "incompatible with each other."); } -#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) - /* check if any option should force disabling DCO */ - o->tuntap_options.disable_dco = !dco_check_option(D_DCO, o) - || !dco_check_startup_option(D_DCO, o); -#elif defined(_WIN32) - /* in Windows we have no 'fallback to non-DCO' strategy, so if a conflicting - * option is found, we simply bail out by means of M_USAGE - */ if (dco_enabled(o)) { - dco_check_option(M_USAGE, o); - dco_check_startup_option(M_USAGE, o); + /* check if any option should force disabling DCO */ + o->tuntap_options.disable_dco = !dco_check_option(D_DCO, o) + || !dco_check_startup_option(D_DCO, o); + } + +#ifdef _WIN32 + if (dco_enabled(o)) + { + o->windows_driver = WINDOWS_DRIVER_DCO; + } + else + { + if (o->windows_driver == WINDOWS_DRIVER_DCO) + { + msg(M_WARN, "Option --windows-driver ovpn-dco is ignored because Data Channel Offload is disabled"); + o->windows_driver = WINDOWS_DRIVER_TAP_WINDOWS6; + } + else if (o->windows_driver == WINDOWS_DRIVER_UNSPECIFIED) + { + o->windows_driver = WINDOWS_DRIVER_TAP_WINDOWS6; + } } #endif @@ -3705,6 +3718,9 @@ options_postprocess_mutate(struct options *o, struct env_set *es) o->dev_node = NULL; } + /* this depends on o->windows_driver, which is set above */ + options_postprocess_mutate_invariant(o); + /* * Save certain parms before modifying options during connect, especially * when using --pull @@ -5903,9 +5919,7 @@ add_option(struct options *options, #endif else if (streq(p[0], "disable-dco")) { -#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) options->tuntap_options.disable_dco = true; -#endif } else if (streq(p[0], "dev-node") && p[1] && !p[2]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 6d9174a4..3543308a 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -882,13 +882,11 @@ bool key_is_external(const struct options *options); static inline bool dco_enabled(const struct options *o) { -#if defined(_WIN32) - return o->windows_driver == WINDOWS_DRIVER_DCO; -#elif defined(ENABLE_DCO) +#ifdef ENABLE_DCO return !o->tuntap_options.disable_dco; #else return false; -#endif /* defined(_WIN32) */ +#endif /* ENABLE_DCO */ } #endif /* ifndef OPTIONS_H */ diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 94803acd..cb2a8fb6 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -3539,25 +3539,6 @@ read_tun(struct tuntap *tt, uint8_t *buf, int len) #elif defined(_WIN32) -static const char * -print_windows_driver(enum windows_driver_type windows_driver) -{ - switch (windows_driver) - { - case WINDOWS_DRIVER_TAP_WINDOWS6: - return "tap-windows6"; - - case WINDOWS_DRIVER_WINTUN: - return "wintun"; - - case WINDOWS_DRIVER_DCO: - return "ovpn-dco"; - - default: - return "unspecified"; - } -} - int tun_read_queue(struct tuntap *tt, int maxsize) { diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h index 1cca1cfb..24d52670 100644 --- a/src/openvpn/tun.h +++ b/src/openvpn/tun.h @@ -156,6 +156,7 @@ struct tuntap_options { struct tuntap_options { int dummy; /* not used */ + bool disable_dco; /* not used, but removes the need in #ifdefs */ }; #endif /* if defined(_WIN32) || defined(TARGET_ANDROID) */ @@ -660,6 +661,25 @@ tuntap_is_dco_win_timeout(struct tuntap *tt, int status) return tuntap_is_dco_win(tt) && (status < 0) && (openvpn_errno() == ERROR_NETNAME_DELETED); } +static const char * +print_windows_driver(enum windows_driver_type windows_driver) +{ + switch (windows_driver) + { + case WINDOWS_DRIVER_TAP_WINDOWS6: + return "tap-windows6"; + + case WINDOWS_DRIVER_WINTUN: + return "wintun"; + + case WINDOWS_DRIVER_DCO: + return "ovpn-dco"; + + default: + return "unspecified"; + } +} + #else /* ifdef _WIN32 */ static inline bool