Skip to content
Snippets Groups Projects
Commit 7c97063c00d0 authored by Jeff Forcier's avatar Jeff Forcier
Browse files

Merge branch '2.9' into 2.10

No related branches found
No related tags found
No related merge requests found
...@@ -350,6 +350,10 @@ ...@@ -350,6 +350,10 @@
# Break out of the loop on success # Break out of the loop on success
break break
except socket.error as e: except socket.error as e:
# As mentioned in socket docs it is better
# to close sockets explicitly
if sock:
sock.close()
# Raise anything that isn't a straight up connection error # Raise anything that isn't a straight up connection error
# (such as a resolution error) # (such as a resolution error)
if e.errno not in (ECONNREFUSED, EHOSTUNREACH): if e.errno not in (ECONNREFUSED, EHOSTUNREACH):
......
...@@ -2,6 +2,13 @@ ...@@ -2,6 +2,13 @@
Changelog Changelog
========= =========
- :bug:`1822` (via, and relating to, far too many other issues to mention here)
Update `~paramiko.client.SSHClient` so it explicitly closes its wrapped
socket object upon encountering socket errors at connection time. This should
help somewhat with certain classes of memory leaks, resource warnings, and/or
errors (though we hasten to remind everyone that Client and Transport have
their own ``.close()`` methods for use in non-error situations!). Patch
courtesy of ``@YoavCohen``.
- bug:`1637` (via :issue:`1599`) Raise `SSHException` explicitly when blank - bug:`1637` (via :issue:`1599`) Raise `SSHException` explicitly when blank
private key data is loaded, instead of the natural result of ``IndexError``. private key data is loaded, instead of the natural result of ``IndexError``.
This should help more bits of Paramiko or Paramiko-adjacent codebases to This should help more bits of Paramiko or Paramiko-adjacent codebases to
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
import weakref import weakref
from tempfile import mkstemp from tempfile import mkstemp
import pytest
from pytest_relaxed import raises from pytest_relaxed import raises
from mock import patch, Mock from mock import patch, Mock
...@@ -462,6 +463,23 @@ ...@@ -462,6 +463,23 @@
assert p() is None assert p() is None
@patch("paramiko.client.socket.socket")
@patch("paramiko.client.socket.getaddrinfo")
def test_closes_socket_on_socket_errors(self, getaddrinfo, mocket):
getaddrinfo.return_value = (
("irrelevant", None, None, None, "whatever"),
)
class SocksToBeYou(socket.error):
pass
my_socket = mocket.return_value
my_socket.connect.side_effect = SocksToBeYou
client = SSHClient()
with pytest.raises(SocksToBeYou):
client.connect(hostname="nope")
my_socket.close.assert_called_once_with()
def test_client_can_be_used_as_context_manager(self): def test_client_can_be_used_as_context_manager(self):
""" """
verify that an SSHClient can be used a context manager verify that an SSHClient can be used a context manager
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment