-
Notifications
You must be signed in to change notification settings - Fork 162
_close_event doesn't set on an error in SSHSession.connection_lost #743
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
Comments
Thanks for the report. Uncaught exceptions generally bubble back out to the SSHConnection's It looks like this same issue could apply to SSHClient/SSHServer, when their I guess in this case it might be best to copy the session into a local variable and setting The other option would be to catch and log errors in the cleanup code, without going all the back up to |
Here's a first cut at a fix for this: diff --git a/asyncssh/channel.py b/asyncssh/channel.py
index ddf1440..0778abf 100644
--- a/asyncssh/channel.py
+++ b/asyncssh/channel.py
@@ -26,6 +26,7 @@ import codecs
import inspect
import re
import signal as _signal
+import sys
from types import MappingProxyType
from typing import TYPE_CHECKING, Any, AnyStr, Awaitable, Callable
from typing import Dict, Generic, Iterable, List, Mapping, Optional
@@ -225,7 +226,13 @@ class SSHChannel(Generic[AnyStr], SSHPacketHandler):
self._request_waiters = []
if self._session is not None:
- self._session.connection_lost(exc)
+ # pylint: disable=broad-except
+ try:
+ self._session.connection_lost(exc)
+ except Exception:
+ self.logger.debug1('Uncaught exception in session ignored',
+ exc_info=sys.exc_info)
+
self._session = None
self._close_event.set()
diff --git a/asyncssh/connection.py b/asyncssh/connection.py
index 94dcb5e..11a3d0d 100644
--- a/asyncssh/connection.py
+++ b/asyncssh/connection.py
@@ -1075,7 +1075,13 @@ class SSHConnection(SSHPacketHandler, asyncio.Protocol):
self._wait = None
if self._owner: # pragma: no branch
- self._owner.connection_lost(exc)
+ # pylint: disable=broad-except
+ try:
+ self._owner.connection_lost(exc)
+ except Exception:
+ self.logger.debug1('Uncaught exception in owner ignored',
+ exc_info=sys.exc_info)
+
self._owner = None
self._cancel_login_timer() Errors in the connection_lost() callback in either SSHClient/SSHServer or SSHClientSession/SSHServerSession are logged (at debug level 1) and include a traceback of the exception. However, processing of the cleanup continues on after that as if nothing happened. This should be enough to always close the AsyncSSH connection successfully, but there may be some cleanup in the session or owner which doesn't run completely. |
This fix is now available in the "develop" branch as commit 8ae6b2b. Thanks for reporting the issue! |
This fix is now included in AsyncSSH 2.21.0. |
If an exception occurs when calling the SSHSession.connection_lost method (which can happen since I can inherit this class), we will get into an infinite loop because the SSHConnection's self._close_event.set() method in the _cleanup() method will not be invoked
asyncssh/channel.py
asyncssh/connection.py
call stack
The text was updated successfully, but these errors were encountered: