-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
bpo-29406: asyncio SSL contexts leak sockets after calling close with certain servers #409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,8 @@ | |
ssl = None | ||
|
||
from . import base_events | ||
from . import compat | ||
from . import futures | ||
from . import protocols | ||
from . import transports | ||
from .log import logger | ||
|
@@ -407,7 +409,7 @@ class SSLProtocol(protocols.Protocol): | |
|
||
def __init__(self, loop, app_protocol, sslcontext, waiter, | ||
server_side=False, server_hostname=None, | ||
call_connection_made=True): | ||
call_connection_made=True, shutdown_timeout=5.0): | ||
if ssl is None: | ||
raise RuntimeError('stdlib ssl module not available') | ||
|
||
|
@@ -438,6 +440,8 @@ def __init__(self, loop, app_protocol, sslcontext, waiter, | |
self._session_established = False | ||
self._in_handshake = False | ||
self._in_shutdown = False | ||
self._shutdown_timeout = shutdown_timeout | ||
self._shutdown_timeout_handle = None | ||
# transport, ex: SelectorSocketTransport | ||
self._transport = None | ||
self._call_connection_made = call_connection_made | ||
|
@@ -552,6 +556,15 @@ def _start_shutdown(self): | |
self._in_shutdown = True | ||
self._write_appdata(b'') | ||
|
||
if self._shutdown_timeout is not None: | ||
self._shutdown_timeout_handle = self._loop.call_later( | ||
self._shutdown_timeout, self._on_shutdown_timeout) | ||
|
||
def _on_shutdown_timeout(self): | ||
if self._transport is not None: | ||
self._fatal_error( | ||
futures.TimeoutError(), 'Can not complete shitdown operation') | ||
|
||
def _write_appdata(self, data): | ||
self._write_backlog.append((data, 0)) | ||
self._write_buffer_size += len(data) | ||
|
@@ -679,12 +692,22 @@ def _fatal_error(self, exc, message='Fatal error on transport'): | |
}) | ||
if self._transport: | ||
self._transport._force_close(exc) | ||
self._transport = None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we also cleanup There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that makes sense. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added cleanup code for |
||
|
||
if self._shutdown_timeout_handle is not None: | ||
self._shutdown_timeout_handle.cancel() | ||
self._shutdown_timeout_handle = None | ||
|
||
def _finalize(self): | ||
self._sslpipe = None | ||
|
||
if self._transport is not None: | ||
self._transport.close() | ||
self._transport = None | ||
|
||
if self._shutdown_timeout_handle is not None: | ||
self._shutdown_timeout_handle.cancel() | ||
self._shutdown_timeout_handle = None | ||
|
||
def _abort(self): | ||
try: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it 5 seconds? Is this some timeout value defined in some SSL RFC?