diff --git a/Renci.SshClient/Renci.SshNet/Channels/ChannelDirectTcpip.cs b/Renci.SshClient/Renci.SshNet/Channels/ChannelDirectTcpip.cs index baf12803..a9909c61 100644 --- a/Renci.SshClient/Renci.SshNet/Channels/ChannelDirectTcpip.cs +++ b/Renci.SshClient/Renci.SshNet/Channels/ChannelDirectTcpip.cs @@ -180,18 +180,21 @@ namespace Renci.SshNet.Channels /// /// Called when channel has no more data to receive. /// - protected override void OnEof() - { - base.OnEof(); + protected override void OnEof() { + base.OnEof(); - this._channelEof.Set(); + EventWaitHandle channelEof = this._channelEof; + if (channelEof != null) + channelEof.Set(); } protected override void OnClose() { base.OnClose(); - this._channelEof.Set(); + EventWaitHandle channelEof = this._channelEof; + if (channelEof != null) + channelEof.Set(); } protected override void OnErrorOccured(Exception exp) @@ -199,7 +202,9 @@ namespace Renci.SshNet.Channels base.OnErrorOccured(exp); // If error occured, no more data can be received - this._channelEof.Set(); + EventWaitHandle channelEof = this._channelEof; + if (channelEof != null) + channelEof.Set(); } protected override void OnDisconnected() @@ -207,7 +212,9 @@ namespace Renci.SshNet.Channels base.OnDisconnected(); // If disconnected, no more data can be received - this._channelEof.Set(); + EventWaitHandle channelEof = this._channelEof; + if (channelEof != null) + channelEof.Set(); } partial void ExecuteThread(Action action); diff --git a/Renci.SshClient/Renci.SshNet/ForwardedPortLocal.NET.cs b/Renci.SshClient/Renci.SshNet/ForwardedPortLocal.NET.cs index 9093235e..8ae14bab 100644 --- a/Renci.SshClient/Renci.SshNet/ForwardedPortLocal.NET.cs +++ b/Renci.SshClient/Renci.SshNet/ForwardedPortLocal.NET.cs @@ -13,7 +13,7 @@ namespace Renci.SshNet public partial class ForwardedPortLocal { private TcpListener _listener; - private object _listenerLocker = new object(); + private readonly object _listenerLocker = new object(); partial void InternalStart() { @@ -22,12 +22,12 @@ namespace Renci.SshNet return; IPAddress addr = this.BoundHost.GetIPAddress(); - var ep = new IPEndPoint(addr, (int)this.BoundPort); + var ep = new IPEndPoint(addr, (int)this.BoundPort); this._listener = new TcpListener(ep); this._listener.Start(); // Update bound port if original was passed as zero - this.BoundPort = (uint) ((IPEndPoint) _listener.LocalEndpoint).Port; + this.BoundPort = (uint)((IPEndPoint)_listener.LocalEndpoint).Port; this.Session.ErrorOccured += Session_ErrorOccured; this.Session.Disconnected += Session_Disconnected; @@ -55,13 +55,14 @@ namespace Renci.SshNet this.RaiseRequestReceived(originatorEndPoint.Address.ToString(), (uint)originatorEndPoint.Port); - var channel = this.Session.CreateChannel(); + using (var channel = this.Session.CreateChannel()) + { + channel.Open(this.Host, this.Port, socket); - channel.Open(this.Host, this.Port, socket); + channel.Bind(); - channel.Bind(); - - channel.Close(); + channel.Close(); + } } catch (Exception exp) { @@ -96,11 +97,11 @@ namespace Renci.SshNet if (!this.IsStarted) return; - lock (this._listenerLocker) - { - this._listener.Stop(); - this._listener = null; - } + this.Session.Disconnected -= Session_Disconnected; + this.Session.ErrorOccured -= Session_ErrorOccured; + + this.StopListener(); + this._listenerTaskCompleted.WaitOne(this.Session.ConnectionInfo.Timeout); this._listenerTaskCompleted.Dispose(); this._listenerTaskCompleted = null; @@ -108,14 +109,26 @@ namespace Renci.SshNet this.IsStarted = false; } + private void StopListener() + { + lock (this._listenerLocker) + { + if (this._listener != null) + { + this._listener.Stop(); + this._listener = null; + } + } + } + private void Session_ErrorOccured(object sender, Common.ExceptionEventArgs e) { - this._listener.Stop(); + this.StopListener(); } private void Session_Disconnected(object sender, EventArgs e) { - this._listener.Stop(); + this.StopListener(); } } }