@@ -44,37 +44,65 @@ public void TraceAsync(IPAddress ipAddress, TracerouteOptions traceOptions, Canc
4444 Task . Run ( ( ) =>
4545 {
4646 byte [ ] buffer = new byte [ traceOptions . Buffer ] ;
47- int maximumHops = traceOptions . MaximumHops + 1 ;
47+ int maximumHops = traceOptions . MaximumHops ;
4848
49- int hop = 1 ;
49+ bool maximumHopsReached = false ;
5050
51- do
51+ // Get the ttl of the ip
52+ using ( System . Net . NetworkInformation . Ping ping = new System . Net . NetworkInformation . Ping ( ) )
5253 {
53- List < Task < Tuple < PingReply , long > > > tasks = new List < Task < Tuple < PingReply , long > > > ( ) ;
54+ PingReply pingReply ;
5455
5556 for ( int i = 0 ; i < 3 ; i ++ )
57+ {
58+ pingReply = ping . Send ( ipAddress , traceOptions . Timeout , buffer , new System . Net . NetworkInformation . PingOptions ( ) { Ttl = 64 , DontFragment = traceOptions . DontFragement } ) ;
59+
60+ if ( pingReply . Status == IPStatus . Success )
61+ {
62+ int ttl = 64 - pingReply . Options . Ttl ;
63+
64+ if ( ttl < maximumHops )
65+ maximumHops = ttl ;
66+ else
67+ maximumHopsReached = true ;
68+
69+ break ;
70+ }
71+ }
72+ }
73+
74+ // Async check all hops
75+ Parallel . For ( 1 , maximumHops + 1 , new ParallelOptions ( ) { CancellationToken = cancellationToken } , i =>
76+ {
77+ List < Task < Tuple < PingReply , long > > > tasks = new List < Task < Tuple < PingReply , long > > > ( ) ;
78+
79+ for ( int y = 0 ; y < 3 ; y ++ )
5680 {
5781 tasks . Add ( Task . Run ( ( ) =>
58- {
59- Stopwatch stopwatch = new Stopwatch ( ) ;
82+ {
83+ Stopwatch stopwatch = new Stopwatch ( ) ;
6084
61- PingReply pingReply ;
85+ PingReply pingReply ;
6286
63- using ( System . Net . NetworkInformation . Ping ping = new System . Net . NetworkInformation . Ping ( ) )
64- {
65- stopwatch . Start ( ) ;
87+ using ( System . Net . NetworkInformation . Ping ping = new System . Net . NetworkInformation . Ping ( ) )
88+ {
89+ stopwatch . Start ( ) ;
6690
67- pingReply = ping . Send ( ipAddress , traceOptions . Timeout , buffer , new System . Net . NetworkInformation . PingOptions ( ) { Ttl = hop , DontFragment = traceOptions . DontFragement } ) ;
91+ pingReply = ping . Send ( ipAddress , traceOptions . Timeout , buffer , new System . Net . NetworkInformation . PingOptions ( ) { Ttl = i , DontFragment = traceOptions . DontFragement } ) ;
6892
69- stopwatch . Stop ( ) ;
70- }
93+ stopwatch . Stop ( ) ;
94+ }
7195
72- return Tuple . Create ( pingReply , stopwatch . ElapsedMilliseconds ) ;
73- } ) ) ;
96+ return Tuple . Create ( pingReply , stopwatch . ElapsedMilliseconds ) ;
97+ } ) ) ;
7498 }
7599
76100 Task . WaitAll ( tasks . ToArray ( ) ) ;
77101
102+ // Here is a good point to cancel (Don't resolve dns...)
103+ if ( cancellationToken . IsCancellationRequested )
104+ return ;
105+
78106 IPAddress ipAddressHop = tasks . FirstOrDefault ( x => x . Result . Item1 != null ) . Result . Item1 . Address ;
79107
80108 string hostname = string . Empty ;
@@ -86,24 +114,15 @@ public void TraceAsync(IPAddress ipAddress, TracerouteOptions traceOptions, Canc
86114 }
87115 catch ( SocketException ) { } // Couldn't resolve hostname
88116
89- OnHopReceived ( new TracerouteHopReceivedArgs ( hop , tasks [ 0 ] . Result . Item2 , tasks [ 1 ] . Result . Item2 , tasks [ 2 ] . Result . Item2 , ipAddressHop , hostname , tasks [ 0 ] . Result . Item1 . Status , tasks [ 1 ] . Result . Item1 . Status , tasks [ 2 ] . Result . Item1 . Status ) ) ;
90-
91- if ( ipAddressHop != null )
92- {
93- if ( ipAddressHop . ToString ( ) == ipAddress . ToString ( ) )
94- {
95- OnTraceComplete ( ) ;
96- return ;
97- }
98- }
99-
100- hop ++ ;
101- } while ( hop < maximumHops && ! cancellationToken . IsCancellationRequested ) ;
117+ OnHopReceived ( new TracerouteHopReceivedArgs ( i , tasks [ 0 ] . Result . Item2 , tasks [ 1 ] . Result . Item2 , tasks [ 2 ] . Result . Item2 , ipAddressHop , hostname , tasks [ 0 ] . Result . Item1 . Status , tasks [ 1 ] . Result . Item1 . Status , tasks [ 2 ] . Result . Item1 . Status ) ) ;
118+ } ) ;
102119
103120 if ( cancellationToken . IsCancellationRequested )
104121 OnUserHasCanceled ( ) ;
105- else if ( hop == maximumHops )
122+ else if ( maximumHopsReached )
106123 OnMaximumHopsReached ( new MaximumHopsReachedArgs ( traceOptions . MaximumHops ) ) ;
124+ else
125+ OnTraceComplete ( ) ;
107126
108127 } , cancellationToken ) ;
109128 }
0 commit comments