OpenVPN 3 Core Library
Loading...
Searching...
No Matches
sessionstats.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// A class that handles statistics tracking in an OpenVPN session
13
14#ifndef OPENVPN_LOG_SESSIONSTATS_H
15#define OPENVPN_LOG_SESSIONSTATS_H
16
17#include <cstring>
18
21#include <openvpn/common/rc.hpp>
23#include <openvpn/time/time.hpp>
24
25namespace openvpn {
26
27class SessionStats : public RC<thread_safe_refcount>
28{
29 public:
31 using inc_callback_t = std::function<void(const count_t value)>;
32
33 enum Stats
34 {
35 // operating stats
36 BYTES_IN = 0, // network bytes in
37 BYTES_OUT, // network bytes out
38 PACKETS_IN, // network packets in
39 PACKETS_OUT, // network packets out
40 TUN_BYTES_IN, // tun/tap bytes in
41 TUN_BYTES_OUT, // tun/tap bytes out
42 TUN_PACKETS_IN, // tun/tap packets in
43 TUN_PACKETS_OUT, // tun/tap packets out
45 };
46
48 : verbose_(false)
49 {
50 std::memset((void *)stats_, 0, sizeof(stats_));
51 }
52
53 virtual void error(const size_t type, const std::string *text = nullptr)
54 {
55 }
56
57 // if true, clients may provide additional detail to error() method above
58 // via text argument.
59 bool verbose() const
60 {
61 return verbose_;
62 }
63
64#ifdef OPENVPN_STATS_VIRTUAL
65 virtual
66#endif
67 void
68 inc_stat(const size_t type, const count_t value)
69 {
70 if (type < N_STATS)
71 {
72 stats_[type] += value;
73 if (auto lock = inc_callbacks_[type].lock())
74 std::invoke(*lock, value);
75 }
76 }
77
78 count_t get_stat(const size_t type) const
79 {
80 if (type < N_STATS)
81 return stats_[type];
82 else
83 return 0;
84 }
85
86 count_t get_stat_fast(const size_t type) const
87 {
88 return stats_[type];
89 }
90
91 static const char *stat_name(const size_t type)
92 {
93 static const char *names[] = {
94 "BYTES_IN",
95 "BYTES_OUT",
96 "PACKETS_IN",
97 "PACKETS_OUT",
98 "TUN_BYTES_IN",
99 "TUN_BYTES_OUT",
100 "TUN_PACKETS_IN",
101 "TUN_PACKETS_OUT",
102 };
103
104 if (type < N_STATS)
105 return names[type];
106 else
107 return "UNKNOWN_STAT_TYPE";
108 }
109
111 {
113 }
114
116 {
118 }
119
120 struct DCOTransportSource : public virtual RC<thread_unsafe_refcount>
121 {
123
124 struct Data
125 {
130
135
136 Data() = default;
137
138 Data(count_t transport_bytes_in_arg, count_t transport_bytes_out_arg)
139 : transport_bytes_in(transport_bytes_in_arg),
140 transport_bytes_out(transport_bytes_out_arg)
141 {
142 }
143
144 Data(count_t transport_bytes_in_arg, count_t transport_bytes_out_arg, count_t tun_bytes_in_arg, count_t tun_bytes_out_arg)
145 : transport_bytes_in(transport_bytes_in_arg),
146 transport_bytes_out(transport_bytes_out_arg),
147 tun_bytes_in(tun_bytes_in_arg), tun_bytes_out(tun_bytes_out_arg)
148 {
149 }
150
151 Data(count_t transport_bytes_in_arg,
152 count_t transport_bytes_out_arg,
153 count_t tun_bytes_in_arg,
154 count_t tun_bytes_out_arg,
155 count_t transport_pkts_in_arg,
156 count_t transport_pkts_out_arg,
157 count_t tun_pkts_in_arg,
158 count_t tun_pkts_out_arg)
159
160 : transport_bytes_in(transport_bytes_in_arg),
161 transport_bytes_out(transport_bytes_out_arg),
162 tun_bytes_in(tun_bytes_in_arg),
163 tun_bytes_out(tun_bytes_out_arg),
164 transport_pkts_in(transport_pkts_in_arg),
165 transport_pkts_out(transport_pkts_out_arg),
166 tun_pkts_in(tun_pkts_in_arg),
167 tun_pkts_out(tun_pkts_out_arg)
168 {
169 }
170
171 Data operator-(const Data &rhs) const
172 {
173 Data data;
175 data.transport_bytes_in = transport_bytes_in - rhs.transport_bytes_in;
177 data.transport_bytes_out = transport_bytes_out - rhs.transport_bytes_out;
178 if (tun_bytes_in > rhs.tun_bytes_in)
179 data.tun_bytes_in = tun_bytes_in - rhs.tun_bytes_in;
181 data.tun_bytes_out = tun_bytes_out - rhs.tun_bytes_out;
183 data.transport_pkts_in = transport_pkts_in - rhs.transport_pkts_in;
185 data.transport_pkts_out = transport_pkts_out - rhs.transport_pkts_out;
186 if (tun_pkts_in > rhs.tun_pkts_in)
187 data.tun_pkts_in = tun_pkts_in - rhs.tun_pkts_in;
188 if (tun_pkts_out > rhs.tun_pkts_out)
189 data.tun_pkts_out = tun_pkts_out - rhs.tun_pkts_out;
190 return data;
191 }
192 };
193
195 };
196
198 {
199 dco_.reset(source);
200 }
201
203 {
204 if (dco_)
205 {
207
208 if (data.transport_bytes_in > 0)
209 {
211 }
212
213 stats_[BYTES_IN] += data.transport_bytes_in;
214 stats_[BYTES_OUT] += data.transport_bytes_out;
215 stats_[TUN_BYTES_IN] += data.tun_bytes_in;
216 stats_[TUN_BYTES_OUT] += data.tun_bytes_out;
217 stats_[PACKETS_IN] += data.transport_pkts_in;
218 stats_[PACKETS_OUT] += data.transport_pkts_out;
219 stats_[TUN_PACKETS_IN] += data.tun_pkts_in;
220 stats_[TUN_PACKETS_OUT] += data.tun_pkts_out;
221
222 return true;
223 }
224
225 return false;
226 }
227
237 [[nodiscard]] std::shared_ptr<inc_callback_t> set_inc_callback(Stats stat, inc_callback_t callback)
238 {
239 auto cb_ptr = std::make_shared<inc_callback_t>(callback);
240 inc_callbacks_[stat] = cb_ptr;
241 return cb_ptr;
242 }
243
244 protected:
245 void session_stats_set_verbose(const bool v)
246 {
247 verbose_ = v;
248 }
249
250 private:
255 std::array<std::weak_ptr<inc_callback_t>, N_STATS> inc_callbacks_;
256};
257
258} // namespace openvpn
259
260#endif // OPENVPN_LOG_SESSIONSTATS_H
The smart pointer class.
Definition rc.hpp:119
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
Definition rc.hpp:290
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Definition rc.hpp:912
RCPtr< SessionStats > Ptr
std::array< std::weak_ptr< inc_callback_t >, N_STATS > inc_callbacks_
count_t get_stat_fast(const size_t type) const
virtual void error(const size_t type, const std::string *text=nullptr)
volatile count_t stats_[N_STATS]
void dco_configure(SessionStats::DCOTransportSource *source)
std::function< void(const count_t value)> inc_callback_t
void inc_stat(const size_t type, const count_t value)
DCOTransportSource::Ptr dco_
std::shared_ptr< inc_callback_t > set_inc_callback(Stats stat, inc_callback_t callback)
Sets a callback to be triggered upon increment of stats.
const Time & last_packet_received() const
void session_stats_set_verbose(const bool v)
void update_last_packet_received(const Time &now)
static const char * stat_name(const size_t type)
count_t get_stat(const size_t type) const
static TimeType now()
Definition time.hpp:305
Support deferred server-side state creation when client connects.
Definition ovpncli.cpp:95
long long count_t
Definition count.hpp:16
Data(count_t transport_bytes_in_arg, count_t transport_bytes_out_arg, count_t tun_bytes_in_arg, count_t tun_bytes_out_arg, count_t transport_pkts_in_arg, count_t transport_pkts_out_arg, count_t tun_pkts_in_arg, count_t tun_pkts_out_arg)
Data(count_t transport_bytes_in_arg, count_t transport_bytes_out_arg, count_t tun_bytes_in_arg, count_t tun_bytes_out_arg)
Data(count_t transport_bytes_in_arg, count_t transport_bytes_out_arg)