/// <summary> /// Begins an asychronous traceroute to the specified destination. /// </summary> /// <param name="destination">The destination IP address.</param> /// <param name="callback">The callback method.</param> /// <param name="state">The user state.</param> /// <returns>The result of the asynchronous operation.</returns> public IAsyncResult Begin(IPAddress destination, AsyncCallback callback, object state) { lock (this.settings) { // Create a new traceroute state. TracerouteState asyncState = new TracerouteState(destination, this.settings.DataLength, callback, state); // Send a traceroute. this.Send(asyncState); // Return the asynchronous state. return asyncState; } }
// Private methods. /// <summary> /// Send a traceroute message using the specified traceroute state. /// </summary> /// <param name="asyncState">The traceroute state.</param> private void Send(TracerouteState asyncState) { // Begin sending a traceroute message using the state. IAsyncResult result = asyncState.Begin((IAsyncResult asyncResult) => { // Finish sending a traceroute message using the state. asyncState.End(asyncResult); // A flag indicated whether the traceroute has completed. bool completed = false; lock (this.settings.Sync) { // Check whether the traceroute reached the destination. completed = completed || (asyncState.LastReply != null ? asyncState.Destination.Equals(asyncState.LastReply.Address) && (this.settings.StopHopOnSuccess ? asyncState.TtlSuccess : asyncState.CurrentAttempt >= this.settings.MaximumAttempts) : false); // Check whether the maximum number of hops was reached. completed = completed || (asyncState.CurrentTtl > this.settings.MaximumHops); // Check whether the maximum number of failed hops was reached. completed = completed || (this.settings.StopTracerouteOnFail && (asyncState.LastFailedTtlCount + 1 >= this.settings.MaximumFailedHops) && (asyncState.CurrentAttempt >= this.settings.MaximumAttempts)); // Check whether the operation was canceled. completed = completed || asyncState.CancellationToken.IsCancellationRequested; } // If the traceroute is completed, complete the asynchronous operation. if (completed) asyncState.Complete(); // Call the callback method. if (null != asyncState.Callback) asyncState.Callback(asyncState); // If the operation is not completed. if (!completed) { lock (this.settings.Sync) { // If the hop was successful, and the traceroute stops on success; or if the maximum number of attempts was reached. if ((this.settings.StopHopOnSuccess && asyncState.TtlSuccess) || (asyncState.CurrentAttempt >= this.settings.MaximumAttempts)) { // Increment the TTL. asyncState.Next(); } } // Send a new message. this.Send(asyncState); } else { // Dispose the asynchronous state. asyncState.Dispose(); } }); }