]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Support --inactive option for DCO
authorLev Stipakov <lev@openvpn.net>
Wed, 15 Mar 2023 13:38:08 +0000 (15:38 +0200)
committerGert Doering <gert@greenie.muc.de>
Fri, 17 Mar 2023 12:09:54 +0000 (13:09 +0100)
When DCO is in use, userland doesn't see any traffic
which breaks --inactive option.

Fix by adding inactivity check to inactivity timeout
callback. Get the cumulative tun bytes count (ping packets
are excluded) from DCO and compare it to the previous value
stored in c2.inactivity_bytes. Reset inactivity timer and
update c2.inactivity_bytes if amount of new bytes exceeds
inactivity_minimum_bytes, otherwise terminate session
due to inactivity.

Github: Fixes OpenVPN/openvpn#228

Currently works only on Windows, since we don't yet have
single peer stats implementation for Linux and FreeBSD.

Change-Id: Ib417b965bc4a2c17b51935b43c9627b106716526
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Heiko Hund <heiko@ist.eigentlich.net>
Message-Id: <20230315133808.1550-1-lstipakov@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg26421.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
src/openvpn/dco_win.c
src/openvpn/forward.c

index 26463b387dea6ee38c6e417dd84a2e3b32b22b1e..4b414efa56d78453ee39cbb2fd49efe97e74b9d8 100644 (file)
@@ -429,6 +429,8 @@ dco_get_peer_stats(struct context *c)
 
     c->c2.dco_read_bytes = stats.TransportBytesReceived;
     c->c2.dco_write_bytes = stats.TransportBytesSent;
+    c->c2.tun_read_bytes = stats.TunBytesReceived;
+    c->c2.tun_write_bytes = stats.TunBytesSent;
 
     return 0;
 }
index 0e86b58c67746db3d8f51172ed43b954c4a99850..ddfd5a1835815614175dd8fe211d5e97ba4f4356 100644 (file)
@@ -460,10 +460,33 @@ check_add_routes(struct context *c)
 
 /*
  * Should we exit due to inactivity timeout?
+ *
+ * In the non-dco case, the timeout is reset via register_activity()
+ * whenever there is sufficient activity on tun or link, so this function
+ * is only ever called to raise the TERM signal.
+ *
+ * With DCO, OpenVPN does not see incoming or outgoing data packets anymore
+ * and the logic needs to change - we permit the event to trigger and check
+ * kernel DCO counters here, returning and rearming the timer if there was
+ * sufficient traffic.
  */
 static void
 check_inactivity_timeout(struct context *c)
 {
+    if (dco_enabled(&c->options) && dco_get_peer_stats(c) == 0)
+    {
+        int64_t tot_bytes = c->c2.tun_read_bytes + c->c2.tun_write_bytes;
+        int64_t new_bytes = tot_bytes - c->c2.inactivity_bytes;
+
+        if (new_bytes >= c->options.inactivity_minimum_bytes)
+        {
+            c->c2.inactivity_bytes = tot_bytes;
+            event_timeout_reset(&c->c2.inactivity_interval);
+
+            return;
+        }
+    }
+
     msg(M_INFO, "Inactivity timeout (--inactive), exiting");
     register_signal(c->sig, SIGTERM, "inactive");
 }