@@ -44,37 +44,66 @@ 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+ // Check 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+ Parallel . For ( 1 , maximumHops + 1 , new ParallelOptions ( ) { CancellationToken = cancellationToken } , i =>
75+ {
76+ List < Task < Tuple < PingReply , long > > > tasks = new List < Task < Tuple < PingReply , long > > > ( ) ;
77+
78+ for ( int y = 0 ; y < 3 ; y ++ )
5679 {
5780 tasks . Add ( Task . Run ( ( ) =>
58- {
59- Stopwatch stopwatch = new Stopwatch ( ) ;
81+ {
82+ Stopwatch stopwatch = new Stopwatch ( ) ;
83+
84+ PingReply pingReply ;
6085
61- PingReply pingReply ;
86+ using ( System . Net . NetworkInformation . Ping ping = new System . Net . NetworkInformation . Ping ( ) )
87+ {
88+ stopwatch . Start ( ) ;
6289
63- using ( System . Net . NetworkInformation . Ping ping = new System . Net . NetworkInformation . Ping ( ) )
64- {
65- stopwatch . Start ( ) ;
90+ pingReply = ping . Send ( ipAddress , traceOptions . Timeout , buffer , new System . Net . NetworkInformation . PingOptions ( ) { Ttl = i , DontFragment = traceOptions . DontFragement } ) ;
6691
67- pingReply = ping . Send ( ipAddress , traceOptions . Timeout , buffer , new System . Net . NetworkInformation . PingOptions ( ) { Ttl = hop , DontFragment = traceOptions . DontFragement } ) ;
92+ Debug . WriteLine ( i . ToString ( ) + " " + pingReply . Address + " " + pingReply . Options . Ttl ) ;
6893
69- stopwatch . Stop ( ) ;
70- }
94+ stopwatch . Stop ( ) ;
95+ }
7196
72- return Tuple . Create ( pingReply , stopwatch . ElapsedMilliseconds ) ;
73- } ) ) ;
97+ return Tuple . Create ( pingReply , stopwatch . ElapsedMilliseconds ) ;
98+ } ) ) ;
7499 }
75100
76101 Task . WaitAll ( tasks . ToArray ( ) ) ;
77102
103+ // Here is a good point to cancel (Don't resolve dns...)
104+ if ( cancellationToken . IsCancellationRequested )
105+ return ;
106+
78107 IPAddress ipAddressHop = tasks . FirstOrDefault ( x => x . Result . Item1 != null ) . Result . Item1 . Address ;
79108
80109 string hostname = string . Empty ;
@@ -86,24 +115,15 @@ public void TraceAsync(IPAddress ipAddress, TracerouteOptions traceOptions, Canc
86115 }
87116 catch ( SocketException ) { } // Couldn't resolve hostname
88117
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 ) ;
118+ 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 ) ) ;
119+ } ) ;
102120
103121 if ( cancellationToken . IsCancellationRequested )
104122 OnUserHasCanceled ( ) ;
105- else if ( hop == maximumHops )
123+ else if ( maximumHopsReached )
106124 OnMaximumHopsReached ( new MaximumHopsReachedArgs ( traceOptions . MaximumHops ) ) ;
125+ else
126+ OnTraceComplete ( ) ;
107127
108128 } , cancellationToken ) ;
109129 }
0 commit comments