]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Introduce dco_get_peer_stats API and Windows implementation
authorLev Stipakov <lev@openvpn.net>
Wed, 14 Dec 2022 21:14:26 +0000 (23:14 +0200)
committerGert Doering <gert@greenie.muc.de>
Thu, 15 Dec 2022 12:35:16 +0000 (13:35 +0100)
dco_get_peer_stats fetches stats for a single peer. This is mostly
useful in client mode. So far only Windows implements that.

Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20221214211426.227-1-lstipakov@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg25703.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit 74d5ece4a035fbbd962ba5ea73c19118b82f8f45)

src/openvpn/dco.h
src/openvpn/dco_freebsd.c
src/openvpn/dco_linux.c
src/openvpn/dco_win.c
src/openvpn/manage.c

index 9a34d5b6c43ba0d8a903c24d766400a6783b0ffd..866aa0fb50eb2e2c790067f8bde1c612f7b17756 100644 (file)
@@ -235,6 +235,13 @@ void dco_delete_iroutes(struct multi_context *m, struct multi_instance *mi);
  **/
 int dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m);
 
+/**
+ * Update traffic statistics for single peer
+ *
+ * @param c   instance context of the peer
+ **/
+int dco_get_peer_stats(struct context *c);
+
 /**
  * Retrieve the list of ciphers supported by the current platform
  *
@@ -362,6 +369,12 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m)
     return 0;
 }
 
+static inline int
+dco_get_peer_stats(struct context *c)
+{
+    return 0;
+}
+
 static inline const char *
 dco_get_supported_ciphers()
 {
index 550a13a8bdb0d6fe9c266ce22bfe48156ce1a396..7f5e69e3e1781bb836f476d0b15abe8f7641eaf3 100644 (file)
@@ -743,6 +743,13 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m)
     return 0;
 }
 
+int
+dco_get_peer_stats(struct context *c)
+{
+    /* Not implemented. */
+    return 0;
+}
+
 const char *
 dco_get_supported_ciphers()
 {
index 200d0b194fede7935cfbc763d94fb2e960ae70c4..222537fc1405473e2149cdf5850b5334b368b71e 100644 (file)
@@ -924,6 +924,13 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m)
     return 0;
 }
 
+int
+dco_get_peer_stats(struct context *c)
+{
+    /* Not implemented. */
+    return 0;
+}
+
 bool
 dco_available(int msglevel)
 {
index 675dece2e228352ba40b75d26218319f495f1b88..0d0d794608c638a60729337834144010c95453e0 100644 (file)
@@ -33,6 +33,7 @@
 #include "tun.h"
 #include "crypto.h"
 #include "ssl_common.h"
+#include "openvpn.h"
 
 #include <bcrypt.h>
 #include <winsock2.h>
@@ -406,6 +407,33 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m)
     return 0;
 }
 
+int
+dco_get_peer_stats(struct context *c)
+{
+    struct tuntap *tt = c->c1.tuntap;
+
+    if (!tuntap_defined(tt))
+    {
+        return -1;
+    }
+
+    OVPN_STATS stats;
+    ZeroMemory(&stats, sizeof(OVPN_STATS));
+
+    DWORD bytes_returned = 0;
+    if (!DeviceIoControl(tt->hand, OVPN_IOCTL_GET_STATS, NULL, 0,
+                         &stats, sizeof(stats), &bytes_returned, NULL))
+    {
+        msg(M_WARN | M_ERRNO, "DeviceIoControl(OVPN_IOCTL_GET_STATS) failed");
+        return -1;
+    }
+
+    c->c2.dco_read_bytes = stats.TransportBytesReceived;
+    c->c2.dco_write_bytes = stats.TransportBytesSent;
+
+    return 0;
+}
+
 void
 dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
 {
index c2c5da568fc847654eefbccd035ecbb385d0e1b5..9349b62ad00030419d3c1c5f696e6bf686195a87 100644 (file)
@@ -43,6 +43,7 @@
 #include "common.h"
 #include "manage.h"
 #include "openvpn.h"
+#include "dco.h"
 
 #include "memdbg.h"
 
@@ -4051,11 +4052,15 @@ management_check_bytecount(struct context *c, struct management *man, struct tim
     if (event_timeout_trigger(&man->connection.bytecount_update_interval,
                               timeval, ETT_DEFAULT))
     {
-        /* TODO: get stats from DCO */
-
         counter_type dco_read_bytes = 0;
         counter_type dco_write_bytes = 0;
 
+        if (dco_enabled(&c->options) && (dco_get_peer_stats(c) == 0))
+        {
+            dco_read_bytes = c->c2.dco_read_bytes;
+            dco_write_bytes = c->c2.dco_write_bytes;
+        }
+
         if (!(man->persist.callback.flags & MCF_SERVER))
         {
             man_bytecount_output_client(man, dco_read_bytes, dco_write_bytes);