+1 vote
by (180 points)
edited by

We have a client application which uses Rebex to host a long-running SSH tunnel. We need to be able to respond to fatal tunnel errors so that we can alert the user of the need to reconnect (for example, if there's a networking failure).

We have hooked into the TunnelError event on the Ssh object. However, not all events are for fatal errors. For example, I can cancel a command using the tunnel, which results in a SocketException "An existing connection was forcibly closed by the remote host". But this does not break the tunnel.

Is there an easy way to distinguish between errors that break the tunnel and those which are transient? Do you suggest we check the IsConnected property or CheckConnectionState() method after each error?

Update: I created a condition where, after establishing the tunnel, I broke network connectivity to the SSH server. However, even though the client can no longer connect to the SSH server, the CheckConnectionState() and GetConnectionState() methods and the IsConnected properties all report that the connection is fine. Is this expected? I had hoped to use these methods to determine whether I had lost connection.

1 Answer

0 votes
by (144k points)

Actually, all TunnelError errors should result in the connection being closed. However the event occurs before that, so perhaps that explains the observerd behavior?

Detecting that a connection is still up and running is somewhat tricky because for some kinds of connectivity issues, the TCP subsystem only detects that something is wrong when some data is actually sent via the connection but no ACK packets arrive. So both IsConnected and GetConnectionState()/CheckConnectionState() only reflects the currently known state of the connection. To reliably detect connection failures, you would have to periodically call Ssh.Session.KeepAlive() method (one approach is described at https://forum.rebex.net/3484/sshsession-keepalive-method and can be used with Ssh class as well).