Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Traceroute.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "Stroika/Frameworks/StroikaPreComp.h"
5
6#include <random>
7
10#include "Stroika/Foundation/Containers/Collection.h"
13#include "Stroika/Foundation/IO/Network/Listener.h"
15
16#include "Ping.h"
17
18#include "Traceroute.h"
19
20using namespace Stroika::Foundation;
23using namespace Stroika::Foundation::Debug;
24using namespace Stroika::Foundation::Execution;
25using namespace Stroika::Foundation::Memory;
26using namespace Stroika::Foundation::IO;
28using namespace Stroika::Foundation::IO::Network::InternetProtocol;
29using namespace Stroika::Foundation::Traversal;
30
31using namespace Stroika::Frameworks;
32using namespace Stroika::Frameworks::NetworkMonitor;
34
35// Comment this in to turn on aggressive noisy DbgTrace in this module
36//#define USE_NOISY_TRACE_IN_THIS_MODULE_ 1
37
38/*
39 ********************************************************************************
40 ************ NetworkMonitor::Traceroute::Options::SampleInfo *******************
41 ********************************************************************************
42 */
43Characters::String Traceroute::Options::SampleInfo::ToString () const
44{
46 sb << "{"sv;
47 sb << "Interval: "sv << fInterval;
48 sb << ", Count: "sv << fSampleCount;
49 sb << "}"sv;
50 return sb;
51}
52
53/*
54 ********************************************************************************
55 ***************** NetworkMonitor::Traceroute::Options **************************
56 ********************************************************************************
57 */
58String Traceroute::Options::ToString () const
59{
61 sb << "{"sv;
62 if (fMaxHops) {
63 sb << "Max-Hops: "sv << *fMaxHops;
64 }
65 if (fTimeout) {
66 sb << ", Timeout: "sv << *fTimeout;
67 }
68 if (fPacketPayloadSize) {
69 sb << ", Packet-Payload-Size: "sv << *fPacketPayloadSize;
70 }
71 if (fSampleInfo) {
72 sb << ", Sample: "sv << *fSampleInfo;
73 }
74 sb << "}"sv;
75 return sb;
76}
77
78/*
79 ********************************************************************************
80 ******************** NetworkMonitor::Traceroute::Hop ***************************
81 ********************************************************************************
82 */
83String Hop::ToString () const
84{
86 sb << "{"sv;
87 sb << "Time: "sv << fTime;
88 sb << ", Address: "sv << fAddress;
89 sb << "}"sv;
90 return sb;
91}
92
93/*
94 ********************************************************************************
95 *********************** NetworkMonitor::Traceroute *****************************
96 ********************************************************************************
97 */
98Sequence<Hop> NetworkMonitor::Traceroute::Run (const InternetAddress& addr, const Options& options)
99{
100 Sequence<Hop> results;
101 Run (addr, [&results] (const Hop& h) { results += h; }, options);
102 return results;
103}
104
105void NetworkMonitor::Traceroute::Run (const InternetAddress& addr, function<void (Hop)> perHopCallback, const Options& options)
106{
107 Debug::TraceContextBumper ctx{"Frameworks::NetworkMonitor::Traceroute::Run", "addr={}, options={}"_f, addr, options};
108 unsigned int maxTTL = options.fMaxHops.value_or (Options::kDefaultMaxHops);
109
110 Ping::Options pingOptions{};
111 pingOptions.fPacketPayloadSize = options.fPacketPayloadSize;
112 Ping::Pinger pinger{addr, pingOptions};
113
114 for (unsigned int ttl = 1; ttl <= maxTTL; ++ttl) {
115#if 0
116 if (options.fSampleInfo) {
117 pingOptions.fSampleInfo = Ping::Options::SampleInfo{options.fSampleInfo->fInterval, options.fSampleInfo->fSampleCount};
118 }
119#endif
120 Time::TimePointSeconds startOfPingRequest = Time::GetTickCount ();
121 try {
122 Ping::Pinger::ResultType r = pinger.RunOnce (ttl);
123 perHopCallback (Hop{r.fPingTime, addr});
124 break;
125 }
126 catch (const ICMP::V4::TTLExpiredException& ttlExpiredException) {
127#if USE_NOISY_TRACE_IN_THIS_MODULE_
128 DbgTrace ("exception {} - ipaddr = {}"_f, ttlExpiredException, ttlExpiredException.GetReachedIP ());
129#endif
130 // totally normal - this is how we find out the hops
131 perHopCallback (Hop{Duration{Time::GetTickCount () - startOfPingRequest}, ttlExpiredException.GetUnreachedIP ()});
132 }
133 catch (const ICMP::V4::DestinationUnreachableException& destinationUnreachableException) {
134#if USE_NOISY_TRACE_IN_THIS_MODULE_
135 DbgTrace ("exception {} - ipaddr = {}"_f, destinationUnreachableException, destinationUnreachableException.GetReachedIP ());
136#endif
137 // Not sure how normal this is? @todo - research - maybe abandon ping when this happens... -- LGP 2017-03-27
138 perHopCallback (Hop{Duration{Time::GetTickCount () - startOfPingRequest}, destinationUnreachableException.GetUnreachedIP ()});
139 }
140 catch (...) {
141#if USE_NOISY_TRACE_IN_THIS_MODULE_
142 DbgTrace (L"exception {}"_f, current_exception ());
143#endif
144 perHopCallback (Hop{});
145 }
146 }
147}
Results< FLOAT_TYPE > Run(const TargetFunction< FLOAT_TYPE > &function2Minimize, const Sequence< FLOAT_TYPE > &initialValues, const Options< FLOAT_TYPE > &options=Options< FLOAT_TYPE >{})
Downhill Simplex Minimization, AKA Nelder-Mead algorithm, to compute minimization.
time_point< RealtimeClock, DurationSeconds > TimePointSeconds
TimePointSeconds is a simpler approach to chrono::time_point, which doesn't require using templates e...
Definition Realtime.h:82
#define DbgTrace
Definition Trace.h:309
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
A generalization of a vector: a container whose elements are keyed by the natural numbers.
Definition Sequence.h:187
Duration is a chrono::duration<double> (=.
Definition Duration.h:96