Skip to content
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

create_connection failed when connecting to a scoped ipv6 address #1634

Closed
j178 opened this issue Jun 1, 2020 · 3 comments · Fixed by #1635
Closed

create_connection failed when connecting to a scoped ipv6 address #1634

j178 opened this issue Jun 1, 2020 · 3 comments · Fixed by #1635
Assignees
Labels
PyVer: python2 PyVer: python3 Type: Docs Type: Enhancement

Comments

@j178
Copy link

j178 commented Jun 1, 2020

  • gevent version: 20.04.0
  • Python version: cPython 3.7.4 downloaded from python.org
  • Operating System: Ubuntu 16.04.3 LTS

Description:

I was trying to create an IPv6 connection to a scoped IPv6 address, but I got an Invalid argument error:

Traceback (most recent call last):
  File "/project/hotspot_scanner/tests/t.py", line 42, in <module>
    sock = gevent.socket.create_connection(('fe80::fcfc:feff:feb2:32bc%eth0', 7001))
  File "/usr/lib/python3.7/site-packages/gevent/socket.py", line 96, in create_connection
    sock.connect(sa)
  File "/usr/lib/python3.7/site-packages/gevent/_socket3.py", line 421, in connect
    raise error(result, strerror(result))
OSError: [Errno 22] Invalid argument

What I've run:

import gevent.socket

sock = gevent.socket.create_connection(('fe80::fcfc:feff:feb2:32bc%eth0', 7001))
print(sock)

The problem is that create_connection did a getaddrinfo, and then when sock.connect(),
there is another getaddrinfo in _socketcommon._resolve_addr(self._sock, address),
the second getaddrinfo lost the IPv6 scope id, then Invalid argument error occurred.

@jamadden
Copy link
Member

jamadden commented Jun 1, 2020

The scope identifier is dropped, that's true and I think has been for some time (though it's not documented IIRC). I can reproduce that on a multi-homed host on macOS with Python 3.x and 2.7. (Here, en7 and en10 are two interfaces with two different local IPs. When the scope ID works, the created sockets have different local IPs. When it doesn't, they have the same local IP.)

>>> import socket
>>> import gevent.socket as gsocket
# Try to connect to google.com
>>> s7  = socket.create_connection(('2607:f8b0:4000:80e::200e%en7', 80))
>>> s10 = socket.create_connection(('2607:f8b0:4000:80e::200e%en10', 80))
>>> s7.getsockname(), s10.getsockname() # Different local IPs :)
(('...:7441', 61130, 0, 0),
 ('...:297c', 61131, 0, 0))
>>> gs7  = gsocket.create_connection(('2607:f8b0:4000:80e::200e%en7', 80))
>>> gs10 = gsocket.create_connection(('2607:f8b0:4000:80e::200e%en10', 80))
>>> gs7.getsockname(), gs10.getsockname() # Same local IP :(
(('...:297c', 61153, 0, 0),
 ('...:297c', 61154, 0, 0))

(Writing tests for it that run in all environments might be tricky without mocking some things…)

I couldn't figure out where an Invalid argument would come from, though…until I actually looked more closely at the IP address you're using. D'oh, it's link-local. On my system, that results in Errno 65 No route to host.

Note that some resolvers (c-ares for sure) don't support scope IDs at all.

@jamadden jamadden added PyVer: python2 PyVer: python3 Type: Docs Type: Enhancement labels Jun 1, 2020
@jamadden jamadden self-assigned this Jun 1, 2020
@j178
Copy link
Author

j178 commented Jun 2, 2020

Thanks for your response!
yes, it's a link-local, that's why the scope identifier is required. You can connect to google.com through its global unicast address with or without a scope identifier, maybe you should try to connect to a local network sevice through its link-local address.

@j178
Copy link
Author

j178 commented Jun 2, 2020

oh, I saw the reference commit, that's pretty nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PyVer: python2 PyVer: python3 Type: Docs Type: Enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants