Port-Forwardings crashes when unable to ship data

Jun 13, 2013 at 8:16 AM
Hi,

I discovered a huge problem in the current implementation of the SSH.Net PortForwarding.

To show the problem I created following test-program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Renci.SshNet;

namespace SshTestConsole
{
    class Program
    {
        static void Main(string[] args)
        {

            SshClient _sshclient = new SshClient($host, $user, $password);
            _sshclient.ErrorOccurred += _sshclient_ErrorOccurred;
            _sshclient.HostKeyReceived += _sshclient_HostKeyReceived;

            ForwardedPortLocal forwarding = new ForwardedPortLocal("127.0.0.1", 22223, "127.0.0.1", 80);
            forwarding.Exception += forwarding_Exception;
            forwarding.RequestReceived += forwarding_RequestReceived;
            _sshclient.Connect();
            _sshclient.AddForwardedPort(forwarding);
            forwarding.Start();
            Console.WriteLine("Enter to exit...");
            Console.ReadLine();
        }

        static void forwarding_RequestReceived(object sender, Renci.SshNet.Common.PortForwardEventArgs e)
        {
            Console.WriteLine("forwarding_RequestReceived: '{0}:{1}'", e.OriginatorHost, e.OriginatorPort); 
        }

        static void forwarding_Exception(object sender, Renci.SshNet.Common.ExceptionEventArgs e)
        {
            Console.WriteLine("forwarding_Exception: {0}\n{1}", e.Exception.Message, e.Exception.StackTrace);
        }

        static void _sshclient_HostKeyReceived(object sender, Renci.SshNet.Common.HostKeyEventArgs e)
        {
            Console.WriteLine("_sshclient_HostKeyReceived: {0}, {1}, {2}, {3}, {4}", e.CanTrust, e.FingerPrint, e.HostKey, e.HostKeyName, e.KeyLength); 
        }

        static void _sshclient_ErrorOccurred(object sender, Renci.SshNet.Common.ExceptionEventArgs e)
        {
            Console.WriteLine("_sshclient_ErrorOccurred: {0}\n{1}", e.Exception.Message, e.Exception.StackTrace);
        }
    }
}
The forwarding works. But when you do some quick reloads (Shift+F5) of the webpage the
forwarding crashes and stops working.
_sshclient_HostKeyReceived: True, System.Byte[], System.Byte[], ssh-rsa, 2048
Enter to exit...
forwarding_RequestReceived: '127.0.0.1:64230'
forwarding_RequestReceived: '127.0.0.1:64231'
_sshclient_ErrorOccurred: Eine bestehende Verbindung wurde softwaregesteuert
durch den Hostcomputer abgebrochen
bei System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
bei Renci.SshNet.Channels.ChannelDirectTcpip.InternalSocketSend(Byte[] data) in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Channels\ChannelDirectTcpip.NET40.cs:Zeile
bei Renci.SshNet.Channels.ChannelDirectTcpip.OnData(Byte[] data) in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Channels\ChannelDirectTcpip.cs:Zeile 157.
bei Renci.SshNet.Channels.Channel.OnChannelData(Object sender, MessageEventArgs1 e) in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Channels\Channel.cs:Zeile 590.
bei System.EventHandler
1.Invoke(Object sender, TEventArgs e)
bei Renci.SshNet.Session.OnChannelDataReceived(ChannelDataMessage message) in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Session.cs:Zeile 1392.
bei Renci.SshNet.Session.HandleMessage(ChannelDataMessage message) in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Session.cs:Zeile 1034.
bei CallSite.Target(Closure , CallSite , Session , Object )
bei Renci.SshNet.Session.HandleMessageCore(Message message) in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Session.NET40.cs:Zeile 20.
bei Renci.SshNet.Session.MessageListener() in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Session.cs:Zeile 1589.
forwarding_RequestReceived: '127.0.0.1:64232'
forwarding_Exception: Eine bestehende Verbindung wurde softwaregesteuert
durch den Hostcomputer abgebrochen
bei Renci.SshNet.Session.WaitHandle(WaitHandle waitHandle) in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Session.cs:Zeile 642.
forwarding_Exception: Eine bestehende Verbindung wurde softwaregesteuert
durch den Hostcomputer abgebrochen
bei Renci.SshNet.Session.WaitHandle(WaitHandle waitHandle) in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Session.cs:Zeile 642.
forwarding_Exception: Eine bestehende Verbindung wurde softwaregesteuert
durch den Hostcomputer abgebrochen
bei Renci.SshNet.Session.WaitHandle(WaitHandle waitHandle) in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Session.cs:Zeile 642.
bei Renci.SshNet.Channels.Channel.Close(Boolean wait) in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Channels\Channel.cs:Zeile 518.
bei Renci.SshNet.Channels.Channel.Close() in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Channels\Channel.cs:Zeile 223.
bei Renci.SshNet.Channels.ChannelDirectTcpip.Close() in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\Channels\ChannelDirectTcpip.cs:Zeile 146.
bei Renci.SshNet.ForwardedPortLocal.<>c__DisplayClass3.<InternalStart>b__2() in c:\Users\srinkes\Documents\Visual Studio 2012\Projects\Project\Renci.SshNet\ForwardedPortLocal.NET.cs:Zeile 62.
IMHO it's OK to throw an Exception (for logging purpose), but it's not OK that the whole
forwarding stops working. Also the IsStarted property is still true :(
I will take some time to investigate for a fix, but hints/ideas are very welcome.

Greetz
Jun 13, 2013 at 9:26 AM
I followed the stacktrace to Renci.SshNet.Channels.ChannelDirectTcpip.InternalSocketSend

And change it from:
        partial void InternalSocketSend(byte[] data)
        {
                this._socket.Send(data, 0, data.Length, SocketFlags.None);
        }
to
        partial void InternalSocketSend(byte[] data)
        {
            try
            {
                this._socket.Send(data, 0, data.Length, SocketFlags.None);
            }
            catch (Exception exp)
            {
                Console.WriteLine("InternalSocketSend Exception: " + exp.Message + "\n" + exp.StackTrace);
            }
        }
Now the forwardings do not crash anymore in my use case.
Jun 25, 2013 at 3:16 PM
Hi,

Any thoughts on this?
A fix upstream would be nice IMHO

Greetz