private void Session_ChannelOpening(object sender, MessageEventArgs <ChannelOpenMessage> e) { var channelOpenMessage = e.Message; var info = channelOpenMessage.Info as ForwardedTcpipChannelInfo; if (info != null) { // Ensure this is the corresponding request if (info.ConnectedAddress == BoundHost && info.ConnectedPort == BoundPort) { if (!IsStarted) { Session.SendMessage(new ChannelOpenFailureMessage(channelOpenMessage.LocalChannelNumber, "", ChannelOpenFailureMessage.AdministrativelyProhibited)); return; } ThreadAbstraction.ExecuteThread(() => { // capture the countdown event that we're adding a count to, as we need to make sure that we'll be signaling // that same instance; the instance field for the countdown event is re-initialize when the port is restarted // and that time there may still be pending requests var pendingChannelCountdown = _pendingChannelCountdown; pendingChannelCountdown.AddCount(); try { RaiseRequestReceived(info.OriginatorAddress, info.OriginatorPort); using ( var channel = Session.CreateChannelForwardedTcpip(channelOpenMessage.LocalChannelNumber, channelOpenMessage.InitialWindowSize, channelOpenMessage.MaximumPacketSize)) { channel.Exception += Channel_Exception; channel.Bind(new IPEndPoint(HostAddress, (int)Port), this); channel.Close(); } } catch (Exception exp) { RaiseExceptionEvent(exp); } finally { // take into account that CountdownEvent has since been disposed; when stopping the port we // wait for a given time for the channels to close, but once that timeout period has elapsed // the CountdownEvent will be disposed try { pendingChannelCountdown.Signal(); } catch (ObjectDisposedException) { } } }); } } }
private void Session_ChannelOpening(object sender, MessageEventArgs <ChannelOpenMessage> e) { var channelOpenMessage = e.Message; var info = channelOpenMessage.Info as ForwardedTcpipChannelInfo; if (info != null) { // Ensure this is the corresponding request if (info.ConnectedAddress == BoundHost && info.ConnectedPort == BoundPort) { if (!_isStarted) { Session.SendMessage(new ChannelOpenFailureMessage(channelOpenMessage.LocalChannelNumber, "", ChannelOpenFailureMessage.AdministrativelyProhibited)); return; } ThreadAbstraction.ExecuteThread(() => { Interlocked.Increment(ref _pendingRequests); try { RaiseRequestReceived(info.OriginatorAddress, info.OriginatorPort); using (var channel = Session.CreateChannelForwardedTcpip(channelOpenMessage.LocalChannelNumber, channelOpenMessage.InitialWindowSize, channelOpenMessage.MaximumPacketSize)) { channel.Exception += Channel_Exception; channel.Bind(new IPEndPoint(HostAddress, (int)Port), this); channel.Close(); } } catch (Exception exp) { RaiseExceptionEvent(exp); } finally { Interlocked.Decrement(ref _pendingRequests); } }); } } }