summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolay Kim <fafhrd91@gmail.com>2017-06-09 21:46:14 (GMT)
committerYury Selivanov <yury@magic.io>2017-06-09 21:46:14 (GMT)
commita0e3d2dd09346b01e7d29a35ed31ed28041570b1 (patch)
tree91f9cddcfc5425c9f29c8575cd4d54e908c116ce
parentb4e5fee6f5bcc50500ea6261a22021db58955b55 (diff)
downloadcpython-a0e3d2dd09346b01e7d29a35ed31ed28041570b1.zip
cpython-a0e3d2dd09346b01e7d29a35ed31ed28041570b1.tar.gz
cpython-a0e3d2dd09346b01e7d29a35ed31ed28041570b1.tar.bz2
Closing transport during handshake process leaks socket (#480)
-rw-r--r--Lib/asyncio/sslproto.py7
-rw-r--r--Lib/test/test_asyncio/test_sslproto.py15
-rw-r--r--Misc/NEWS3
3 files changed, 23 insertions, 2 deletions
diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py
index 61d31a3..a7f1e61 100644
--- a/Lib/asyncio/sslproto.py
+++ b/Lib/asyncio/sslproto.py
@@ -546,8 +546,11 @@ class SSLProtocol(protocols.Protocol):
def _start_shutdown(self):
if self._in_shutdown:
return
- self._in_shutdown = True
- self._write_appdata(b'')
+ if self._in_handshake:
+ self._abort()
+ else:
+ self._in_shutdown = True
+ self._write_appdata(b'')
def _write_appdata(self, data):
self._write_backlog.append((data, 0))
diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py
index f1771c5..bcd236e 100644
--- a/Lib/test/test_asyncio/test_sslproto.py
+++ b/Lib/test/test_asyncio/test_sslproto.py
@@ -42,6 +42,7 @@ class SslProtoHandshakeTests(test_utils.TestCase):
sslpipe.do_handshake.side_effect = mock_handshake
with mock.patch('asyncio.sslproto._SSLPipe', return_value=sslpipe):
ssl_proto.connection_made(transport)
+ return transport
def test_cancel_handshake(self):
# Python issue #23197: cancelling a handshake must not raise an
@@ -95,6 +96,20 @@ class SslProtoHandshakeTests(test_utils.TestCase):
test_utils.run_briefly(self.loop)
self.assertIsInstance(waiter.exception(), ConnectionAbortedError)
+ def test_close_during_handshake(self):
+ # bpo-29743 Closing transport during handshake process leaks socket
+ waiter = asyncio.Future(loop=self.loop)
+ ssl_proto = self.ssl_protocol(waiter)
+
+ def do_handshake(callback):
+ return []
+
+ transport = self.connection_made(ssl_proto)
+ test_utils.run_briefly(self.loop)
+
+ ssl_proto._app_transport.close()
+ self.assertTrue(transport.abort.called)
+
def test_get_extra_info_on_closed_connection(self):
waiter = asyncio.Future(loop=self.loop)
ssl_proto = self.ssl_protocol(waiter)
diff --git a/Misc/NEWS b/Misc/NEWS
index c013639..1bc38b7 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -350,6 +350,9 @@ Extension Modules
Library
-------
+- bpo-29743: Closing transport during handshake process leaks open socket.
+ Patch by Nikolay Kim
+
- bpo-27585: Fix waiter cancellation in asyncio.Lock.
Patch by Mathieu Sornay.