-
-
Notifications
You must be signed in to change notification settings - Fork 32k
loop.create_server does not detect if the interface is IPv6 enabled #75128
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
Comments
The IPv6 detection in asyncio.base_events.create_server only detect if IPv6 is available instead of checking if the interface can actually support it. I noticed that by using Python in a Docker container (example code to reproduce in attachment): docker run -it --rm -v /tmp/test_ipv6.py:/src/test_ipv6.py python:3.6 python /src/test_ipv6.py Will result in: Traceback (most recent call last):
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 1043, in create_server
sock.bind(sa)
OSError: [Errno 99] Cannot assign requested address
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/src/test_ipv6.py", line 11, in <module>
server = loop.run_until_complete(server_creation)
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 466, in run_until_complete
return future.result()
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 1047, in create_server
% (sa, err.strerror.lower()))
OSError: [Errno 99] error while attempting to bind on address ('::1', 27015, 0, 0): cannot assign requested address By default Docker containers have only IPv4 enabled: 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 I believe this detection mechanism should rely on the interface requested. I found this on the web for Python 2 that manage to get the info per interface: https://pastebin.com/VEnhF1Ht but it's using an external library. However if you change the hostname to 127.0.0.1 it works normally. |
Better than trying to detect IPv6 compatibility beforehand would probably to recognize the error and simply ignore it. Note: errno 99 is EADDRNOTAVAIL. Something like this could work (untested): diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 33b8f48..413161a 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -1038,6 +1038,11 @@ class BaseEventLoop(events.AbstractEventLoop):
try:
sock.bind(sa)
except OSError as err:
+ if err.errno == errno.EADDRNOTAVAIL:
+ # See bpo-30945
+ sockets.pop()
+ sock.close()
+ continue
raise OSError(err.errno, 'error while attempting '
'to bind on address %r: %s'
% (sa, err.strerror.lower())) from None |
+1 |
Cécile, could you try the following patch? I have no easy way to test here. |
Sure! It seems to work, the process returns an exit code of 0 and I see no traceback but the message is still displayed in the terminal. (Also I did something weird because your patch applies on branch master and I ran it with Python 3.6... I suppose it shouldn't be a problem) [0] [11:54:13] /tmp > d run -it --rm -v /tmp:/tmp:ro -v ~/repos/cpython/Lib/asyncio:/usr/local/lib/python3.6/asyncio:ro python:3.6 python /tmp/test_ipv6.py
error while attempting to bind on address ('::1', 27015, 0, 0): cannot assign requested address
[0] [11:54:19] /tmp > d run -it --rm -v /tmp:/tmp:ro python:3.6 python /tmp/test_ipv6.py
Traceback (most recent call last):
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 1043, in create_server
sock.bind(sa)
OSError: [Errno 99] Cannot assign requested address
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/tmp/test_ipv6.py", line 11, in <module>
server = loop.run_until_complete(server_creation)
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 466, in run_until_complete
return future.result()
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 1047, in create_server
% (sa, err.strerror.lower()))
OSError: [Errno 99] error while attempting to bind on address ('::1', 27015, 0, 0): cannot assign requested address
[1] [11:54:52] /tmp > |
Cécile, thank you. The reason the message is still displayed is that I turned the error into a warning (in other words, it is expected). |
Seeing this as well when running the cpython test suite in docker:
I'm going to try and write a patch to skip these tests (there's already a helper) |
Actually, my issue seems to be something more strange. The host being passed in is
asyncio is picking ipv6 because of this code: cpython/Lib/asyncio/base_events.py Lines 1334 to 1340 in a445feb
despite my host not actually having an ipv6 network hooked up. |
Applying this patch makes the tests pass for me, but I don't think the patch is appropriate (just hides the bug):
|
I see that the patch hasn't been applied to master on GitHub. Is there anything else expected from me on this ticket? |
Does anybody wants to make a PR to fix this? |
Which should be fine; create_server enumerates all addresses and tries to connect to each one. IPV6_V6ONLY is only applied to one socket for one IPv6 address. I think Antoine's patch is OK. |
…reate_server() Co-authored-by: Antoine Pitrou <[email protected]>
…server() (GH-114420) Co-authored-by: Antoine Pitrou <[email protected]>
…reate_server() (pythonGH-114420) (cherry picked from commit a53e56e) Co-authored-by: Serhiy Storchaka <[email protected]> Co-authored-by: Antoine Pitrou <[email protected]>
…reate_server() (pythonGH-114420) (cherry picked from commit a53e56e) Co-authored-by: Serhiy Storchaka <[email protected]> Co-authored-by: Antoine Pitrou <[email protected]>
Thank you for your patch Antoine. I am surprised that it was not merged at its time. It fixes a constant failure on some buildbots. Buildbot failure could perhaps be fixed by changing the configuration (I think that I encountered such errors on different buildbots in the past), but it is better to fix it in the core. |
…create_server() (GH-114420) (GH-114441) (cherry picked from commit a53e56e) Co-authored-by: Serhiy Storchaka <[email protected]> Co-authored-by: Antoine Pitrou <[email protected]>
…create_server() (GH-114420) (GH-114442) (cherry picked from commit a53e56e) Co-authored-by: Serhiy Storchaka <[email protected]> Co-authored-by: Antoine Pitrou <[email protected]>
…reate_server() (pythonGH-114420) Co-authored-by: Antoine Pitrou <[email protected]>
…reate_server() (pythonGH-114420) Co-authored-by: Antoine Pitrou <[email protected]>
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:
bugs.python.org fields:
Linked PRs
The text was updated successfully, but these errors were encountered: