@@ -12,6 +12,7 @@ of the License.
1212module ;
1313#pragma warning (disable : 4005)
1414#include " targetver.h"
15+ #include " WinMTRRoutePolicy.h"
1516#define WIN32_LEAN_AND_MEAN
1617#define VC_EXTRALEAN
1718#define NOMCX
@@ -670,6 +671,15 @@ WinMTRTraceResult WinMTRNet::DoTrace(std::stop_token stop_token, SOCKADDR_INET a
670671 auto now = monotonic_now ();
671672 scheduler.start (this_session, current_epoch, now);
672673 const auto mandatory_ttl = std::max (trace_options.start_ttl , trace_options.minimum_ttl );
674+ winmtr::route::RoutePolicy route_policy ({
675+ .start_ttl = trace_options.start_ttl ,
676+ .minimum_ttl = trace_options.minimum_ttl ,
677+ .max_hops = trace_options.max_hops ,
678+ .unknown_host_limit = trace_options.unknown_host_limit ,
679+ .exploration_period = WinMTRUtils::PATH_EXPLORATION_PERIOD ,
680+ .exploration_frontier_ttls = WinMTRUtils::PATH_EXPLORATION_FRONTIER_TTLS ,
681+ .shrink_confirmations = WinMTRUtils::PATH_SHRINK_CONFIRMATIONS ,
682+ });
673683 // The first path discovery is complete but staggered over one interval. A
674684 // full initial sweep avoids hiding a destination behind an early run of
675685 // silent routers; subsequent cycles use the configured unknown tail.
@@ -682,13 +692,6 @@ WinMTRTraceResult WinMTRNet::DoTrace(std::stop_token stop_token, SOCKADDR_INET a
682692 bool session_had_usable_reply = false ;
683693 bool stopping = false ;
684694 std::optional<winmtr::probe::MonotonicMilliseconds> drain_deadline;
685- bool exploration_cycle = true ;
686- bool initial_discovery = true ;
687- unsigned highest_response_ttl = 0 ;
688- unsigned destination_ttl = 0 ;
689- unsigned stable_ceiling = initial_ceiling;
690- unsigned shrink_candidate = 0 ;
691- unsigned shrink_confirmations = 0 ;
692695
693696 const auto notify_changed = [this ] {
694697 if (options != nullptr ) options->notifyTraceDataChanged ();
@@ -704,50 +707,8 @@ WinMTRTraceResult WinMTRNet::DoTrace(std::stop_token stop_token, SOCKADDR_INET a
704707 && minimum > reported_cycles) {
705708 reported_cycles = minimum;
706709 setCompletedCycles (reported_cycles, current_epoch);
707- if (exploration_cycle) {
708- const auto tail_origin = highest_response_ttl == 0
709- ? trace_options.start_ttl - 1u
710- : highest_response_ttl;
711- const auto normal_ceiling = destination_ttl != 0
712- ? std::max (mandatory_ttl, destination_ttl)
713- : std::min (trace_options.max_hops ,
714- std::max (mandatory_ttl, tail_origin + trace_options.unknown_host_limit ));
715- if (initial_discovery) {
716- stable_ceiling = normal_ceiling;
717- initial_discovery = false ;
718- shrink_candidate = 0 ;
719- shrink_confirmations = 0 ;
720- }
721- else if (normal_ceiling < stable_ceiling) {
722- if (shrink_candidate == normal_ceiling) {
723- ++shrink_confirmations;
724- }
725- else {
726- shrink_candidate = normal_ceiling;
727- shrink_confirmations = 1 ;
728- }
729- if (shrink_confirmations >= WinMTRUtils::PATH_SHRINK_CONFIRMATIONS ) {
730- stable_ceiling = normal_ceiling;
731- shrink_candidate = 0 ;
732- shrink_confirmations = 0 ;
733- }
734- }
735- else {
736- stable_ceiling = normal_ceiling;
737- shrink_candidate = 0 ;
738- shrink_confirmations = 0 ;
739- }
740- scheduler.set_last_ttl (stable_ceiling, monotonic_now ());
741- exploration_cycle = false ;
742- }
743- if (reported_cycles % WinMTRUtils::PATH_EXPLORATION_PERIOD == 0
744- && stable_ceiling < trace_options.max_hops ) {
745- exploration_cycle = true ;
746- highest_response_ttl = 0 ;
747- destination_ttl = 0 ;
748- const auto frontier_ceiling = std::min (trace_options.max_hops ,
749- stable_ceiling + WinMTRUtils::PATH_EXPLORATION_FRONTIER_TTLS );
750- scheduler.set_last_ttl (frontier_ceiling, monotonic_now ());
710+ if (const auto ceiling = route_policy.complete_cycle (reported_cycles)) {
711+ scheduler.set_last_ttl (*ceiling, monotonic_now ());
751712 }
752713 }
753714 };
@@ -760,13 +721,7 @@ WinMTRTraceResult WinMTRNet::DoTrace(std::stop_token stop_token, SOCKADDR_INET a
760721 reported_cycles = 0 ;
761722 session_reached_destination = false ;
762723 session_had_usable_reply = false ;
763- exploration_cycle = true ;
764- initial_discovery = true ;
765- highest_response_ttl = 0 ;
766- destination_ttl = 0 ;
767- stable_ceiling = initial_ceiling;
768- shrink_candidate = 0 ;
769- shrink_confirmations = 0 ;
724+ route_policy.reset ();
770725 scheduler.restart (current_epoch, now);
771726 scheduler.set_last_ttl (initial_ceiling, now);
772727 }
@@ -776,8 +731,8 @@ WinMTRTraceResult WinMTRNet::DoTrace(std::stop_token stop_token, SOCKADDR_INET a
776731 if (found == requests.end ()) continue ;
777732 const auto disposition = scheduler.complete (request->token ,
778733 request->completion_kind , request->completed_at );
779- const auto accepted_after_destination = destination_ttl != 0
780- && request->token .ttl > std::max (mandatory_ttl, destination_ttl)
734+ const auto accepted_after_destination = route_policy. destination_ttl () != 0
735+ && request->token .ttl > std::max (mandatory_ttl, route_policy. destination_ttl () )
781736 && (disposition == winmtr::probe::CompletionDisposition::accepted_reply
782737 || disposition == winmtr::probe::CompletionDisposition::accepted_timeout
783738 || disposition == winmtr::probe::CompletionDisposition::accepted_local_error
@@ -802,12 +757,9 @@ WinMTRTraceResult WinMTRNet::DoTrace(std::stop_token stop_token, SOCKADDR_INET a
802757 trace_options.resolve_hostnames ,
803758 trace_options.lookup_asn_isp );
804759 session_had_usable_reply = true ;
805- highest_response_ttl = std::max (highest_response_ttl, request->token .ttl );
760+ route_policy. note_reply ( request->token .ttl , request-> destination_reply );
806761 if (request->destination_reply ) {
807762 session_reached_destination = true ;
808- destination_ttl = destination_ttl == 0
809- ? request->token .ttl
810- : std::min (destination_ttl, request->token .ttl );
811763 scheduler.set_last_ttl (std::max (mandatory_ttl, request->token .ttl ), now);
812764 }
813765 notify_changed ();
@@ -847,8 +799,8 @@ WinMTRTraceResult WinMTRNet::DoTrace(std::stop_token stop_token, SOCKADDR_INET a
847799 drain_deadline = now + trace_options.grace_ms ;
848800 }
849801 for (const auto & expired : scheduler.expire (now)) {
850- if (destination_ttl != 0
851- && expired.ttl > std::max (mandatory_ttl, destination_ttl)) {
802+ if (route_policy. destination_ttl () != 0
803+ && expired.ttl > std::max (mandatory_ttl, route_policy. destination_ttl () )) {
852804 commitPostDestinationCompletion (expired.ttl , expired.epoch );
853805 }
854806 else {
@@ -880,9 +832,7 @@ WinMTRTraceResult WinMTRNet::DoTrace(std::stop_token stop_token, SOCKADDR_INET a
880832 commitCacheSkipped (slot.token .ttl , slot.token .epoch );
881833 if (cached_destination) {
882834 session_reached_destination = true ;
883- destination_ttl = destination_ttl == 0
884- ? slot.token .ttl
885- : std::min (destination_ttl, slot.token .ttl );
835+ route_policy.note_reply (slot.token .ttl , true );
886836 scheduler.set_last_ttl (std::max (mandatory_ttl, slot.token .ttl ), now);
887837 }
888838 notify_changed ();
0 commit comments