diff options
author | Mark Hirota <mhirota@impinj.com> | 2016-07-20 14:51:02 -0700 |
---|---|---|
committer | Jeff Forcier <jeff@bitprophet.org> | 2016-12-05 19:13:37 -0800 |
commit | c1ac40ae74e4dc0454172e6e2abd888fca23a2d8 (patch) | |
tree | 9f19fa82429f9c3abd2835d641d2d4b3a566d8cd | |
parent | bd9154edcb9d9e734f30e071d4fe86dd09bcc089 (diff) |
Add timeout to Transport.start_client()
-rw-r--r-- | paramiko/client.py | 2 | ||||
-rw-r--r-- | paramiko/transport.py | 11 |
2 files changed, 9 insertions, 4 deletions
diff --git a/paramiko/client.py b/paramiko/client.py index 40cd5cf2..69666360 100644 --- a/paramiko/client.py +++ b/paramiko/client.py @@ -335,7 +335,7 @@ class SSHClient (ClosingContextManager): t.set_log_channel(self._log_channel) if banner_timeout is not None: t.banner_timeout = banner_timeout - t.start_client() + t.start_client(timeout=timeout) ResourceManager.register(self, t) server_key = t.get_remote_server_key() diff --git a/paramiko/transport.py b/paramiko/transport.py index c352246c..764486a8 100644 --- a/paramiko/transport.py +++ b/paramiko/transport.py @@ -1,4 +1,5 @@ # Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com> +# Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com> # # This file is part of paramiko. # @@ -444,7 +445,7 @@ class Transport (threading.Thread, ClosingContextManager): # We need the FQDN to get this working with SSPI self.gss_host = socket.getfqdn(gss_host) - def start_client(self, event=None): + def start_client(self, event=None, timeout=None): """ Negotiate a new SSH2 session as a client. This is the first step after creating a new `.Transport`. A separate thread is created for protocol @@ -455,7 +456,7 @@ class Transport (threading.Thread, ClosingContextManager): be triggered. On failure, `is_active` will return ``False``. (Since 1.4) If ``event`` is ``None``, this method will not return until - negotation is done. On success, the method returns normally. + negotiation is done. On success, the method returns normally. Otherwise an SSHException is raised. After a successful negotiation, you will usually want to authenticate, @@ -472,6 +473,9 @@ class Transport (threading.Thread, ClosingContextManager): :param .threading.Event event: an event to trigger when negotiation is complete (optional) + :param float timeout: + a timeout, in seconds, for SSH2 session negotiation (optional) + :raises SSHException: if negotiation fails (and no ``event`` was passed in) """ @@ -485,6 +489,7 @@ class Transport (threading.Thread, ClosingContextManager): # synchronous, wait for a result self.completion_event = event = threading.Event() self.start() + max_time = time.time() + timeout if timeout is not None else None while True: event.wait(0.1) if not self.active: @@ -492,7 +497,7 @@ class Transport (threading.Thread, ClosingContextManager): if e is not None: raise e raise SSHException('Negotiation failed.') - if event.is_set(): + if event.is_set() or (timeout is not None and time.time() >= max_time): break def start_server(self, event=None, server=None): |