join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
ping.hpp
Go to the documentation of this file.
1
25#ifndef JOIN_FABRIC_PING_HPP
26#define JOIN_FABRIC_PING_HPP
27
28// libjoin.
30#include <join/ip_address.hpp>
31#include <join/condition.hpp>
32#include <join/reactor.hpp>
33
34// C++.
35#include <unordered_map>
36#include <functional>
37#include <chrono>
38#include <memory>
39#include <string>
40
41// C.
42#include <netinet/in.h>
43
44namespace join
45{
50 {
53
55 std::chrono::microseconds rtt{0};
56
58 int ttl = 0;
59
61 int size = 0;
62
64 uint32_t mtu = 0;
65
67 bool expired = false;
68
70 std::string error;
71
73 std::error_code code;
74 };
75
80 {
81 public:
85 PingStats () = default;
86
97 PingStats (const std::string& device, const IpAddress& source, const std::string& host, int size,
98 std::chrono::milliseconds interval, int hop, int df);
99
104 PingStats (const PingStats& other) = default;
105
111 PingStats& operator= (const PingStats& other) = default;
112
117 PingStats (PingStats&& other) = default;
118
124 PingStats& operator= (PingStats&& other) = default;
125
129 ~PingStats () = default;
130
135 const std::string& device () const noexcept
136 {
137 return _device;
138 }
139
144 const IpAddress& source () const noexcept
145 {
146 return _source;
147 }
148
153 const std::string& host () const noexcept
154 {
155 return _host;
156 }
157
162 const IpAddress& address () const noexcept
163 {
164 return _address;
165 }
166
171 int size () const noexcept
172 {
173 return _size;
174 }
175
180 std::chrono::milliseconds interval () const noexcept
181 {
182 return _interval;
183 }
184
189 const IpAddress& from () const noexcept
190 {
191 return _answer.from;
192 }
193
198 uint16_t sequence () const noexcept
199 {
200 return _sequence;
201 }
202
207 int hop () const noexcept
208 {
209 return _hop;
210 }
211
216 int df () const noexcept
217 {
218 return _df;
219 }
220
225 int route () const noexcept
226 {
227 return _route;
228 }
229
234 int ttl () const noexcept
235 {
236 return _answer.ttl;
237 }
238
243 int packetSize () const noexcept
244 {
245 return _answer.size;
246 }
247
252 std::chrono::microseconds rtt () const noexcept
253 {
254 return _answer.rtt;
255 }
256
261 bool expired () const noexcept
262 {
263 return _answer.expired;
264 }
265
270 uint32_t mtu () const noexcept
271 {
272 return _answer.mtu;
273 }
274
279 const std::string& error () const noexcept
280 {
281 return _answer.error;
282 }
283
288 const std::error_code& code () const noexcept
289 {
290 return _answer.code;
291 }
292
297 uint32_t sent () const noexcept
298 {
299 return _sent;
300 }
301
306 uint32_t received () const noexcept
307 {
308 return _received;
309 }
310
315 double loss () const noexcept
316 {
317 return _sent ? ((_sent - _received) * 100.0) / _sent : 0.0;
318 }
319
324 std::chrono::microseconds min () const noexcept
325 {
326 return std::chrono::microseconds (_min);
327 }
328
333 std::chrono::microseconds max () const noexcept
334 {
335 return std::chrono::microseconds (_max);
336 }
337
342 std::chrono::microseconds avg () const noexcept
343 {
344 return std::chrono::microseconds (static_cast<uint64_t> (_mean));
345 }
346
351 std::chrono::microseconds mdev () const noexcept;
352
357 std::chrono::microseconds total () const noexcept
358 {
359 return std::chrono::duration_cast<std::chrono::microseconds> (_stop - _start);
360 }
361
365 void reset () noexcept;
366
367 private:
372 void sample (std::chrono::microseconds rtt) noexcept;
373
375 std::string _device;
376
378 IpAddress _source;
379
381 std::string _host;
382
384 IpAddress _address;
385
387 int _size = 0;
388
390 std::chrono::milliseconds _interval{0};
391
393 uint16_t _sequence = 0;
394
396 int _hop = 0;
397
399 int _df = IP_PMTUDISC_DONT;
400
402 int _route = 0;
403
405 PingAnswer _answer;
406
408 uint32_t _sent = 0;
409
411 uint32_t _received = 0;
412
414 uint32_t _samples = 0;
415
417 uint64_t _min = 0;
418
420 uint64_t _max = 0;
421
423 double _mean = 0.0;
424
426 double _m2 = 0.0;
427
429 std::chrono::steady_clock::time_point _start;
430
432 std::chrono::steady_clock::time_point _stop;
433
435 friend class Ping;
436 };
437
441 class Ping : public EventHandler
442 {
443 public:
445 using PingNotify = std::function<void (const PingStats&)>;
446
449
452
455
458
461
467 explicit Ping (int ttl = _defaultTtl, Reactor& reactor = ReactorThread::reactor ());
468
475 explicit Ping (const std::string& device, int ttl = _defaultTtl, Reactor& reactor = ReactorThread::reactor ());
476
481 Ping (const Ping& other) = delete;
482
488 Ping& operator= (const Ping& other) = delete;
489
494 Ping (Ping&& other) = delete;
495
501 Ping& operator= (Ping&& other) = delete;
502
506 ~Ping () = default;
507
519 int ping (const IpAddress& source, const std::string& destination, int size = _defaultSize, int count = 1,
520 std::chrono::milliseconds interval = std::chrono::milliseconds (500), int df = IP_PMTUDISC_DONT,
521 std::chrono::milliseconds timeout = std::chrono::seconds (5));
522
534 static int ping4 (const std::string& destination, int size = _defaultSize, int count = 1,
535 std::chrono::milliseconds interval = std::chrono::milliseconds (500), int ttl = _defaultTtl,
536 int df = IP_PMTUDISC_DONT, std::chrono::milliseconds timeout = std::chrono::seconds (5));
537
549 static int ping6 (const std::string& destination, int size = _defaultSize, int count = 1,
550 std::chrono::milliseconds interval = std::chrono::milliseconds (500), int ttl = _defaultTtl,
551 int df = IP_PMTUDISC_DONT, std::chrono::milliseconds timeout = std::chrono::seconds (5));
552
560 int pathMtu (const IpAddress& source, const std::string& destination,
561 std::chrono::milliseconds timeout = std::chrono::seconds (5));
562
574 int trace (const IpAddress& source, const std::string& destination, int maxHops = _defaultMaxHops,
575 int probes = _defaultProbes, int size = _defaultSize, int df = IP_PMTUDISC_DONT,
576 std::chrono::milliseconds timeout = std::chrono::seconds (5));
577
585 static const char* message (int family, uint8_t type, uint8_t code) noexcept;
586
587 protected:
594 static bool isFatal (const PingStats& stats, uint32_t transmitted);
595
601 static int headerSize (const PingStats& stats);
602
609 int open (Icmp::Socket& socket, PingStats& stats);
610
617 static int setFilter (Icmp::Socket& socket, PingStats& stats);
618
623 void close (Icmp::Socket& socket);
624
632 int echo (Icmp::Socket& socket, PingStats& stats, std::chrono::milliseconds timeout);
633
638 void onReadable (int fd) override final;
639
644 void onError (int fd) override final;
645
651 static void notify (const PingNotify& function, const PingStats& stats);
652
660 static int fail (PingStats& stats, const std::error_code& code, const std::string& error);
661
662#ifdef DEBUG
667 static void defaultOnStart (const PingStats& stats);
668
673 static void defaultOnSuccess (const PingStats& stats);
674
679 static void defaultOnFailure (const PingStats& stats);
680
685 static void defaultOnStop (const PingStats& stats);
686#endif
687
689 static constexpr int _defaultTtl = 60;
690
692 static constexpr int _defaultSize = 56;
693
695 static constexpr int _defaultMaxHops = 30;
696
698 static constexpr int _defaultProbes = 3;
699
701 static constexpr int _icmpHeaderSize = 8;
702
704 static constexpr size_t _bufferSize = 65535;
705
707 static constexpr int _maxMtuProbes = 30;
708
710 static constexpr int _retryDelay = 200;
711
713 static constexpr int _dumpSize = 64;
714
719 {
722
724 std::chrono::steady_clock::time_point sent;
725
728
730 bool answered = false;
731 };
732
734 std::unordered_map<uint16_t, std::unique_ptr<PendingRequest>> _pending;
735
738
740 std::unique_ptr<char[]> _buffer;
741
743 const std::string _device;
744
746 const uint16_t _identity;
747
749 uint16_t _sequence = 0;
750
752 const int _ttl;
753
756 };
757}
758
759#endif
basic datagram socket class.
Definition protocol.hpp:47
condition variable class.
Definition condition.hpp:42
Event handler interface class.
Definition reactor.hpp:48
IPv6, IPv4 address class.
Definition ip_address.hpp:51
class used to protect shared data from being simultaneously accessed by multiple threads.
Definition mutex.hpp:37
ICMP echo statistics.
Definition ping.hpp:80
const IpAddress & source() const noexcept
get the source address the echo requests are sent from.
Definition ping.hpp:144
uint32_t received() const noexcept
get the number of answers received.
Definition ping.hpp:306
const std::string & error() const noexcept
get the human readable form of the last error.
Definition ping.hpp:279
const std::string & host() const noexcept
get the destination as requested by the caller.
Definition ping.hpp:153
std::chrono::microseconds avg() const noexcept
get the average round trip time.
Definition ping.hpp:342
uint32_t sent() const noexcept
get the number of echo requests sent.
Definition ping.hpp:297
void reset() noexcept
reset the round trip time aggregates and the last request outcome.
Definition ping.cpp:114
int hop() const noexcept
get the time to live the echo requests are sent with.
Definition ping.hpp:207
double loss() const noexcept
get the packet loss percentage.
Definition ping.hpp:315
std::chrono::microseconds rtt() const noexcept
get the round trip time of the last echo request.
Definition ping.hpp:252
PingStats(PingStats &&other)=default
create instance by move.
int route() const noexcept
get the MTU the stack knows for the destination.
Definition ping.hpp:225
bool expired() const noexcept
check if the last echo request expired before reaching the destination.
Definition ping.hpp:261
const IpAddress & from() const noexcept
get the address that answered the last echo request.
Definition ping.hpp:189
int df() const noexcept
get the path MTU discovery setting the echo requests are sent with.
Definition ping.hpp:216
std::chrono::milliseconds interval() const noexcept
get the interval between two echo requests.
Definition ping.hpp:180
PingStats & operator=(const PingStats &other)=default
assign instance by copy.
std::chrono::microseconds min() const noexcept
get the minimum round trip time.
Definition ping.hpp:324
int ttl() const noexcept
get the time to live of the last answer received.
Definition ping.hpp:234
const IpAddress & address() const noexcept
get the resolved destination address.
Definition ping.hpp:162
std::chrono::microseconds mdev() const noexcept
get the round trip time mean deviation.
Definition ping.cpp:100
PingStats()=default
create the PingStats instance.
std::chrono::microseconds max() const noexcept
get the maximum round trip time.
Definition ping.hpp:333
int size() const noexcept
get the number of data bytes sent in each echo request.
Definition ping.hpp:171
const std::string & device() const noexcept
get the device the echo requests are sent through.
Definition ping.hpp:135
int packetSize() const noexcept
get the ICMP message size of the last answer received.
Definition ping.hpp:243
~PingStats()=default
destroy the PingStats instance.
std::chrono::microseconds total() const noexcept
get the total elapsed time, request intervals included.
Definition ping.hpp:357
uint32_t mtu() const noexcept
get the MTU reported by the last error received.
Definition ping.hpp:270
const std::error_code & code() const noexcept
get the error code of the last request.
Definition ping.hpp:288
PingStats(const PingStats &other)=default
create instance by copy.
uint16_t sequence() const noexcept
get the sequence number of the last echo request.
Definition ping.hpp:198
ICMP echo client.
Definition ping.hpp:442
static const char * message(int family, uint8_t type, uint8_t code) noexcept
get the human readable form of an ICMP type and code pair.
Definition ping.cpp:978
static int fail(PingStats &stats, const std::error_code &code, const std::string &error)
set the outcome of the last request in the statistics.
Definition ping.cpp:1112
void close(Icmp::Socket &socket)
unregister and close the socket used by a sequence.
Definition ping.cpp:538
~Ping()=default
destroy the Ping instance.
int pathMtu(const IpAddress &source, const std::string &destination, std::chrono::milliseconds timeout=std::chrono::seconds(5))
discover the path MTU towards the given destination.
Definition ping.cpp:241
const std::string _device
device name to bind to.
Definition ping.hpp:743
static constexpr int _dumpSize
maximum number of bytes dumped in debug builds.
Definition ping.hpp:713
static bool isFatal(const PingStats &stats, uint32_t transmitted)
check if the last failure occurred before the request could be transmitted.
Definition ping.cpp:400
const uint16_t _identity
echo request identifier.
Definition ping.hpp:746
Mutex _syncMutex
mutex for synchronous operations.
Definition ping.hpp:737
static constexpr int _defaultTtl
default time to live.
Definition ping.hpp:689
int echo(Icmp::Socket &socket, PingStats &stats, std::chrono::milliseconds timeout)
send an echo request through the given socket and wait for its answer.
Definition ping.cpp:548
PingNotify onFailure
callback called when an echo request failed.
Definition ping.hpp:454
PingNotify onSuccess
callback called when an echo request is answered.
Definition ping.hpp:451
Ping(const Ping &other)=delete
create instance by copy.
PingNotify onHop
callback called when all the probes of a hop have been sent.
Definition ping.hpp:457
PingNotify onStart
callback called when a sequence is going to start.
Definition ping.hpp:448
int open(Icmp::Socket &socket, PingStats &stats)
resolve the destination then open and register the socket used by a sequence.
Definition ping.cpp:421
uint16_t _sequence
sequence number of the last echo request sent.
Definition ping.hpp:749
void onReadable(int fd) override final
method called when data are ready to be read.
Definition ping.cpp:703
Ping(int ttl=_defaultTtl, Reactor &reactor=ReactorThread::reactor())
create the Ping instance.
Definition ping.cpp:134
static constexpr int _maxMtuProbes
maximum number of probes sent by pathMtu.
Definition ping.hpp:707
static int setFilter(Icmp::Socket &socket, PingStats &stats)
restrict the ICMP messages delivered to the given socket.
Definition ping.cpp:501
static constexpr size_t _bufferSize
receive buffer size.
Definition ping.hpp:704
Ping & operator=(const Ping &other)=delete
assign instance by copy.
PingNotify onStop
callback called when a sequence is going to stop.
Definition ping.hpp:460
static int ping6(const std::string &destination, int size=_defaultSize, int count=1, std::chrono::milliseconds interval=std::chrono::milliseconds(500), int ttl=_defaultTtl, int df=IP_PMTUDISC_DONT, std::chrono::milliseconds timeout=std::chrono::seconds(5))
send echo requests to the given destination using the AF_INET6 address family.
Definition ping.cpp:231
static constexpr int _defaultSize
default number of data bytes sent in each echo request.
Definition ping.hpp:692
static int ping4(const std::string &destination, int size=_defaultSize, int count=1, std::chrono::milliseconds interval=std::chrono::milliseconds(500), int ttl=_defaultTtl, int df=IP_PMTUDISC_DONT, std::chrono::milliseconds timeout=std::chrono::seconds(5))
send echo requests to the given destination using the AF_INET address family.
Definition ping.cpp:221
Ping(Ping &&other)=delete
create instance by move.
static constexpr int _icmpHeaderSize
ICMP header size.
Definition ping.hpp:701
const int _ttl
default time to live.
Definition ping.hpp:752
static constexpr int _retryDelay
delay in milliseconds applied before retrying a request that could not be queued.
Definition ping.hpp:710
Reactor & _reactor
event loop reactor.
Definition ping.hpp:755
void onError(int fd) override final
method called when an error occurred.
Definition ping.cpp:849
static void notify(const PingNotify &function, const PingStats &stats)
safe way to notify sequence events.
Definition ping.cpp:1100
static constexpr int _defaultMaxHops
default maximum number of hops probed by trace.
Definition ping.hpp:695
std::function< void(const PingStats &)> PingNotify
notification callback definition.
Definition ping.hpp:445
static int headerSize(const PingStats &stats)
get the number of header bytes added to the data of an echo request.
Definition ping.cpp:410
std::unordered_map< uint16_t, std::unique_ptr< PendingRequest > > _pending
pending echo requests indexed by sequence number.
Definition ping.hpp:734
int ping(const IpAddress &source, const std::string &destination, int size=_defaultSize, int count=1, std::chrono::milliseconds interval=std::chrono::milliseconds(500), int df=IP_PMTUDISC_DONT, std::chrono::milliseconds timeout=std::chrono::seconds(5))
send echo requests to the given destination.
Definition ping.cpp:169
std::unique_ptr< char[]> _buffer
receive buffer.
Definition ping.hpp:740
int trace(const IpAddress &source, const std::string &destination, int maxHops=_defaultMaxHops, int probes=_defaultProbes, int size=_defaultSize, int df=IP_PMTUDISC_DONT, std::chrono::milliseconds timeout=std::chrono::seconds(5))
discover the route towards the given destination.
Definition ping.cpp:321
static constexpr int _defaultProbes
default number of echo requests sent per hop by trace.
Definition ping.hpp:698
static Reactor & reactor()
get the global Reactor instance.
Definition reactor.cpp:584
Reactor class.
Definition reactor.hpp:156
const std::string sample
sample text.
Definition digest_test.cpp:35
Definition acceptor.hpp:32
Definition error.hpp:144
answer to an echo request.
Definition ping.hpp:50
int size
ICMP message size of the answer.
Definition ping.hpp:61
std::string error
human readable form of the answer.
Definition ping.hpp:70
IpAddress from
address that answered.
Definition ping.hpp:52
std::error_code code
answer error code.
Definition ping.hpp:73
uint32_t mtu
MTU reported by the answer, zero if none was reported.
Definition ping.hpp:64
bool expired
set if a time exceeded message was received.
Definition ping.hpp:67
std::chrono::microseconds rtt
round trip time.
Definition ping.hpp:55
int ttl
time to live of the answer.
Definition ping.hpp:58
pending echo request.
Definition ping.hpp:719
bool answered
set once the request has been answered.
Definition ping.hpp:730
std::chrono::steady_clock::time_point sent
time the echo request was sent at.
Definition ping.hpp:724
Condition cond
answer notification.
Definition ping.hpp:721
PingAnswer answer
answer received, shared with the statistics.
Definition ping.hpp:727