From patchwork Thu Nov 24 16:26:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 2852 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director14.mail.ord1d.rsapps.net ([172.31.255.6]) by backend30.mail.ord1d.rsapps.net with LMTP id OD5CH3abf2NKRQAAIUCqbw (envelope-from ) for ; Thu, 24 Nov 2022 11:27:34 -0500 Received: from proxy1.mail.iad3b.rsapps.net ([172.31.255.6]) by director14.mail.ord1d.rsapps.net with LMTP id aEBwHnabf2NLXgAAeJ7fFg (envelope-from ) for ; Thu, 24 Nov 2022 11:27:34 -0500 Received: from smtp31.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy1.mail.iad3b.rsapps.net with LMTPS id KBUTGXabf2OGKQAALM5PBw (envelope-from ) for ; Thu, 24 Nov 2022 11:27:34 -0500 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: smtp31.gate.iad3b.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; dmarc=none (p=nil; dis=none) header.from=rfc2549.org X-Suspicious-Flag: YES X-Classification-ID: e5f98986-6c14-11ed-8ea4-52540005277f-1-1 Received: from [216.105.38.7] ([216.105.38.7:34790] helo=lists.sourceforge.net) by smtp31.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 1E/99-09205-57B9F736; Thu, 24 Nov 2022 11:27:34 -0500 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1oyF3x-0000ZL-TS; Thu, 24 Nov 2022 16:26:57 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1oyF3w-0000ZF-O0 for openvpn-devel@lists.sourceforge.net; Thu, 24 Nov 2022 16:26:56 +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:To:From:Sender:Reply-To:Cc: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=6ve1CWHVMhHNzM1B86xY9gF8RjkVfIV4MDY8AfVBpRM=; b=AsHsJ0TJUvjhLElpX9Q43v8oRK UT6Sgfw62OPuKkNBSQfsvYITN1z8zWhAK78eUmcbk3CGDaTIp4cKAM5o1xz5EWob/m6V6iV62JvEK peNPQL7xVAI4shftALmTnDNzLH34lHBpGYVkufkY+T1/CpU9a0/KVL8SrEHfwQKww+Fk=; 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:To:From:Sender:Reply-To:Cc: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=6ve1CWHVMhHNzM1B86xY9gF8RjkVfIV4MDY8AfVBpRM=; b=TbWup+CzLf0+/fouUYjF33ANcs rnkszR8d3tL4A4uTgRdix89LSOUMD4YQOeWOx5a+q9M1he4l+w44s+MlJfdfM6Qu73EC7UVzNrt0p v1TTabcbHP4E9wSXylqqXFBBjgZofeDqeCaGSlVApuH+peOwlSLFTcqXqzkUBi996tsE=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1oyF3s-005IZX-B3 for openvpn-devel@lists.sourceforge.net; Thu, 24 Nov 2022 16:26:56 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.95 (FreeBSD)) (envelope-from ) id 1oyF3i-000264-1W for openvpn-devel@lists.sourceforge.net; Thu, 24 Nov 2022 17:26:42 +0100 Received: (nullmailer pid 3173164 invoked by uid 10006); Thu, 24 Nov 2022 16:26:42 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Thu, 24 Nov 2022 17:26:42 +0100 Message-Id: <20221124162642.3173118-1-arne@rfc2549.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221012133457.1927871-1-arne@rfc2549.org> References: <20221012133457.1927871-1-arne@rfc2549.org> MIME-Version: 1.0 X-Spam-Report: Spam detection software, running on the system "util-spamd-1.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: For tcp this makes no difference as the remote address of the socket never changes. For udp this allows OpenVPN to differentiate if a reconnecting client is using the same address as before or from a [...] Content analysis details: (0.3 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 SPF_NONE SPF: sender does not publish an SPF Record X-Headers-End: 1oyF3s-005IZX-B3 Subject: [Openvpn-devel] [PATCH v3 1/3] Move dco_installed from sock->info to sock->info.lsa.actual 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox For tcp this makes no difference as the remote address of the socket never changes. For udp this allows OpenVPN to differentiate if a reconnecting client is using the same address as before or from a different one. This allow sending via the normal userspace socket in that case. Patch v2: fix windows code path Patch v3: fix mtcp server code path Signed-off-by: Arne Schwabe --- src/openvpn/dco.c | 27 +++++++++++++++++++++++---- src/openvpn/dco_linux.c | 2 +- src/openvpn/forward.c | 8 ++++---- src/openvpn/init.c | 2 +- src/openvpn/mtcp.c | 6 +++--- src/openvpn/socket.c | 8 ++++---- src/openvpn/socket.h | 12 ++++++------ 7 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c index a76cdd0cd..f190d038b 100644 --- a/src/openvpn/dco.c +++ b/src/openvpn/dco.c @@ -426,6 +426,22 @@ dco_check_pull_options(int msglevel, const struct options *o) return true; } +static void +addr_set_dco_installed(struct context *c) +{ + /* We ensure that all addresses we currently hold have the dco_installed + * bit set */ + for (int i = 0; i < KEY_SCAN_SIZE; ++i) + { + struct key_state *ks = get_key_scan(c->c2.tls_multi, i); + if (ks) + { + ks->remote_addr.dco_installed = true; + } + } + get_link_socket_info(c)->lsa->actual.dco_installed = true; +} + int dco_p2p_add_new_peer(struct context *c) { @@ -438,6 +454,8 @@ dco_p2p_add_new_peer(struct context *c) ASSERT(ls->info.connection_established); + addr_set_dco_installed(c); + struct sockaddr *remoteaddr = &ls->info.lsa->actual.dest.addr.sa; struct tls_multi *multi = c->c2.tls_multi; int ret = dco_new_peer(&c->c1.tuntap->dco, multi->peer_id, @@ -448,7 +466,7 @@ dco_p2p_add_new_peer(struct context *c) } c->c2.tls_multi->dco_peer_added = true; - c->c2.link_socket->info.dco_installed = true; + c->c2.link_socket->info.lsa->actual.dco_installed = true; return 0; } @@ -522,11 +540,12 @@ dco_multi_add_new_peer(struct multi_context *m, struct multi_instance *mi) { struct context *c = &mi->context; - int peer_id = mi->context.c2.tls_multi->peer_id; + int peer_id = c->c2.tls_multi->peer_id; struct sockaddr *remoteaddr, *localaddr = NULL; struct sockaddr_storage local = { 0 }; int sd = c->c2.link_socket->sd; + if (c->mode == CM_CHILD_TCP) { /* the remote address will be inferred from the TCP socket endpoint */ @@ -537,9 +556,9 @@ dco_multi_add_new_peer(struct multi_context *m, struct multi_instance *mi) ASSERT(c->c2.link_socket_info->connection_established); remoteaddr = &c->c2.link_socket_info->lsa->actual.dest.addr.sa; } + addr_set_dco_installed(c); /* In server mode we need to fetch the remote addresses from the push config */ - struct in_addr vpn_ip4 = { 0 }; struct in_addr *vpn_addr4 = NULL; if (c->c2.push_ifconfig_defined) @@ -575,7 +594,7 @@ dco_multi_add_new_peer(struct multi_context *m, struct multi_instance *mi) { msg(D_DCO|M_ERRNO, "error closing TCP socket after DCO handover"); } - c->c2.link_socket->info.dco_installed = true; + c->c2.link_socket->info.lsa->actual.dco_installed = true; c->c2.link_socket->sd = SOCKET_UNDEFINED; } diff --git a/src/openvpn/dco_linux.c b/src/openvpn/dco_linux.c index 98e10507b..109358205 100644 --- a/src/openvpn/dco_linux.c +++ b/src/openvpn/dco_linux.c @@ -285,7 +285,7 @@ ovpn_nl_cb_finish(struct nl_msg (*msg) __attribute__ ((unused)), void *arg) * * We pass the error code to the user by means of a variable pointed by *arg * (supplied by the user when setting this callback) and we parse the kernel - * reply to see if it contains a human readable error. If found, it is printed. + * reply to see if it contains a human-readable error. If found, it is printed. */ static int ovpn_nl_cb_error(struct sockaddr_nl (*nla) __attribute__ ((unused)), diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 20d9a7598..622be8411 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -1643,13 +1643,13 @@ process_ip_header(struct context *c, unsigned int flags, struct buffer *buf) * standard Overlapped I/O. * * Hide that complexity (...especially if more platforms show up - * in future...) in a small inline function. + * in the future...) in a small inline function. */ static inline bool -should_use_dco_socket(struct link_socket *sock) +should_use_dco_socket(struct link_socket_actual *actual) { #if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) - return sock->info.dco_installed; + return actual->dco_installed; #else return false; #endif @@ -1728,7 +1728,7 @@ process_outgoing_link(struct context *c) socks_preprocess_outgoing_link(c, &to_addr, &size_delta); /* Send packet */ - if (should_use_dco_socket(c->c2.link_socket)) + if (should_use_dco_socket(c->c2.to_link_addr)) { size = dco_do_write(&c->c1.tuntap->dco, c->c2.tls_multi->peer_id, diff --git a/src/openvpn/init.c b/src/openvpn/init.c index c2154b8dd..1b30c8f0a 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -3678,7 +3678,7 @@ do_close_link_socket(struct context *c) * closed in do_close_tun(). Set it to UNDEFINED so * we won't use WinSock API to close it. */ if (tuntap_is_dco_win(c->c1.tuntap) && c->c2.link_socket - && c->c2.link_socket->info.dco_installed) + && c->c2.link_socket->info.lsa->actual.dco_installed) { c->c2.link_socket->sd = SOCKET_UNDEFINED; } diff --git a/src/openvpn/mtcp.c b/src/openvpn/mtcp.c index 1abb903f2..07da15a6d 100644 --- a/src/openvpn/mtcp.c +++ b/src/openvpn/mtcp.c @@ -402,7 +402,7 @@ multi_tcp_wait_lite(struct multi_context *m, struct multi_instance *mi, const in tv_clear(&c->c2.timeval); /* ZERO-TIMEOUT */ - if (mi && mi->context.c2.link_socket->info.dco_installed) + if (mi && mi->context.c2.link_socket->info.lsa->actual.dco_installed) { /* If we got a socket that has been handed over to the kernel * we must not call the normal socket function to figure out @@ -537,7 +537,7 @@ multi_tcp_dispatch(struct multi_context *m, struct multi_instance *mi, const int case TA_INITIAL: ASSERT(mi); - if (!mi->context.c2.link_socket->info.dco_installed) + if (!mi->context.c2.link_socket->info.lsa->actual.dco_installed) { multi_tcp_set_global_rw_flags(m, mi); } @@ -590,7 +590,7 @@ multi_tcp_post(struct multi_context *m, struct multi_instance *mi, const int act } else { - if (!c->c2.link_socket->info.dco_installed) + if (!c->c2.link_socket->info.lsa->actual.dco_installed) { multi_tcp_set_global_rw_flags(m, mi); } diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c index 4a9825619..82787f9f2 100644 --- a/src/openvpn/socket.c +++ b/src/openvpn/socket.c @@ -2147,7 +2147,7 @@ create_socket_dco_win(struct context *c, struct link_socket *sock, get_server_poll_remaining_time(sock->server_poll_timeout), signal_received); - sock->info.dco_installed = true; + sock->info.lsa->actual.dco_installed = true; if (*signal_received) { @@ -3480,7 +3480,7 @@ link_socket_write_udp_posix_sendmsg(struct link_socket *sock, static int socket_get_last_error(const struct link_socket *sock) { - if (sock->info.dco_installed) + if (sock->info.lsa->actual.dco_installed) { return GetLastError(); } @@ -3521,7 +3521,7 @@ socket_recv_queue(struct link_socket *sock, int maxsize) ASSERT(ResetEvent(sock->reads.overlapped.hEvent)); sock->reads.flags = 0; - if (sock->info.dco_installed) + if (sock->info.lsa->actual.dco_installed) { status = ReadFile((HANDLE)sock->sd, wsabuf[0].buf, wsabuf[0].len, &sock->reads.size, &sock->reads.overlapped); @@ -3626,7 +3626,7 @@ socket_send_queue(struct link_socket *sock, struct buffer *buf, const struct lin ASSERT(ResetEvent(sock->writes.overlapped.hEvent)); sock->writes.flags = 0; - if (sock->info.dco_installed) + if (sock->info.lsa->actual.dco_installed) { status = WriteFile((HANDLE)sock->sd, wsabuf[0].buf, wsabuf[0].len, &sock->writes.size, &sock->writes.overlapped); diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h index 94c8b6dff..929ef8187 100644 --- a/src/openvpn/socket.h +++ b/src/openvpn/socket.h @@ -88,6 +88,7 @@ struct link_socket_actual /*int dummy;*/ /* add offset to force a bug if dest not explicitly dereferenced */ struct openvpn_sockaddr dest; + bool dco_installed; #if ENABLE_IP_PKTINFO union { #if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST) @@ -121,7 +122,6 @@ struct link_socket_info sa_family_t af; /* Address family like AF_INET, AF_INET6 or AF_UNSPEC*/ bool bind_ipv6_only; int mtu_changed; /* Set to true when mtu value is changed */ - bool dco_installed; }; /* @@ -1036,9 +1036,9 @@ link_socket_read_udp_win32(struct link_socket *sock, struct link_socket_actual *from) { sockethandle_t sh = { .s = sock->sd }; - if (sock->info.dco_installed) + if (sock->info.lsa->actual.dco_installed) { - from->dest = sock->info.lsa->actual.dest; + *from = sock->info.lsa->actual; sh.is_handle = true; } return sockethandle_finalize(sh, &sock->reads, buf, from); @@ -1059,7 +1059,7 @@ link_socket_read(struct link_socket *sock, struct link_socket_actual *from) { if (proto_is_udp(sock->info.proto) - || sock->info.dco_installed) + || sock->info.lsa->actual.dco_installed) /* unified UDPv4 and UDPv6, for DCO the kernel * will strip the length header */ { @@ -1102,7 +1102,7 @@ link_socket_write_win32(struct link_socket *sock, { int err = 0; int status = 0; - sockethandle_t sh = { .s = sock->sd, .is_handle = sock->info.dco_installed }; + sockethandle_t sh = { .s = sock->sd, .is_handle = sock->info.lsa->actual.dco_installed }; if (overlapped_io_active(&sock->writes)) { status = sockethandle_finalize(sh, &sock->writes, NULL, NULL); @@ -1176,7 +1176,7 @@ link_socket_write(struct link_socket *sock, struct buffer *buf, struct link_socket_actual *to) { - if (proto_is_udp(sock->info.proto) || sock->info.dco_installed) + if (proto_is_udp(sock->info.proto) || to->dco_installed) { /* unified UDPv4 and UDPv6 and DCO (kernel adds size header) */ return link_socket_write_udp(sock, buf, to);