You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
asyncio proactor udp transport stops responding after send to port that isn't listening #91227
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2022-03-20.14:58:17.671>labels= ['3.10', 'OS-windows', 'expert-asyncio']
title="asyncio proactor udp transport stops responding after send to port that isn't listening"updated_at=<Date2022-03-20.15:48:54.679>user='https://github.com/esoma'
Reproducer attached. Change USE_PROACTOR to False to use the SelectorEventLoop instead, which doesn't exhibit this behavior.
The output on my machine when using the proactor loop is:
datagram received b'ping 1'
datagram received b'ping 2'
And the selector loop (which is the behavior I would expect):
datagram received b'ping 1'
datagram received b'ping 2'
datagram received b'ping 3'
At a high level, after sending data to an address that isn't listening the asyncio protocol will no longer receive messages.
Digging deeper, _ProactorDatagramTransport._loop_reading encounters the windows error 1234 (ERROR_PORT_UNREACHABLE) after the "bad send". It appears this a (undocumented/buggy?) behavior of WSARecvFrom where the next call to it after an unreachable WSASendTo in UDP mode will return the ICMP unreachable message. The actual error is returned from GetOverlappedResult.
I've hacked together a fix that retries IocpProactor.recvfrom if the result is ERROR_PORT_UNREACHABLE. It fixes the issue for the reproducer and my actual use case, but it's probably not ideal. My solution for the moment is just to use the SelectorEventLoop instead.
Activity
esoma commentedon Mar 20, 2022
Reproducer attached. Change
USE_PROACTORtoFalseto use theSelectorEventLoopinstead, which doesn't exhibit this behavior.The output on my machine when using the proactor loop is:
And the selector loop (which is the behavior I would expect):
At a high level, after sending data to an address that isn't listening the asyncio protocol will no longer receive messages.
Digging deeper,
_ProactorDatagramTransport._loop_readingencounters the windows error 1234 (ERROR_PORT_UNREACHABLE) after the "bad send". It appears this a (undocumented/buggy?) behavior ofWSARecvFromwhere the next call to it after an unreachableWSASendToin UDP mode will return the ICMP unreachable message. The actual error is returned fromGetOverlappedResult.I've hacked together a fix that retries
IocpProactor.recvfromif the result is ERROR_PORT_UNREACHABLE. It fixes the issue for the reproducer and my actual use case, but it's probably not ideal. My solution for the moment is just to use the SelectorEventLoop instead.esoma commentedon Mar 20, 2022
Uploading my hack to
asyncio.windows_events.py-- this is based off 3.10.2's distribution.asvetlov commentedon Mar 20, 2022
Thanks for the report.
Could you make a pull request?
The whole attached windows_events.py is hard to analyze.
esoma commentedon Mar 20, 2022
Certainly: #32011
msoxzw commentedon Jul 26, 2022
As far as I know, there are several alternative solutions from open source projects:
The Go programming language - https://github.com/golang/go/blob/ceefd3a37bb2a77b1e9a76fc74360c68ef16ddb8/src/internal/poll/fd_windows.go#L341-L352
The libuv - https://github.com/libuv/libuv/blob/6c692ad1cbcc5083ec90954a4b091b660aedfc10/src/win/udp.c#L462-L486
esoma commentedon Jul 26, 2022
Looks like the libuv solution is similar to my PR -- just trying again.
The go solution is much simpler though. I'll try that out.
12 remaining items
jaycelq commentedon Aug 24, 2023
Any update on this issue?
gh-91227: Ignore ERROR_PORT_UNREACHABLE in proactor recvfrom() (#32011)
pythongh-91227: Ignore ERROR_PORT_UNREACHABLE in proactor recvfrom() (p…
[3.11] pythongh-91227: Ignore ERROR_PORT_UNREACHABLE in proactor recv…
[3.12] gh-91227: Ignore ERROR_PORT_UNREACHABLE in proactor recvfrom() (…
[3.11] gh-91227: Ignore ERROR_PORT_UNREACHABLE in proactor recvfrom() (…
pythongh-91227: Ignore ERROR_PORT_UNREACHABLE in proactor recvfrom() (p…
Squashed commit of the following:
Squashed commit of the following:
pythongh-91227: Ignore ERROR_PORT_UNREACHABLE in proactor recvfrom() (p…
New Game: Zillion (ArchipelagoMW#1081)
Zillion: map tracker in client (ArchipelagoMW#1136)
pythongh-127057: Re-arm proactor datagram read loop after a recoverab…