PortForwading Bug

Feb 3, 2014 at 10:25 AM
Edited Feb 5, 2014 at 7:42 AM
Hi,

I detected a problem when using PortForwading.

The first time, the tunneling is working properly, but after closing, the forwading rule is still working,
 ' RENCI
    Dim client As SshClient
    Dim port As ForwardedPortLocal

    Public Sub SSHDisconnect(ByRef _client As SshClient, ByRef _port As ForwardedPortLocal)
        _port.Stop()
        _client.Disconnect()
        _client.RemoveForwardedPort(_port)
    End Sub
I use this sequence for open:
 Public Function SSHConect(ByRef _client As SshClient, ByRef _port As ForwardedPortLocal, _SSHIPserver As String, _SSHPortServer As Integer, _SSHForwardIP As String, _SSHForwardPort As Integer) As Boolean
        If (Not IsNothing(_client)) Then
            If (_client.IsConnected) Then
                '_port.Stop()
                '_client.RemoveForwardedPort(_port)
                _client.Disconnect()
            End If
        End If
        SSHConect = False
        _client = New SshClient(_SSHIPserver, _SSHPortServer, "userssh", "111111")

        _client.KeepAliveInterval = New TimeSpan(0, 0, 30)
        _client.Connect()
        _client.SendKeepAlive()


        If _client.IsConnected Then
            Try
                _port = New ForwardedPortLocal("127.0.0.1", _SSHForwardPort, _SSHForwardIP, _SSHForwardPort)
                _client.AddForwardedPort(_port)
                _port.Start()

                If (_port.IsStarted) Then
                    SSHConect = True
                Else
                    SSHConect = False
                End If

            Catch ex As Exception
                MessageBox.Show(ex.ToString())
                SSHConect = False
            End Try
        End If
    End Function
When connection is established first time is possible to SELECT from SQLServer database without problems.

_port = New ForwardedPortLocal("127.0.0.1", 14444, _SSHForwardIP, 1433)
and _port.IsStarted is True

After close connection and open to another SSH server, the first portforwading rule is still running, and the next rule doesn't works.

This is the state for second time with connecting to a new ssh server ip, connected state is true.

Image

Any idea how to repair??
Feb 3, 2014 at 1:02 PM
I'm unable to reproduce the issue.
Local Port Forwardings open and close properly.

Your Pics are too small to see anything.
Feb 4, 2014 at 8:02 AM
Edited Feb 4, 2014 at 8:12 AM
Thanks for reply.

yes, really small.....I upload the pictures to another site.

http://subefotos.com/ver/?013a03f6bd067f31fe7632f954b9bb45o.jpg

https://drive.google.com/file/d/0BzK7a0IKeyr4dHdXUEpRYm8yV2M/edit?usp=sharing

Image




Could be a problem with init sequence, because it create a new instance each time in the SSHConnect function?¿

_client = New SshClient(_SSHIPserver, _SSHPortServer, "userssh", "11111111")


I will try to collect more data
Feb 5, 2014 at 7:28 AM
I am facing the exact same problem, see issue: http://sshnet.codeplex.com/workitem/1867
Feb 5, 2014 at 7:43 AM
Yes, I commented your issue bimbimone.
Feb 5, 2014 at 7:48 AM
Edited Feb 5, 2014 at 7:48 AM
bimbimone wrote:
I am facing the exact same problem, see issue: http://sshnet.codeplex.com/workitem/1867
Actually no. You two are talking about different things.
You get a "Only one usage of each socket address (protocol/network address/port) is normally permitted", while e5490626 is talking
about his old forwarding is still used "successfully" and he doesn't get a Exception. At least he never mentioned an exception.

In your case it would be helpfull (since I don't know if your app cleans everything correctly on exit) to add some debug to your app.
I've never seen this issues and I use PortForwarding a lot.

I'm quite sure there is no problem in this lib and the bug must be in your applications.

Make sure you clean up everything correctly.
Feb 5, 2014 at 8:00 AM
Edited Feb 5, 2014 at 8:01 AM
da_rinkes wrote:
bimbimone wrote:
I am facing the exact same problem, see issue: http://sshnet.codeplex.com/workitem/1867
Actually no. You two are talking about different things.
You get a "Only one usage of each socket address (protocol/network address/port) is normally permitted", while e5490626 is talking
about his old forwarding is still used "successfully" and he doesn't get a Exception. At least he never mentioned an exception.
I think our issues are related but the exception I am getting is when I try to open the ports again, not when I try to close them. This is the exception you get when ports are still in use.
I'm quite sure there is no problem in this lib and the bug must be in your applications.

Make sure you clean up everything correctly.
I have made an effort in cleaning up but still i face this issue. I will take a look to see if other processes keep the port open (maybe on the listening side).
But just to check. When one closes a forwarded port, is it normal that this takes seconds to complete?
Feb 5, 2014 at 8:13 AM
Edited Feb 5, 2014 at 8:14 AM
I used this little console-application and everything is working fine:
using System;
using System.Diagnostics;
using Renci.SshNet;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var client = new SshClient(IP, USER, PASSWORD);
            try
            {
                client.Connect();
                Console.WriteLine("Started first client");
                Console.WriteLine(RunCmd("netstat -ant | find \"22222\""));

                var fw = new ForwardedPortLocal("127.0.0.1", 22222, "127.0.0.1", 22);
                client.AddForwardedPort(fw);
                fw.Start();

                Console.WriteLine("Started Forwarding");
                Console.WriteLine(RunCmd("netstat -ant | find \"22222\""));

                Console.WriteLine("FW started: " + fw.IsStarted);
                var fwclient = new SshClient("127.0.0.1", 22222, USER, PASSWORD);
                fwclient.Connect();

                Console.WriteLine("Started second client");
                Console.WriteLine(RunCmd("netstat -ant | find \"22222\""));

                Console.WriteLine("Press Enter to stop");
                Console.ReadLine();

                fwclient.Disconnect();
                Console.WriteLine("Stopped second Client");

                fw.Stop();
                client.RemoveForwardedPort(fw);
                Console.WriteLine("Stopped Forwarding");
                Console.WriteLine(RunCmd("netstat -ant | find \"22222\""));
                client.Disconnect();
                Console.WriteLine("Stopped first client");
                Console.WriteLine(RunCmd("netstat -ant | find \"22222\""));
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }

            Console.ReadLine();
        }

        private static string RunCmd(string cmd)
        {
            var proc = new Process
            {
                StartInfo =
                {
                    FileName = "cmd.exe",
                    Arguments = "/c " + cmd,
                    UseShellExecute = false,
                    RedirectStandardOutput = true
                }
            };
            proc.Start();
            proc.WaitForExit();
            return proc.StandardOutput.ReadToEnd();
        }
    }
}
Example- Output:
Started first client

Started Forwarding
  TCP    127.0.0.1:22222        0.0.0.0:0              ABHÖREN         InHost


FW started: True
Started second client
  TCP    127.0.0.1:22222        0.0.0.0:0              ABHÖREN         InHost

  TCP    127.0.0.1:22222        127.0.0.1:51105        HERGESTELLT     InHost

  TCP    127.0.0.1:51105        127.0.0.1:22222        HERGESTELLT     InHost


Press Enter to stop

Stopped second Client
Stopped Forwarding
  TCP    127.0.0.1:22222        127.0.0.1:51105        HERGESTELLT     InHost

  TCP    127.0.0.1:51105        127.0.0.1:22222        HERGESTELLT     InHost


Stopped first client
  TCP    127.0.0.1:22222        127.0.0.1:51105        HERGESTELLT     InHost

  TCP    127.0.0.1:51105        127.0.0.1:22222        HERGESTELLT     InHost
The ListenSocket of the forwarding gets cleaned up as expected.
What does netstat -ant say after you stop your forwarding?
But just to check. When one closes a forwarded port, is it normal that this takes seconds to complete?
No.
Feb 5, 2014 at 8:20 AM
Thank you for the quick answer! I will try your example project and see what happens.
Feb 5, 2014 at 9:14 AM
Thanks to your example I was able to 'pin-point' my problem and I have found my solution.
You were right, this is not a bug in the library it was my very own application that was causing this trouble.

The problem was that other processes for whom I had created the local port forwarding, kept one end of the port open. (In my case adb.exe, android debug bridge).

The solution is to first close these processes before stopping the forwarded ports. Now stopping is completing fast and successfully.

Thanks for the great support and sorry for the inconvenience.
Feb 5, 2014 at 9:18 AM
Edited Feb 5, 2014 at 9:38 AM
bimbimone wrote:
Thanks to your example I was able to 'pin-point' my problem and I have found my solution.
You were right, this is not a bug in the library it was my very own application that was causing this trouble.

The problem was that other processes for whom I had created the local port forwarding, kept one end of the port open. (In my case adb.exe, android debug bridge).

The solution is to first close these processes before stopping the forwarded ports. Now stopping is completing fast and successfully.

Thanks for the great support and sorry for the inconvenience.
Good to hear :)

But its still quite strange, that adb is forcing the listen port to stay open. Is the listen port gone in netstat -ant?
I would have expected the listen port to close and adb to stop with an error like "connection lost".
Feb 10, 2014 at 10:23 AM
I read last comments, but I'm not able to solve.

I do this next test.
I made a TEMP database on two sql servers availables with 2 freeSSH servers for each network.
I create a temp users for SSH server
With a blank Windows form project I draw 2 buttons and 2 richtectbox. I used VB.

From Click event on button 1 I write to conenct to server 1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        RichTextBox1.AppendText("Connecting...." & vbNewLine)

      

        Dim client As SshClient = New SshClient("77.73.166.66", 1443, "tempuser", "tempuser")
        Try
            client.Connect()
            RichTextBox1.AppendText("Connected to 77.73.166.66:1443" & vbNewLine)
            Dim fw As ForwardedPortLocal = New ForwardedPortLocal("127.0.0.1", 14444, "192.168.1.3", 1433)
            client.AddForwardedPort(fw)
            fw.Start()

            Dim query As String = "select * from temp"
            Dim CadenaDEconexion As String = "data source =127.0.0.1,14444; initial catalog = TEMP; user id = tempuser; password = tempuser; MultipleActiveResultSets=True"

            Dim cnn As New SqlConnection(CadenaDEconexion)
            Dim cmd As New SqlCommand
            Dim rdr As SqlDataReader
            cnn.Open()
            cmd.Connection = cnn
            cmd.CommandText = query
            rdr = cmd.ExecuteReader

            While rdr.Read
                RichTextBox1.AppendText(rdr(0) & " " & rdr(1) & vbNewLine)
            End While

            rdr.Close()
            cnn.Close()

            fw.Stop()
            client.RemoveForwardedPort(fw)
            client.Disconnect()
        Catch ex As Exception

        End Try
    End Sub
On the Click from button2 to connect to server 2


    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        RichTextBox2.AppendText("Connecting...." & vbNewLine)
        Dim client As SshClient = New SshClient("77.73.161.57", 1443, "tempuser", "tempuser")
        Try
            client.Connect()
            RichTextBox2.AppendText("Connected to 77.73.161.57:1443" & vbNewLine)
            Dim fw As ForwardedPortLocal = New ForwardedPortLocal("127.0.0.1", 14444, "192.168.1.3", 1433)
            client.AddForwardedPort(fw)
            fw.Start()

            Dim query As String = "select * from temp"
            Dim CadenaDEconexion As String = "data source =127.0.0.1,14444; initial catalog = TEMP; user id = tempuser; password = tempuser; MultipleActiveResultSets=True"

            Dim cnn As New SqlConnection(CadenaDEconexion)
            Dim cmd As New SqlCommand
            Dim rdr As SqlDataReader
            cnn.Open()
            cmd.Connection = cnn
            cmd.CommandText = query
            rdr = cmd.ExecuteReader

            While rdr.Read
                RichTextBox2.AppendText(rdr(0) & " " & rdr(1) & vbNewLine)
            End While

            rdr.Close()
            cnn.Close()

            fw.Stop()
            client.RemoveForwardedPort(fw)
            client.Disconnect()


        Catch ex As Exception

        End Try
    End Sub
TEST steps:

I Start application:
Button1 Connect to Server1----- OK
Query restult------>
Connected to 77.73.166.66:1443
Full 1
My name
Close application

Start application
Button2 Connect to server2 ----- OK
Query result ----->
Full 2
My name 2
Close application


Start application
Button1 Connect to server 1 ---> ok
Query Result --->
Full 1
My name
WITHOUT close application
Button2 Connecto to server 2 ---> Client.IsConnected shows True
but...Query result--->
Full 1
My name


Returns the results from Client1.

You can use my servers data to try if you need.

What I'm doing wrong??
Feb 10, 2014 at 10:34 AM
You are using the same port for both LocalForwards.
Usually you should get an exception... but I'm bad in reading VB

Change the port 14444 in Button2_Click to something different, e.g 14445.
Feb 11, 2014 at 10:38 AM
But the forwading port is closed before reopen, I think this should works fine.

in fact, I'm using a Chilkat SSH trial component while we find a solution for SSH.net, and works very well just like that.
Feb 11, 2014 at 11:25 AM
Edited Feb 11, 2014 at 11:56 AM
Hi,

I could reproduce your issue with your code and credentials.
The problem in fact isn't SSH.Net. Its the SqlConnection pool.

To make it clear, the problem is your connection/query/result seems to get cached.
So same connection/query, result is returned from the cache not the actual server.

If you clear the pool, in C# it's "SqlConnection.ClearAllPools()" or "SqlConnection.ClearPool(sql)", everything is fine.

My Code:
using System;
using System.Data.SqlClient;
using Renci.SshNet;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string ip1 = "77.73.166.66";
            string ip2 = "77.73.161.57";
            try
            {
                GetData(ip1);
                GetData(ip2);
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }

            Console.WriteLine("Press Enter to exit");
            Console.ReadLine();
        }

        private static void GetData(string ip)
        {
            Console.WriteLine("Getting Data from: " + ip);
            var client = new SshClient(ip, 1443, "tempuser", "tempuser");
            client.Connect();

            var fw = new ForwardedPortLocal("127.0.0.1", 14444, "192.168.1.3", 1433);
            client.AddForwardedPort(fw);
            fw.Start();

            var query = "select * from temp";
            var foo = "data source =127.0.0.1,14444; initial catalog = TEMP; user id = tempuser; password = tempuser; MultipleActiveResultSets=True";

            var sql = new SqlConnection(foo);
            var cmd = new SqlCommand();

            sql.Open();
            cmd.Connection = sql;
            cmd.CommandText = query;

            var reader = cmd.ExecuteReader();

            while (reader.Read())
            {
                Console.WriteLine(reader[0] + " " + reader[1]);
            }

            reader.Close();
            sql.Close();

            // this fixes the issue
            //SqlConnection.ClearAllPools();
            SqlConnection.ClearPool(sql);


            fw.Stop();
            client.RemoveForwardedPort(fw);
            client.Disconnect();
        }
    }
}
Also if you don't clear the pool, you can send sql queries to localhost:14443 without having any connection to it and
get the cached result.

Caching is so awesome... ;)
Feb 18, 2014 at 2:25 PM
Hi!

Thanks a lot!!

It seems run ok with the ClearPool. I have the doubt why Chilkat component don't need the Clearpool, can be they do it inside the DLL.

Thanks for your time.
Mar 21, 2014 at 11:24 AM
Hello,

I'm worry to announce this problem is still present under Windows XP.

The SqlConnection.ClearAllPools() solution runs fine under Windows 7, but under XP breaks still.

I debug just this code:
    //  Wait for key exchange to be completed
                    this.WaitHandle(this._keyExchangeCompletedWaitHandle);

                    //  If sessionId is not set then its not connected
                    if (this.SessionId == null)
                    {
                        this.Disconnect();
                        return;
                    }

                    //  Request user authorization service
                    this.SendMessage(new ServiceRequestMessage(ServiceName.UserAuthentication));

                    //  Wait for service to be accepted
                    this.WaitHandle(this._serviceAccepted);
On Session.cs file

The exception shows:

"No se controló System.NullReferenceException
Message=Referencia a objeto no establecida como instancia de un objeto.
InnerException: "

on

private void Session_ErrorOccured(object sender, Common.ExceptionEventArgs e)
    {
        this._listener.Stop();
    }

This exception only appears the second time that I open the connection.
The example also fails on XP SP3 machine, without the SQLCOnnection.clearallpools() only opens the portforwading to one server, and the second tunnel stay to the first connection,

With the clearallpools() also rasie the exception System.NullReferenceException

:_(((
:_((

I try with Chilkat demo, and run fine, using the SQLCOnnectino.clearallpools()

I would like solve the SSH.NET problem,

please help.
Mar 21, 2014 at 11:49 AM
Sorry, Its not an SSH.NET bug/problem. It's an bug of your app.
Btw. Please use english exceptions and post code.
Else it's just guessing,
Apr 4, 2014 at 4:47 PM
Hi,

I upload this sample code to test

https://drive.google.com/file/d/0BzK7a0IKeyr4OE9rSDJTMHlFS2s/edit?usp=sharing

Te same in Windows 7 run ok, in XP doesn't


I will appreciatte any help