Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SFTP: "client not connected" after server closed connection #1474

Closed
mus65 opened this issue Aug 23, 2024 · 4 comments · Fixed by #1484
Closed

SFTP: "client not connected" after server closed connection #1474

mus65 opened this issue Aug 23, 2024 · 4 comments · Fixed by #1484

Comments

@mus65
Copy link
Contributor

mus65 commented Aug 23, 2024

As reported by multiple people here #843 (comment) , #1362 does not completely fix the general issue. A "client not connected" exception can still happen after checking for IsConnected .

I will try to reproduce this and create a PR.

@toblast
Copy link

toblast commented Aug 23, 2024

This issue happened only if I didn't set the KeepAliveInternal. Figured it might be important for your tests or for someone trying to avoid the issue.

@mus65
Copy link
Contributor Author

mus65 commented Aug 24, 2024

As mention by Rob-Hague in #843 (comment) , this can't really be fixed. IsConnected just can't be relied upon because you have to actually send data to notice that the connection is gone.

Even if the check that throws the exception would be removed, the sending itself would fail. The only way to avoid this, is to configure a keep alive on the client or the server.

@mus65 mus65 closed this as completed Aug 24, 2024
@mus65
Copy link
Contributor Author

mus65 commented Sep 2, 2024

Reopening this. We have a case where the keep alive doesn't help. Affected server is PSFTPd .

I think there is at least one issue in SSH.NET: if the "Client not connected" exception happens, I would expect IsConnected to be false after this, but it seems like it stays true so another OpenAsync fails again with Client not connected..

Idea why the keep alive doesn't help: maybe the SFTP subsession needs its own keep-alive? Or maybe the server is just not reacting to keep alives and closing the session either way....

fyi @Rob-Hague

Renci.SshNet.Common.SshConnectionException: Client not connected.
   at Renci.SshNet.Session.SendMessage(Message message)
   at Renci.SshNet.Session.Renci.SshNet.ISession.SendMessage(Message message)
   at Renci.SshNet.Channels.Channel.SendData(Byte[] data, Int32 offset, Int32 size)
   at Renci.SshNet.Channels.Channel.SendData(Byte[] data)
   at Renci.SshNet.SubsystemSession.SendData(Byte[] data)
   at Renci.SshNet.Sftp.SftpSession.SendMessage(SftpMessage sftpMessage)
   at Renci.SshNet.Sftp.SftpSession.SendRequest(SftpRequest request)
   at Renci.SshNet.Sftp.SftpSession.RequestOpenAsync(String path, Flags flags, CancellationToken cancellationToken)
   at Renci.SshNet.Sftp.SftpSession.RequestOpenAsync(String path, Flags flags, CancellationToken cancellationToken)
   at Renci.SshNet.Sftp.SftpFileStream.OpenAsync(ISftpSession session, String path, FileMode mode, FileAccess access, Int32 bufferSize, CancellationToken cancellationToken)

@mus65 mus65 reopened this Sep 2, 2024
@mus65
Copy link
Contributor Author

mus65 commented Sep 3, 2024

There also seems be a related issue where the client can get into a broken state. Even after re-connect with ConnectAsync, any following OpenAsync keeps throwing the exception from the old session. It seems like Session.Reset() is not called in some cases (which would reset the exception handle).

We currently work around both issues by explicitly disconnecting before doing a reconnect. This seems to work (for now).

Renci.SshNet.Common.SshConnectionException: An established connection was aborted by the server.
   at Renci.SshNet.Session.WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout)
   at Renci.SshNet.Session.Renci.SshNet.ISession.WaitOnHandle(WaitHandle waitHandle)
   at Renci.SshNet.Channels.Channel.GetDataLengthThatCanBeSentInMessage(Int32 messageLength)
   at Renci.SshNet.Sftp.SftpSession.SendRequest(SftpRequest request)
   at Renci.SshNet.Sftp.SftpSession.RequestOpenAsync(String path, Flags flags, CancellationToken cancellationToken)
   at Renci.SshNet.Sftp.SftpSession.RequestOpenAsync(String path, Flags flags, CancellationToken cancellationToken)
   at Renci.SshNet.Sftp.SftpFileStream.OpenAsync(ISftpSession session, String path, FileMode mode, FileAccess access, Int32 bufferSize, CancellationToken cancellationToken)

Also worth mentioning that when the server disconnects the session, we do get an ErrorOccurred event with this exception (as expected).

mus65 added a commit to mus65/SSH.NET that referenced this issue Sep 5, 2024
if the server closes the session and the client reconnects,
this currently leads to a broken state because the session
is re-created, but the SFTP subsession is not and still
references the old session.

This causes all operations to fail with "client not connected" or
even throwing the "An established connection was aborted by the server."
exception of the old session.

Always re-create the SFTP subsession to fix this.

fixes sshnet#1474
mus65 added a commit to mus65/SSH.NET that referenced this issue Sep 5, 2024
if the server closes the session and the client reconnects,
this currently leads to a broken state because the session
is re-created, but the SFTP subsession is not and still
references the old session.

This causes all operations to fail with "client not connected" or
even throwing the "An established connection was aborted by the server."
exception of the old session.

Always re-create the SFTP subsession to fix this.

fixes sshnet#1474
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants