summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOmer Anson <omer.anson@toganetworks.com>2017-02-09 18:59:03 +0200
committerJeff Forcier <jeff@bitprophet.org>2017-02-20 14:40:14 -0800
commit718e821b4a6d68b0daf3e7061a1cc78ee8389896 (patch)
treebcdd539f961419b4a2bd90bc113c544fba4b4e00
parent11f4c2fa13aadd000a22f33edb9ef4d70cf03236 (diff)
Add back-reference from Transport to the SSHClient that created it
In some cases, the SSH client is created, the command is executed, the streams are extracted, and the explicit reference to SSHClient is then discarded (since it was e.g. created in a function that only returns the streams). In this case, the SHSClient may be garbage collected, and the connection's state is undefined. This fix adds a reference from Transport to the SSHClient that created it. The streams have a reference to the Channel, which references the Transport. Now that the Transport references the SSHClient, it won't be garbage collected until it is closed. Closes-Bug: #44 Related-Bug: #344
-rw-r--r--paramiko/client.py1
-rw-r--r--paramiko/transport.py5
2 files changed, 6 insertions, 0 deletions
diff --git a/paramiko/client.py b/paramiko/client.py
index ebf21b08..18139416 100644
--- a/paramiko/client.py
+++ b/paramiko/client.py
@@ -336,6 +336,7 @@ class SSHClient (ClosingContextManager):
if banner_timeout is not None:
t.banner_timeout = banner_timeout
t.start_client()
+ t.set_sshclient(self)
ResourceManager.register(self, t)
server_key = t.get_remote_server_key()
diff --git a/paramiko/transport.py b/paramiko/transport.py
index f1d590ec..6d7dd0e8 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -282,6 +282,7 @@ class Transport (threading.Thread, ClosingContextManager):
arguments.
"""
self.active = False
+ self._sshclient = None
if isinstance(sock, string_types):
# convert "host:port" into (host, port)
@@ -637,6 +638,9 @@ class Transport (threading.Thread, ClosingContextManager):
Transport._modulus_pack = None
return False
+ def set_sshclient(self, sshclient):
+ self._sshclient = sshclient
+
def close(self):
"""
Close this session, and any open channels that are tied to it.
@@ -647,6 +651,7 @@ class Transport (threading.Thread, ClosingContextManager):
for chan in list(self._channels.values()):
chan._unlink()
self.sock.close()
+ self._sshclient = None
def get_remote_server_key(self):
"""