|
1 | 1 | import os |
2 | 2 | import signal |
3 | 3 | import socket |
| 4 | +import struct |
4 | 5 | import sys |
5 | 6 | import time |
6 | 7 | import threading |
|
19 | 20 | from asyncio import windows_utils |
20 | 21 | from test import support |
21 | 22 | from test.support import os_helper |
| 23 | +from test.support import socket_helper |
22 | 24 | from test.test_asyncio import utils as test_utils |
23 | 25 |
|
24 | 26 |
|
@@ -115,6 +117,38 @@ def test_close(self): |
115 | 117 | self.assertEqual(f.result(), b'') |
116 | 118 | b.close() |
117 | 119 |
|
| 120 | + def test_accept_connection_reset(self): |
| 121 | + # gh-93821: a connection reset while it waits in the listen queue |
| 122 | + # makes AcceptEx fail with ERROR_NETNAME_DELETED. The server must |
| 123 | + # keep accepting. |
| 124 | + async def handle(reader, writer): |
| 125 | + writer.close() |
| 126 | + |
| 127 | + async def main(): |
| 128 | + server = await asyncio.start_server(handle, socket_helper.HOSTv4, 0) |
| 129 | + port = server.sockets[0].getsockname()[1] |
| 130 | + # Both connects complete while the loop is blocked here: the |
| 131 | + # first is taken by the pending AcceptEx, the second waits in |
| 132 | + # the listen queue and is reset there. |
| 133 | + first = socket.create_connection((socket_helper.HOSTv4, port)) |
| 134 | + second = socket.create_connection((socket_helper.HOSTv4, port)) |
| 135 | + second.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, |
| 136 | + struct.pack('HH', 1, 0)) |
| 137 | + second.close() |
| 138 | + try: |
| 139 | + await asyncio.sleep(0.5) |
| 140 | + reader, writer = await asyncio.wait_for( |
| 141 | + asyncio.open_connection(socket_helper.HOSTv4, port), |
| 142 | + support.SHORT_TIMEOUT) |
| 143 | + writer.close() |
| 144 | + await writer.wait_closed() |
| 145 | + finally: |
| 146 | + first.close() |
| 147 | + server.close() |
| 148 | + await server.wait_closed() |
| 149 | + |
| 150 | + self.loop.run_until_complete(main()) |
| 151 | + |
118 | 152 | def test_double_bind(self): |
119 | 153 | ADDRESS = r'\\.\pipe\test_double_bind-%s' % os.getpid() |
120 | 154 | server1 = windows_events.PipeServer(ADDRESS) |
|
0 commit comments