Python's documentation has a bug[1], in that it doesn't correctly annotate
is_alive as being a function introduced in Python 2.6.
[1] http://bugs.python.org/issue15126
Signed-off-by: Steven Noonan <snoonan@amazon.com>
Make sure the Thread.run() method has terminated before closing the
socket. Currently, the socket is closed through Packetizer.close(),
which happens too early. Move the socket.close() into Transport.close()
and after the Thread.join() call.
While at it, modify the stop_thread() method and use it in
Transport.close() to avoid code duplication. Use join() with a timeout
to make it possible to terminate the main thread with KeyboardInterrupt.
Also, remove the now obsolete socket.close() from Transport.atfork().
This fixes a potential infinite loop if paramiko.SSHClient is connected
through a paramiko.Channel instead of a regular socket (tunneling).
Details:
Using a debug patch to dump the current stack of the thread every
couple of seconds while trying to close it, I've seen the following
over and over again:
Thread could not be stopped, still running.
Current traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 524, in __bootstrap
self.__bootstrap_inner()
File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
self.run()
File ".../paramiko/transport.py", line 1564, in run
self._channel_handler_table[ptype](chan, m)
File ".../paramiko/channel.py", line 1102, in _handle_close
self.transport._send_user_message(m)
File ".../paramiko/transport.py", line 1418, in _send_user_message
self._send_message(data)
File ".../paramiko/transport.py", line 1398, in _send_message
self.packetizer.send_message(data)
File ".../paramiko/packet.py", line 319, in send_message
self.write_all(out)
File ".../paramiko/packet.py", line 248, in write_all
n = self.__socket.send(out)
File ".../paramiko/channel.py", line 732, in send
self.lock.release()
The thread was running Packetizer.write_all() in an endless loop:
while len(out) > 0:
...
n = Channel.send(out) # n == 0 because channel got closed
...
out = out[n:] # essentially out = out
Signed-off-by: Frank Arnold <farnold@amazon.com>
More sophisticated key negotiation is still necessary in the case
where we have an ECDSA key for the server and it offers us both RSA
and ECDSA. In this case, we will pick RSA and fail because we don't
have it. Instead, we should pick ECDSA. Still, this works if you tell
your server to only offer ECDSA keys :)
Bulk check the ACKs from the server every 32MB
(or every write request). This way you gain speed
but also making sure not to get the error too late
in a large transfer.
This works for smaller files too, since there is a
cleanup routine being called when the file has been transfered.
resize_pty(), and Client.invoke_shell(). Perhaps useless, but more RFC
compliant. Updated methods to include these parameters in server messages.
Adjusted Channel.resize_pty() to neither request nor wait for a response, as
per RFC 4254 6.7 (A response SHOULD NOT be sent to this message.) This is
necessary as certain hosts have been observed to not acknowledge this type of
channel request (Cisco IOS XR), which causes paramiko to end the session.