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 : unsigned int
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] = 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 return 0;
83 }
84
85 count_t get_stat_fast(const size_t type) const
86 {
87 return stats_[type];
88 }
89
90 static const char *stat_name(const size_t type)
91 {
92 static const char *names[] = {
93 "BYTES_IN",
94 "BYTES_OUT",
95 "PACKETS_IN",
96 "PACKETS_OUT",
97 "TUN_BYTES_IN",
98 "TUN_BYTES_OUT",
99 "TUN_PACKETS_IN",
100 "TUN_PACKETS_OUT",
101 };
102
103 static_assert(N_STATS == array_size(names), "stats names array inconsistency");
104 if (type < N_STATS)
105 return names[type];
106 return "UNKNOWN_STAT_TYPE";
107 }
108
110 {
112 }
113
115 {
117 }
118
119 struct DCOTransportSource : public virtual RC<thread_unsafe_refcount>
120 {
122
123 struct Data
124 {
129
134
135 Data() = default;
136
137 Data(count_t transport_bytes_in_arg, count_t transport_bytes_out_arg)
138 : transport_bytes_in(transport_bytes_in_arg),
139 transport_bytes_out(transport_bytes_out_arg)
140 {
141 }
142
143 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)
144 : transport_bytes_in(transport_bytes_in_arg),
145 transport_bytes_out(transport_bytes_out_arg),
146 tun_bytes_in(tun_bytes_in_arg), tun_bytes_out(tun_bytes_out_arg)
147 {
148 }
149
150 Data(count_t transport_bytes_in_arg,
151 count_t transport_bytes_out_arg,
152 count_t tun_bytes_in_arg,
153 count_t tun_bytes_out_arg,
154 count_t transport_pkts_in_arg,
155 count_t transport_pkts_out_arg,
156 count_t tun_pkts_in_arg,
157 count_t tun_pkts_out_arg)
158
159 : transport_bytes_in(transport_bytes_in_arg),
160 transport_bytes_out(transport_bytes_out_arg),
161 tun_bytes_in(tun_bytes_in_arg),
162 tun_bytes_out(tun_bytes_out_arg),
163 transport_pkts_in(transport_pkts_in_arg),
164 transport_pkts_out(transport_pkts_out_arg),
165 tun_pkts_in(tun_pkts_in_arg),
166 tun_pkts_out(tun_pkts_out_arg)
167 {
168 }
169
170 Data operator-(const Data &rhs) const
171 {
172 Data data;
174 data.transport_bytes_in = transport_bytes_in - rhs.transport_bytes_in;
176 data.transport_bytes_out = transport_bytes_out - rhs.transport_bytes_out;
177 if (tun_bytes_in > rhs.tun_bytes_in)
178 data.tun_bytes_in = tun_bytes_in - rhs.tun_bytes_in;
180 data.tun_bytes_out = tun_bytes_out - rhs.tun_bytes_out;
182 data.transport_pkts_in = transport_pkts_in - rhs.transport_pkts_in;
184 data.transport_pkts_out = transport_pkts_out - rhs.transport_pkts_out;
185 if (tun_pkts_in > rhs.tun_pkts_in)
186 data.tun_pkts_in = tun_pkts_in - rhs.tun_pkts_in;
187 if (tun_pkts_out > rhs.tun_pkts_out)
188 data.tun_pkts_out = tun_pkts_out - rhs.tun_pkts_out;
189 return data;
190 }
191 };
192
194 };
195
197 {
198 dco_.reset(source);
199 }
200
202 {
203 if (dco_)
204 {
206
207 if (data.transport_bytes_in > 0)
208 {
210 }
211
212 inc_stat(BYTES_IN, data.transport_bytes_in);
213 inc_stat(BYTES_OUT, data.transport_bytes_out);
214 inc_stat(TUN_BYTES_IN, data.tun_bytes_in);
215 inc_stat(TUN_BYTES_OUT, data.tun_bytes_out);
216 inc_stat(PACKETS_IN, data.transport_pkts_in);
217 inc_stat(PACKETS_OUT, data.transport_pkts_out);
218 inc_stat(TUN_PACKETS_IN, data.tun_pkts_in);
219 inc_stat(TUN_PACKETS_OUT, data.tun_pkts_out);
220
221 return true;
222 }
223
224 return false;
225 }
226
236 [[nodiscard]] std::shared_ptr<inc_callback_t> set_inc_callback(Stats stat, inc_callback_t callback)
237 {
238 auto cb_ptr = std::make_shared<inc_callback_t>(callback);
239 inc_callbacks_[stat] = cb_ptr;
240 return cb_ptr;
241 }
242
243 protected:
244 void session_stats_set_verbose(const bool v)
245 {
246 verbose_ = v;
247 }
248
249 private:
254 std::array<std::weak_ptr<inc_callback_t>, N_STATS> inc_callbacks_;
255};
256
257} // namespace openvpn
258
259#endif // OPENVPN_LOG_SESSIONSTATS_H
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:908
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:302
constexpr std::size_t array_size(T(&)[N])
Definition arraysize.hpp:19
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)