[3.12] gh-91227: Ignore ERROR_PORT_UNREACHABLE in proactor recvfrom() (GH-32011) (GH-117209)

(cherry picked from commit f11d0d8be8)

Co-authored-by: Erik Soma <stillusingirc@gmail.com>
This commit is contained in:
Miss Islington (bot) 2024-03-25 11:21:31 +01:00 committed by GitHub
parent 193a24bb80
commit bd2c60f8c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 174 additions and 12 deletions

View file

@ -8,6 +8,7 @@ if sys.platform != 'win32': # pragma: no cover
import _overlapped
import _winapi
import errno
from functools import partial
import math
import msvcrt
import socket
@ -466,6 +467,18 @@ class IocpProactor:
else:
raise
@classmethod
def _finish_recvfrom(cls, trans, key, ov, *, empty_result):
try:
return cls.finish_socket_func(trans, key, ov)
except OSError as exc:
# WSARecvFrom will report ERROR_PORT_UNREACHABLE when the same
# socket is used to send to an address that is not listening.
if exc.winerror == _overlapped.ERROR_PORT_UNREACHABLE:
return empty_result, None
else:
raise
def recv(self, conn, nbytes, flags=0):
self._register_with_iocp(conn)
ov = _overlapped.Overlapped(NULL)
@ -500,7 +513,8 @@ class IocpProactor:
except BrokenPipeError:
return self._result((b'', None))
return self._register(ov, conn, self.finish_socket_func)
return self._register(ov, conn, partial(self._finish_recvfrom,
empty_result=b''))
def recvfrom_into(self, conn, buf, flags=0):
self._register_with_iocp(conn)
@ -510,17 +524,8 @@ class IocpProactor:
except BrokenPipeError:
return self._result((0, None))
def finish_recv(trans, key, ov):
try:
return ov.getresult()
except OSError as exc:
if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED,
_overlapped.ERROR_OPERATION_ABORTED):
raise ConnectionResetError(*exc.args)
else:
raise
return self._register(ov, conn, finish_recv)
return self._register(ov, conn, partial(self._finish_recvfrom,
empty_result=0))
def sendto(self, conn, buf, flags=0, addr=None):
self._register_with_iocp(conn)