/// <summary>
 /// Removes a packet capture handler.
 /// </summary>
 /// <param name="handler">The handler.</param>
 internal void RemoveHandler(PacketCaptureHandler handler)
 {
     this.handlers.Remove(handler);
 }
        ///// <summary>
        ///// Requests a receiving buffer. The method blocks until a buffer is available or until the cancellation is requested.
        ///// </summary>
        ///// <param name="cancel">The cancellation token.</param>
        ///// <returns>The buffer index.</returns>
        //private int RequestBuffer(CancellationToken cancel)
        //{
        //    // The buffer index.
        //    int bufferIndex = -1;
        //    do
        //    {
        //        // Wait for a buffer to become available.
        //        this.bufferWait.WaitOne();
        //        lock (this.syncBuffer)
        //        {
        //            // If the buffer queue is not empty.
        //            if (this.bufferQueue.Count > 0)
        //            {
        //                // Get the first buffer index.
        //                bufferIndex = this.bufferQueue.Dequeue();
        //                // If the queue is empty, reset the buffer wait handle.
        //                if (this.bufferQueue.Count == 0) this.bufferWait.Reset();
        //            }
        //        }
        //    }
        //    while ((bufferIndex == -1) && (!cancel.IsCancellationRequested));
        //    // Return the buffer index.
        //    return bufferIndex;
        //}
        ///// <summary>
        ///// Releases the specified buffer.
        ///// </summary>
        ///// <param name="bufferIndex">The buffer index.</param>
        //private void ReleaseBuffer(int bufferIndex)
        //{
        //    // Release the buffer.
        //    lock (this.syncBuffer)
        //    {
        //        // If the buffer queue is empty, set the buffer wait handle.
        //        if (this.bufferQueue.Count == 0) this.bufferWait.Set();
        //        // Add the buffer index to the queue.
        //        this.bufferQueue.Enqueue(bufferIndex);
        //    }
        //}
        ///// <summary>
        ///// Receives a packet from the specified socket.
        ///// </summary>
        ///// <param name="socket">The socket.</param>
        ///// <param name="cancel">The cancellation token.</param>
        ///// <param name="result">The result.</param>
        //private void ReceivePacket(Socket socket, CancellationToken cancel, MultipathTracerouteResult result)
        //{
        //    // The remote end-point.
        //    EndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
        //    // Request a buffer.
        //    int bufferIndex = this.RequestBuffer(cancel);
        //    // If the operation was canceled, return.
        //    if (cancel.IsCancellationRequested) return;
        //    // Synchronization object.
        //    object localSync = new object();
        //    // Buffer flag.
        //    bool bufferFlag = true;
        //    try
        //    {
        //        // Begin receiving a packet.
        //        socket.BeginReceiveFrom(this.bufferRecv[bufferIndex], 0, this.bufferRecv[bufferIndex].Length, SocketFlags.None, ref endPoint, (IAsyncResult asyncResult) =>
        //            {
        //                lock (localSync)
        //                {
        //                    try
        //                    {
        //                        // End receiving a packet.
        //                        int length = socket.EndReceiveFrom(asyncResult, ref endPoint);
        //                        // Process the packet.
        //                        this.ProcessPacket(this.bufferRecv[bufferIndex], length, result);
        //                    }
        //                    catch (ObjectDisposedException) { }
        //                    catch (Exception exception)
        //                    {
        //                        // Ignore all errors for received packets.
        //                        result.Callback(MultipathTracerouteState.StateType.PacketError, exception);
        //                    }
        //                    finally
        //                    {
        //                        // If the buffer flag is set.
        //                        if (bufferFlag)
        //                        {
        //                            // Release the buffer.
        //                            this.ReleaseBuffer(bufferIndex);
        //                            // Begin receiving the next packet.
        //                            this.ReceivePacket(socket, cancel, result);
        //                            // Set the flag to false.
        //                            bufferFlag = false;
        //                        }
        //                    }
        //                }
        //            }, null);
        //    }
        //    catch (ObjectDisposedException) { }
        //    catch (Exception)
        //    {
        //        lock (localSync)
        //        {
        //            // If the buffer flag is set.
        //            if (bufferFlag)
        //            {
        //                // Release the buffer.
        //                this.ReleaseBuffer(bufferIndex);
        //                // Begin receiving the next packet.
        //                this.ReceivePacket(socket, cancel, result);
        //                // Set the flag to false.
        //                bufferFlag = false;
        //            }
        //        }
        //    }
        //}
        public void PacketReceiveSuccess(PacketCaptureHandler handler, byte[] buffer, int length, ProtoPacketIp ip)
        {
            MultipathTracerouteCaptureHandler tracerouteHandler = handler as MultipathTracerouteCaptureHandler;

            // Call the callback methods.
            tracerouteHandler.Result.Callback(MultipathTracerouteState.StateType.PacketCapture, ip);

            // Process the packet for the current protocol.
            lock (this.syncProcess)
            {
                if (null != this.processPacket) this.processPacket(ip, length, tracerouteHandler.Result);
            }
        }
 /// <summary>
 /// Adds a packet capture handler.
 /// </summary>
 /// <param name="handler">The handler.</param>
 internal void AddHandler(PacketCaptureHandler handler)
 {
     this.handlers.Add(handler);
 }
        public void PacketReceiveError(PacketCaptureHandler handler, byte[] buffer, Exception exception)
        {
            MultipathTracerouteCaptureHandler tracerouteHandler = handler as MultipathTracerouteCaptureHandler;

            // Ignore all errors for received packets.
            tracerouteHandler.Result.Callback(MultipathTracerouteState.StateType.PacketError, exception);
        }