BYTECOUNT on management interface is used to display client stats,
for example by openvpn-gui. At the moment BYTECOUNT is sent if
there is a traffic. With DCO, userspace process doesn't see data
channel traffic, BYTECOUNT is not sent and therefore stats
are not updated.
Fix displaying DCO client stats by adding a timer, which is triggerd
every n seconds, where n is set by existing management command
bytecount <n>. Output stats, taking into account stats from DCO,
when timer is triggered.
While on it, simplify bytecount routines call chains - inlining
functions which are used only once.
DCO stats fetching is not yet implemented.
Stats for the server mode (BYTECOUNT_CLI) are unaffected
by this change - to output those in timer callback we would need to
enumerate all peers, and I am not sure we want to output stats
for all peers every <n> seconds.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <20221214224220.307-1-lstipakov@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg25707.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit a9991b3eb6644785421398bff8cb3a728d131713)
| ... | ... |
@@ -771,6 +771,13 @@ process_coarse_timers(struct context *c) |
| 771 | 771 |
|
| 772 | 772 |
/* Should we ping the remote? */ |
| 773 | 773 |
check_ping_send(c); |
| 774 |
+ |
|
| 775 |
+#ifdef ENABLE_MANAGEMENT |
|
| 776 |
+ if (management) |
|
| 777 |
+ {
|
|
| 778 |
+ management_check_bytecount(c, management, &c->c2.timeval); |
|
| 779 |
+ } |
|
| 780 |
+#endif /* ENABLE_MANAGEMENT */ |
|
| 774 | 781 |
} |
| 775 | 782 |
|
| 776 | 783 |
static void |
| ... | ... |
@@ -953,7 +960,7 @@ process_incoming_link_part1(struct context *c, struct link_socket_info *lsi, boo |
| 953 | 953 |
#ifdef ENABLE_MANAGEMENT |
| 954 | 954 |
if (management) |
| 955 | 955 |
{
|
| 956 |
- management_bytes_in(management, c->c2.buf.len); |
|
| 956 |
+ management_bytes_client(management, c->c2.buf.len, 0); |
|
| 957 | 957 |
management_bytes_server(management, &c->c2.link_read_bytes, &c->c2.link_write_bytes, &c->c2.mda_context); |
| 958 | 958 |
} |
| 959 | 959 |
#endif |
| ... | ... |
@@ -1793,7 +1800,7 @@ process_outgoing_link(struct context *c) |
| 1793 | 1793 |
#ifdef ENABLE_MANAGEMENT |
| 1794 | 1794 |
if (management) |
| 1795 | 1795 |
{
|
| 1796 |
- management_bytes_out(management, size); |
|
| 1796 |
+ management_bytes_client(management, 0, size); |
|
| 1797 | 1797 |
management_bytes_server(management, &c->c2.link_read_bytes, &c->c2.link_write_bytes, &c->c2.mda_context); |
| 1798 | 1798 |
} |
| 1799 | 1799 |
#endif |
| ... | ... |
@@ -42,6 +42,7 @@ |
| 42 | 42 |
#include "ssl.h" |
| 43 | 43 |
#include "common.h" |
| 44 | 44 |
#include "manage.h" |
| 45 |
+#include "openvpn.h" |
|
| 45 | 46 |
|
| 46 | 47 |
#include "memdbg.h" |
| 47 | 48 |
|
| ... | ... |
@@ -460,32 +461,37 @@ man_status(struct management *man, const int version, struct status_output *so) |
| 460 | 460 |
static void |
| 461 | 461 |
man_bytecount(struct management *man, const int update_seconds) |
| 462 | 462 |
{
|
| 463 |
- if (update_seconds >= 0) |
|
| 463 |
+ if (update_seconds > 0) |
|
| 464 | 464 |
{
|
| 465 | 465 |
man->connection.bytecount_update_seconds = update_seconds; |
| 466 |
+ event_timeout_init(&man->connection.bytecount_update_interval, |
|
| 467 |
+ man->connection.bytecount_update_seconds, |
|
| 468 |
+ now); |
|
| 466 | 469 |
} |
| 467 | 470 |
else |
| 468 | 471 |
{
|
| 469 | 472 |
man->connection.bytecount_update_seconds = 0; |
| 473 |
+ event_timeout_clear(&man->connection.bytecount_update_interval); |
|
| 470 | 474 |
} |
| 471 | 475 |
msg(M_CLIENT, "SUCCESS: bytecount interval changed"); |
| 472 | 476 |
} |
| 473 | 477 |
|
| 474 |
-void |
|
| 475 |
-man_bytecount_output_client(struct management *man) |
|
| 478 |
+static void |
|
| 479 |
+man_bytecount_output_client(struct management *man, |
|
| 480 |
+ counter_type dco_read_bytes, |
|
| 481 |
+ counter_type dco_write_bytes) |
|
| 476 | 482 |
{
|
| 477 | 483 |
char in[32]; |
| 478 | 484 |
char out[32]; |
| 485 |
+ |
|
| 479 | 486 |
/* do in a roundabout way to work around possible mingw or mingw-glibc bug */ |
| 480 |
- openvpn_snprintf(in, sizeof(in), counter_format, man->persist.bytes_in); |
|
| 481 |
- openvpn_snprintf(out, sizeof(out), counter_format, man->persist.bytes_out); |
|
| 487 |
+ openvpn_snprintf(in, sizeof(in), counter_format, man->persist.bytes_in + dco_read_bytes); |
|
| 488 |
+ openvpn_snprintf(out, sizeof(out), counter_format, man->persist.bytes_out + dco_write_bytes); |
|
| 482 | 489 |
msg(M_CLIENT, ">BYTECOUNT:%s,%s", in, out); |
| 483 |
- man->connection.bytecount_last_update = now; |
|
| 484 | 490 |
} |
| 485 | 491 |
|
| 486 | 492 |
void |
| 487 |
-man_bytecount_output_server(struct management *man, |
|
| 488 |
- const counter_type *bytes_in_total, |
|
| 493 |
+man_bytecount_output_server(const counter_type *bytes_in_total, |
|
| 489 | 494 |
const counter_type *bytes_out_total, |
| 490 | 495 |
struct man_def_auth_context *mdac) |
| 491 | 496 |
{
|
| ... | ... |
@@ -2542,6 +2548,8 @@ man_connection_close(struct management *man) |
| 2542 | 2542 |
command_line_free(mc->in); |
| 2543 | 2543 |
buffer_list_free(mc->out); |
| 2544 | 2544 |
|
| 2545 |
+ event_timeout_clear(&mc->bytecount_update_interval); |
|
| 2546 |
+ |
|
| 2545 | 2547 |
in_extra_reset(&man->connection, IER_RESET); |
| 2546 | 2548 |
buffer_list_free(mc->ext_key_input); |
| 2547 | 2549 |
man_connection_clear(mc); |
| ... | ... |
@@ -4037,6 +4045,24 @@ management_sleep(const int n) |
| 4037 | 4037 |
} |
| 4038 | 4038 |
} |
| 4039 | 4039 |
|
| 4040 |
+void |
|
| 4041 |
+management_check_bytecount(struct context *c, struct management *man, struct timeval *timeval) |
|
| 4042 |
+{
|
|
| 4043 |
+ if (event_timeout_trigger(&man->connection.bytecount_update_interval, |
|
| 4044 |
+ timeval, ETT_DEFAULT)) |
|
| 4045 |
+ {
|
|
| 4046 |
+ /* TODO: get stats from DCO */ |
|
| 4047 |
+ |
|
| 4048 |
+ counter_type dco_read_bytes = 0; |
|
| 4049 |
+ counter_type dco_write_bytes = 0; |
|
| 4050 |
+ |
|
| 4051 |
+ if (!(man->persist.callback.flags & MCF_SERVER)) |
|
| 4052 |
+ {
|
|
| 4053 |
+ man_bytecount_output_client(man, dco_read_bytes, dco_write_bytes); |
|
| 4054 |
+ } |
|
| 4055 |
+ } |
|
| 4056 |
+} |
|
| 4057 |
+ |
|
| 4040 | 4058 |
#else /* ifdef ENABLE_MANAGEMENT */ |
| 4041 | 4059 |
|
| 4042 | 4060 |
void |
| ... | ... |
@@ -295,7 +295,7 @@ struct man_connection {
|
| 295 | 295 |
bool log_realtime; |
| 296 | 296 |
bool echo_realtime; |
| 297 | 297 |
int bytecount_update_seconds; |
| 298 |
- time_t bytecount_last_update; |
|
| 298 |
+ struct event_timeout bytecount_update_interval; |
|
| 299 | 299 |
|
| 300 | 300 |
const char *up_query_type; |
| 301 | 301 |
int up_query_mode; |
| ... | ... |
@@ -512,55 +512,27 @@ void management_auth_token(struct management *man, const char *token); |
| 512 | 512 |
* These functions drive the bytecount in/out counters. |
| 513 | 513 |
*/ |
| 514 | 514 |
|
| 515 |
-void man_bytecount_output_client(struct management *man); |
|
| 516 |
- |
|
| 517 |
-static inline void |
|
| 518 |
-man_bytecount_possible_output_client(struct management *man) |
|
| 519 |
-{
|
|
| 520 |
- if (man->connection.bytecount_update_seconds > 0 |
|
| 521 |
- && now >= man->connection.bytecount_last_update |
|
| 522 |
- + man->connection.bytecount_update_seconds) |
|
| 523 |
- {
|
|
| 524 |
- man_bytecount_output_client(man); |
|
| 525 |
- } |
|
| 526 |
-} |
|
| 527 |
- |
|
| 528 |
-static inline void |
|
| 529 |
-management_bytes_out_client(struct management *man, const int size) |
|
| 530 |
-{
|
|
| 531 |
- man->persist.bytes_out += size; |
|
| 532 |
- man_bytecount_possible_output_client(man); |
|
| 533 |
-} |
|
| 534 |
- |
|
| 535 |
-static inline void |
|
| 536 |
-management_bytes_in_client(struct management *man, const int size) |
|
| 537 |
-{
|
|
| 538 |
- man->persist.bytes_in += size; |
|
| 539 |
- man_bytecount_possible_output_client(man); |
|
| 540 |
-} |
|
| 541 |
- |
|
| 542 |
-static inline void |
|
| 543 |
-management_bytes_out(struct management *man, const int size) |
|
| 544 |
-{
|
|
| 545 |
- if (!(man->persist.callback.flags & MCF_SERVER)) |
|
| 546 |
- {
|
|
| 547 |
- management_bytes_out_client(man, size); |
|
| 548 |
- } |
|
| 549 |
-} |
|
| 515 |
+void |
|
| 516 |
+management_check_bytecount(struct context *c, |
|
| 517 |
+ struct management *man, |
|
| 518 |
+ struct timeval *timeval); |
|
| 550 | 519 |
|
| 551 | 520 |
static inline void |
| 552 |
-management_bytes_in(struct management *man, const int size) |
|
| 521 |
+management_bytes_client(struct management *man, |
|
| 522 |
+ const int size_in, |
|
| 523 |
+ const int size_out) |
|
| 553 | 524 |
{
|
| 554 | 525 |
if (!(man->persist.callback.flags & MCF_SERVER)) |
| 555 | 526 |
{
|
| 556 |
- management_bytes_in_client(man, size); |
|
| 527 |
+ man->persist.bytes_in += size_in; |
|
| 528 |
+ man->persist.bytes_out += size_out; |
|
| 557 | 529 |
} |
| 558 | 530 |
} |
| 559 | 531 |
|
| 560 |
-void man_bytecount_output_server(struct management *man, |
|
| 561 |
- const counter_type *bytes_in_total, |
|
| 562 |
- const counter_type *bytes_out_total, |
|
| 563 |
- struct man_def_auth_context *mdac); |
|
| 532 |
+void |
|
| 533 |
+man_bytecount_output_server(const counter_type *bytes_in_total, |
|
| 534 |
+ const counter_type *bytes_out_total, |
|
| 535 |
+ struct man_def_auth_context *mdac); |
|
| 564 | 536 |
|
| 565 | 537 |
static inline void |
| 566 | 538 |
management_bytes_server(struct management *man, |
| ... | ... |
@@ -570,9 +542,9 @@ management_bytes_server(struct management *man, |
| 570 | 570 |
{
|
| 571 | 571 |
if (man->connection.bytecount_update_seconds > 0 |
| 572 | 572 |
&& now >= mdac->bytecount_last_update + man->connection.bytecount_update_seconds |
| 573 |
- && (mdac->flags & (DAF_CONNECTION_ESTABLISHED|DAF_CONNECTION_CLOSED)) == DAF_CONNECTION_ESTABLISHED) |
|
| 573 |
+ && (mdac->flags & (DAF_CONNECTION_ESTABLISHED | DAF_CONNECTION_CLOSED)) == DAF_CONNECTION_ESTABLISHED) |
|
| 574 | 574 |
{
|
| 575 |
- man_bytecount_output_server(man, bytes_in_total, bytes_out_total, mdac); |
|
| 575 |
+ man_bytecount_output_server(bytes_in_total, bytes_out_total, mdac); |
|
| 576 | 576 |
} |
| 577 | 577 |
} |
| 578 | 578 |
|