Connection not releasing

Jul 26, 2012 at 7:33 PM

I have a project where I am connecting to a series of devices.  These devices all run dropbear and PostGres on linux. I'm currently using your software to connect an SSHtunnel to ultimately connect to postgres.  For the most part, this works pretty good.

However, when I disconnect from one device (wireless or wired) and then connect to a new device, it fails to connect. I should note, this only seems to happen on XP SP3 machines. Also note, that if I reconnect  to the same device I have no issues.

What we have discovered is that a port is not apparently properly disconnecting. If I "repair" the connection using Windows, it severs that connection and works fine after that. Rebooting the device; disconnecting the connections (by unplugging or deleting the wireless profiles) doesn't seem to have any effect. If I allow the computer to sit for approx 9-10 minutes, the hung connection is cleared.

I think it's pretty clear I'm not properly shutting down the connection. I'm using v3.5 .NET (C#) and my connect code looks like this:

        public bool Connect(int connectionTimeout)
        {
            var dtStart = DateTime.Now;

            while (DateTime.Now - dtStart < TimeSpan.FromSeconds(connectionTimeout))
            {
                SendConsoleMessage(
                    string.Format("Attempting SSH Tunnel connection -- remaining time before timeout: {0}",
                                  TimeSpan.FromSeconds(connectionTimeout) - (DateTime.Now - dtStart)));
                _sshClient =
                    new SshClient(new PasswordConnectionInfo(HostAddress, HostPort, HostUserName, HostUserPassword)
                                      {Timeout = TimeSpan.FromSeconds(10)});

                try
                {
                    _sshClient.Connect();
                    if (_sshClient == null || !_sshClient.IsConnected)
                        continue;
                }
                catch
                {
                    continue;
                }

                _sshForwardPort = new ForwardedPortLocal(RemoteHostAddress, (uint) RemoteHostPort, RemoteHostAddress,
                                                         (uint) RemoteHostPort);
                _sshClient.AddForwardedPort(_sshForwardPort);

                try
                {
                    _sshForwardPort.Start();
                    if (_sshForwardPort == null || !_sshForwardPort.IsStarted)
                    {
                        if (_sshClient != null && _sshClient.IsConnected)
                            _sshClient.Disconnect();

                        continue;
                    }
                }
                catch
                {
                    continue;
                }

                break;
            }

            var dtEnd = DateTime.Now;


            SendConsoleMessage(string.Format("Connect {0} -- time to connect to SSH : {1}",
                                             _sshClient != null && _sshClient.IsConnected ? "succeeded" : "failed",
                                             (dtEnd - dtStart)));

            return _sshClient != null && _sshClient.IsConnected;
        }

I added a lot of code in the past few days to handle retries, but I'm not married to this code.

My disconnect code looks like this:

       public void Disconnect()
        {
            SendConsoleMessage("SSH Tunnel, disconnect requested.");

            if (_sshForwardPort != null && _sshForwardPort.IsStarted)
                _sshForwardPort.Stop();

            if (_sshClient != null)
                if (_sshClient.IsConnected)
                    _sshClient.Disconnect();
        }

Can you spot what I might be doing wrong? I should note that the disconnect is only called from the dispose and the object (which implements IDisposable) is only used in a "using" block.

Any help you can provide would be immensely helpful!

CosmicFreddy

Coordinator
Aug 10, 2012 at 2:05 PM
Edited Aug 10, 2012 at 2:13 PM

Hi,

 

Sorry for late response, busy with other projects.

 

What I think happens is WinXP doesnt release or reuse sockets properly.

What you can try to do, and let me know if it works, so I could make this change for everybody, is in Session.cs file replace this:

 

        partial void SocketDisconnect()
        {
            this._socket.Disconnect(true);
        }
with this:
        partial void SocketDisconnect()
        {
            this._socket.Disconnect(false);
        }

It simply will tell system not to reuse the same socket again and it will try to use a new socket for next connection.

Hope it helps,
Thanks,
Oleg