<PackageReference Include="SSH.NET" Version="2016.0.0-beta3" />

ChannelForwardedTcpip

Implements "forwarded-tcpip" SSH channel.
using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Messages.Connection; using System; using System.Net; using System.Net.Sockets; namespace Renci.SshNet.Channels { internal class ChannelForwardedTcpip : ServerChannel, IChannelForwardedTcpip, IDisposable { private readonly object _socketShutdownAndCloseLock = new object(); private Socket _socket; private IForwardedPort _forwardedPort; public override ChannelTypes ChannelType => ChannelTypes.ForwardedTcpip; internal ChannelForwardedTcpip(ISession session, uint localChannelNumber, uint localWindowSize, uint localPacketSize, uint remoteChannelNumber, uint remoteWindowSize, uint remotePacketSize) : base(session, localChannelNumber, localWindowSize, localPacketSize, remoteChannelNumber, remoteWindowSize, remotePacketSize) { } public void Bind(IPEndPoint remoteEndpoint, IForwardedPort forwardedPort) { if (!base.IsConnected) throw new SshException("Session is not connected."); _forwardedPort = forwardedPort; _forwardedPort.Closing += ForwardedPort_Closing; try { _socket = SocketAbstraction.Connect(remoteEndpoint, base.ConnectionInfo.Timeout); SendMessage(new ChannelOpenConfirmationMessage(base.RemoteChannelNumber, base.LocalWindowSize, base.LocalPacketSize, base.LocalChannelNumber)); } catch (Exception ex) { SendMessage(new ChannelOpenFailureMessage(base.RemoteChannelNumber, ex.ToString(), 2, "en")); throw; } byte[] array = new byte[base.RemotePacketSize]; SocketAbstraction.ReadContinuous(_socket, array, 0, array.Length, SendData); } protected override void OnErrorOccured(Exception exp) { base.OnErrorOccured(exp); ShutdownSocket(SocketShutdown.Send); } private void ForwardedPort_Closing(object sender, EventArgs eventArgs) { ShutdownSocket(SocketShutdown.Send); } private void ShutdownSocket(SocketShutdown how) { if (_socket != null && _socket.Connected) { lock (_socketShutdownAndCloseLock) { Socket socket = _socket; if (socket != null && socket.Connected) socket.Shutdown(how); } } } private void CloseSocket() { if (_socket != null) { lock (_socketShutdownAndCloseLock) { Socket socket = _socket; if (socket != null) { socket.Dispose(); _socket = null; } } } } protected override void Close(bool wait) { IForwardedPort forwardedPort = _forwardedPort; if (forwardedPort != null) { forwardedPort.Closing -= ForwardedPort_Closing; _forwardedPort = null; } ShutdownSocket(SocketShutdown.Send); base.Close(wait); CloseSocket(); } protected override void OnData(byte[] data) { base.OnData(data); Socket socket = _socket; if (socket != null && socket.Connected) SocketAbstraction.Send(socket, data, 0, data.Length); } } }