/// <summary> /// Stops remote port forwarding. /// </summary> /// <param name="timeout">The maximum amount of time to wait for the port to stop.</param> protected override void StopPort(TimeSpan timeout) { if (!ForwardedPortStatus.ToStopping(ref _status)) { return; } base.StopPort(timeout); // send global request to cancel direct tcpip Session.SendMessage(new CancelTcpIpForwardGlobalRequestMessage(BoundHost, BoundPort)); // wait for response on global request to cancel direct tcpip or completion of message // listener loop (in which case response on global request can never be received) WaitHandle.WaitAny(new[] { _globalRequestResponse, Session.MessageListenerCompleted }, timeout); // unsubscribe from session events as either the tcpip forward is cancelled at the // server, or our session message loop has completed Session.RequestSuccessReceived -= Session_RequestSuccess; Session.RequestFailureReceived -= Session_RequestFailure; Session.ChannelOpenReceived -= Session_ChannelOpening; // wait for pending channels to close _pendingChannelCountdown.Signal(); _pendingChannelCountdown.Wait(timeout); _status = ForwardedPortStatus.Stopped; }
/// <summary> /// Stops local port forwarding, and waits for the specified timeout until all pending /// requests are processed. /// </summary> /// <param name="timeout">The maximum amount of time to wait for pending requests to finish processing.</param> protected override void StopPort(TimeSpan timeout) { if (!ForwardedPortStatus.ToStopping(ref _status)) { return; } // signal existing channels that the port is closing base.StopPort(timeout); // prevent new requests from getting processed StopListener(); // wait for open channels to close InternalStop(timeout); // mark port stopped _status = ForwardedPortStatus.Stopped; }