From 6361a465b3048d45739a3aa2d9a2281d773f4442 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 21 Dec 2013 21:32:07 -0800 Subject: [PATCH] library: Add new callback for obtaining TX/RX statistics The UI may want to periodically request byte/packet counts from the library without exiting the mainloop. So we'll allow it to write OC_CMD_STATS to the cmd_fd and then receive a callback. Signed-off-by: Kevin Cernekee --- libopenconnect.map.in | 1 + library.c | 6 ++++++ openconnect-internal.h | 2 ++ openconnect.h | 14 ++++++++++++++ ssl.c | 3 +++ tun.c | 6 ++++++ 6 files changed, 32 insertions(+) diff --git a/libopenconnect.map.in b/libopenconnect.map.in index 183d66ab..ef9def7e 100644 --- a/libopenconnect.map.in +++ b/libopenconnect.map.in @@ -51,6 +51,7 @@ OPENCONNECT_3.1 { openconnect_set_protect_socket_handler; openconnect_set_mobile_info; openconnect_set_xmlpost; + openconnect_set_stats_handler; } OPENCONNECT_3.0; OPENCONNECT_PRIVATE { diff --git a/library.c b/library.c index 1e58edde..b71e441f 100644 --- a/library.c +++ b/library.c @@ -556,3 +556,9 @@ void openconnect_set_protect_socket_handler(struct openconnect_info *vpninfo, { vpninfo->protect_socket = protect_socket; } + +void openconnect_set_stats_handler(struct openconnect_info *vpninfo, + openconnect_stats_vfn stats_handler) +{ + vpninfo->stats_handler = stats_handler; +} diff --git a/openconnect-internal.h b/openconnect-internal.h index faa0fb87..7dd6d285 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -288,6 +288,8 @@ struct openconnect_info { struct pkt *outgoing_queue; int outgoing_qlen; int max_qlen; + struct oc_stats stats; + openconnect_stats_vfn stats_handler; socklen_t peer_addrlen; struct sockaddr *peer_addr; diff --git a/openconnect.h b/openconnect.h index 2b2f773a..5fee59bd 100644 --- a/openconnect.h +++ b/openconnect.h @@ -187,6 +187,13 @@ struct oc_vpn_option { struct oc_vpn_option *next; }; +struct oc_stats { + uint64_t tx_pkts; + uint64_t tx_bytes; + uint64_t rx_pkts; + uint64_t rx_bytes; +}; + /****************************************************************************/ #define PRG_ERR 0 @@ -197,6 +204,7 @@ struct oc_vpn_option { /* byte commands to write into the cmd_fd */ #define OC_CMD_CANCEL 'x' #define OC_CMD_PAUSE 'p' +#define OC_CMD_STATS 's' #define RECONNECT_INTERVAL_MIN 10 #define RECONNECT_INTERVAL_MAX 100 @@ -378,6 +386,12 @@ typedef void (*openconnect_protect_socket_vfn) (void *privdata, int fd); void openconnect_set_protect_socket_handler(struct openconnect_info *vpninfo, openconnect_protect_socket_vfn protect_socket); +/* Callback for obtaining traffic stats via OC_CMD_STATS. + */ +typedef void (*openconnect_stats_vfn) (void *privdata, const struct oc_stats *stats); +void openconnect_set_stats_handler(struct openconnect_info *vpninfo, + openconnect_stats_vfn stats_handler); + /* SSL certificate capabilities. openconnect_has_pkcs11_support() means that we can accept PKCS#11 URLs in place of filenames, for the certificate and key. */ int openconnect_has_pkcs11_support(void); diff --git a/ssl.c b/ssl.c index 4dfbee61..d5894a3f 100644 --- a/ssl.c +++ b/ssl.c @@ -554,6 +554,9 @@ void check_cmd_fd(struct openconnect_info *vpninfo, fd_set *fds) case OC_CMD_PAUSE: vpninfo->got_pause_cmd = 1; break; + case OC_CMD_STATS: + if (vpninfo->stats_handler) + vpninfo->stats_handler(vpninfo->cbdata, &vpninfo->stats); } } diff --git a/tun.c b/tun.c index e2937ba5..863a189c 100644 --- a/tun.c +++ b/tun.c @@ -736,6 +736,9 @@ int tun_mainloop(struct openconnect_info *vpninfo, int *timeout) break; out_pkt->len = len - prefix_size; + vpninfo->stats.tx_pkts++; + vpninfo->stats.tx_bytes += out_pkt->len; + queue_packet(&vpninfo->outgoing_queue, out_pkt); out_pkt = NULL; @@ -758,6 +761,9 @@ int tun_mainloop(struct openconnect_info *vpninfo, int *timeout) unsigned char *data = this->data; int len = this->len; + vpninfo->stats.rx_pkts++; + vpninfo->stats.rx_bytes += len; + #ifdef TUN_HAS_AF_PREFIX if (!vpninfo->script_tun) { struct ip *iph = (void *)data;