Repository navigation
asyncio SSL transport ignores ssl_shutdown_timeout after the peer sends EOF #160520
Copy link
Copy link
Closed
Closed
Copy link
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-SSLtopic-asynciotype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
ssl_shutdown_timeout stops applying to an asyncio SSL transport once the peer has sent EOF. SSLProtocol._on_shutdown_complete() cancels the shutdown timer (or never starts one if the EOF arrived before close()) and then calls the non-aborting close() of the underlying transport, which waits for its write buffer to drain. If the peer does not read, close() / wait_closed() never finish, while the same peer without the half-close is aborted after the timeout.
import asyncio, socket, ssl
from test.support import findfile
CERT = findfile('keycert.pem', subdir='certdata')
async def handler(reader, writer):
await reader.readline()
writer.write(bytes(16 << 20))
writer.close()
try:
await asyncio.wait_for(writer.wait_closed(), 5)
except TimeoutError as e:
print('server:', repr(e) if e.args else 'still open after 5 s')
writer.transport.abort()
def client(port, half_close):
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
s = ctx.wrap_socket(socket.create_connection(('127.0.0.1', port)))
s.sendall(b'x\n')
if half_close:
s.shutdown(socket.SHUT_WR)
return s # never read
async def main():
sctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
sctx.load_cert_chain(CERT)
server = await asyncio.start_server(
handler, '127.0.0.1', 0, ssl=sctx, ssl_shutdown_timeout=1)
port = server.sockets[0].getsockname()[1]
for half_close in (False, True):
print('peer half-closes:', half_close)
s = await asyncio.to_thread(client, port, half_close)
await asyncio.sleep(6)
s.close()
server.close()
await server.wait_closed()
asyncio.run(main())Output:
peer half-closes: False
server: TimeoutError('SSL shutdown timed out')
peer half-closes: True
server: still open after 5 s
Expected: both connections are aborted with TimeoutError('SSL shutdown timed out') after 1 second. The code is the same on 3.14 and 3.15.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-SSLtopic-asynciotype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Projects
- StatusShow more project fieldsDone
Activity
pythongh-160520: Apply asyncio ssl_shutdown_timeout after peer EOF
gh-160520: Apply asyncio ssl_shutdown_timeout after peer EOF (GH-160521)
[3.14] gh-160520: Apply asyncio ssl_shutdown_timeout after peer EOF (G…
[3.15] gh-160520: Apply asyncio ssl_shutdown_timeout after peer EOF (G…