summaryrefslogtreecommitdiff
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:33:50 -0800
commite58df62ef5e7339e5895f9f5ffdaa3452d45a69c (patch)
tree40df09ad3378e3a15149ad2b4cd083cc433dbc60
parent6b6ff0fb33ca2e0e3b014cbca595cbc50d137e42 (diff)
downloadparamiko-e58df62ef5e7339e5895f9f5ffdaa3452d45a69c.tar.gz
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 1de6ff09..21565673 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -281,6 +281,7 @@ class Transport (threading.Thread, ClosingContextManager):
arguments.
"""
self.active = False
+ self._sshclient = None
if isinstance(sock, string_types):
# convert "host:port" into (host, port)
@@ -636,6 +637,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.
@@ -646,6 +650,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):
"""