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)
| ... | ... |
@@ -236,6 +236,13 @@ void dco_delete_iroutes(struct multi_context *m, struct multi_instance *mi); |
| 236 | 236 |
int dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m); |
| 237 | 237 |
|
| 238 | 238 |
/** |
| 239 |
+ * Update traffic statistics for single peer |
|
| 240 |
+ * |
|
| 241 |
+ * @param c instance context of the peer |
|
| 242 |
+ **/ |
|
| 243 |
+int dco_get_peer_stats(struct context *c); |
|
| 244 |
+ |
|
| 245 |
+/** |
|
| 239 | 246 |
* Retrieve the list of ciphers supported by the current platform |
| 240 | 247 |
* |
| 241 | 248 |
* @return list of colon-separated ciphers |
| ... | ... |
@@ -362,6 +369,12 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m) |
| 362 | 362 |
return 0; |
| 363 | 363 |
} |
| 364 | 364 |
|
| 365 |
+static inline int |
|
| 366 |
+dco_get_peer_stats(struct context *c) |
|
| 367 |
+{
|
|
| 368 |
+ return 0; |
|
| 369 |
+} |
|
| 370 |
+ |
|
| 365 | 371 |
static inline const char * |
| 366 | 372 |
dco_get_supported_ciphers() |
| 367 | 373 |
{
|
| ... | ... |
@@ -743,6 +743,13 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m) |
| 743 | 743 |
return 0; |
| 744 | 744 |
} |
| 745 | 745 |
|
| 746 |
+int |
|
| 747 |
+dco_get_peer_stats(struct context *c) |
|
| 748 |
+{
|
|
| 749 |
+ /* Not implemented. */ |
|
| 750 |
+ return 0; |
|
| 751 |
+} |
|
| 752 |
+ |
|
| 746 | 753 |
const char * |
| 747 | 754 |
dco_get_supported_ciphers() |
| 748 | 755 |
{
|
| ... | ... |
@@ -924,6 +924,13 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m) |
| 924 | 924 |
return 0; |
| 925 | 925 |
} |
| 926 | 926 |
|
| 927 |
+int |
|
| 928 |
+dco_get_peer_stats(struct context *c) |
|
| 929 |
+{
|
|
| 930 |
+ /* Not implemented. */ |
|
| 931 |
+ return 0; |
|
| 932 |
+} |
|
| 933 |
+ |
|
| 927 | 934 |
bool |
| 928 | 935 |
dco_available(int msglevel) |
| 929 | 936 |
{
|
| ... | ... |
@@ -33,6 +33,7 @@ |
| 33 | 33 |
#include "tun.h" |
| 34 | 34 |
#include "crypto.h" |
| 35 | 35 |
#include "ssl_common.h" |
| 36 |
+#include "openvpn.h" |
|
| 36 | 37 |
|
| 37 | 38 |
#include <bcrypt.h> |
| 38 | 39 |
#include <winsock2.h> |
| ... | ... |
@@ -406,6 +407,33 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m) |
| 406 | 406 |
return 0; |
| 407 | 407 |
} |
| 408 | 408 |
|
| 409 |
+int |
|
| 410 |
+dco_get_peer_stats(struct context *c) |
|
| 411 |
+{
|
|
| 412 |
+ struct tuntap *tt = c->c1.tuntap; |
|
| 413 |
+ |
|
| 414 |
+ if (!tuntap_defined(tt)) |
|
| 415 |
+ {
|
|
| 416 |
+ return -1; |
|
| 417 |
+ } |
|
| 418 |
+ |
|
| 419 |
+ OVPN_STATS stats; |
|
| 420 |
+ ZeroMemory(&stats, sizeof(OVPN_STATS)); |
|
| 421 |
+ |
|
| 422 |
+ DWORD bytes_returned = 0; |
|
| 423 |
+ if (!DeviceIoControl(tt->hand, OVPN_IOCTL_GET_STATS, NULL, 0, |
|
| 424 |
+ &stats, sizeof(stats), &bytes_returned, NULL)) |
|
| 425 |
+ {
|
|
| 426 |
+ msg(M_WARN | M_ERRNO, "DeviceIoControl(OVPN_IOCTL_GET_STATS) failed"); |
|
| 427 |
+ return -1; |
|
| 428 |
+ } |
|
| 429 |
+ |
|
| 430 |
+ c->c2.dco_read_bytes = stats.TransportBytesReceived; |
|
| 431 |
+ c->c2.dco_write_bytes = stats.TransportBytesSent; |
|
| 432 |
+ |
|
| 433 |
+ return 0; |
|
| 434 |
+} |
|
| 435 |
+ |
|
| 409 | 436 |
void |
| 410 | 437 |
dco_event_set(dco_context_t *dco, struct event_set *es, void *arg) |
| 411 | 438 |
{
|
| ... | ... |
@@ -43,6 +43,7 @@ |
| 43 | 43 |
#include "common.h" |
| 44 | 44 |
#include "manage.h" |
| 45 | 45 |
#include "openvpn.h" |
| 46 |
+#include "dco.h" |
|
| 46 | 47 |
|
| 47 | 48 |
#include "memdbg.h" |
| 48 | 49 |
|
| ... | ... |
@@ -4051,11 +4052,15 @@ management_check_bytecount(struct context *c, struct management *man, struct tim |
| 4051 | 4051 |
if (event_timeout_trigger(&man->connection.bytecount_update_interval, |
| 4052 | 4052 |
timeval, ETT_DEFAULT)) |
| 4053 | 4053 |
{
|
| 4054 |
- /* TODO: get stats from DCO */ |
|
| 4055 |
- |
|
| 4056 | 4054 |
counter_type dco_read_bytes = 0; |
| 4057 | 4055 |
counter_type dco_write_bytes = 0; |
| 4058 | 4056 |
|
| 4057 |
+ if (dco_enabled(&c->options) && (dco_get_peer_stats(c) == 0)) |
|
| 4058 |
+ {
|
|
| 4059 |
+ dco_read_bytes = c->c2.dco_read_bytes; |
|
| 4060 |
+ dco_write_bytes = c->c2.dco_write_bytes; |
|
| 4061 |
+ } |
|
| 4062 |
+ |
|
| 4059 | 4063 |
if (!(man->persist.callback.flags & MCF_SERVER)) |
| 4060 | 4064 |
{
|
| 4061 | 4065 |
man_bytecount_output_client(man, dco_read_bytes, dco_write_bytes); |