From: Lev Stipakov Date: Wed, 15 Mar 2023 13:38:08 +0000 (+0200) Subject: Support --inactive option for DCO X-Git-Tag: v2.7_alpha1~515 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=514eefb14ace41a5790e59b81654d1d5eed60670;p=thirdparty%2Fopenvpn.git Support --inactive option for DCO 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 Acked-by: Heiko Hund 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 --- diff --git a/src/openvpn/dco_win.c b/src/openvpn/dco_win.c index 26463b387..4b414efa5 100644 --- a/src/openvpn/dco_win.c +++ b/src/openvpn/dco_win.c @@ -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; } diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 0e86b58c6..ddfd5a183 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -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"); }