Skip to content

Commit

Permalink
🔗 Fix connecting to link-local IPv6 addresses (#4556)
Browse files Browse the repository at this point in the history
  • Loading branch information
socketpair committed Oct 16, 2020
1 parent 2940484 commit 86107ed
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGES/4554.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix connecting to link-local IPv6 addresses.
35 changes: 25 additions & 10 deletions aiohttp/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,23 @@ async def resolve(self, host: str, port: int=0,

hosts = []
for family, _, proto, _, address in infos:
hosts.append(
{'hostname': host,
'host': address[0], 'port': address[1],
'family': family, 'proto': proto,
'flags': socket.AI_NUMERICHOST})
if family == socket.AF_INET6 and address[3]: # type: ignore
# This is essential for link-local IPv6 addresses.
# LL IPv6 is a VERY rare case. Strictly speaking, we should use
# getnameinfo() unconditionally, but performance makes sense.
host, _port = socket.getnameinfo(
address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV)
port = int(_port)
else:
host, port = address[:2]
hosts.append({
'hostname': host,
'host': host,
'port': port,
'family': family,
'proto': proto,
'flags': socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,
})

return hosts

Expand All @@ -62,11 +74,14 @@ async def resolve(self, host: str, port: int=0,
raise OSError(msg) from exc
hosts = []
for address in resp.addresses:
hosts.append(
{'hostname': host,
'host': address, 'port': port,
'family': family, 'proto': 0,
'flags': socket.AI_NUMERICHOST})
hosts.append({
'hostname': host,
'host': address,
'port': port,
'family': family,
'proto': 0,
'flags': socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,
})

if not hosts:
raise OSError("DNS lookup failed")
Expand Down
4 changes: 2 additions & 2 deletions tests/test_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,10 +652,10 @@ async def test_tcp_connector_resolve_host(loop) -> None:
for rec in res:
if rec['family'] == socket.AF_INET:
assert rec['host'] == '127.0.0.1'
assert rec['hostname'] == 'localhost'
assert rec['hostname'] == '127.0.0.1'
assert rec['port'] == 8080
elif rec['family'] == socket.AF_INET6:
assert rec['hostname'] == 'localhost'
assert rec['hostname'] == '::1'
assert rec['port'] == 8080
if platform.system() == 'Darwin':
assert rec['host'] in ('::1', 'fe80::1', 'fe80::1%lo0')
Expand Down

0 comments on commit 86107ed

Please sign in to comment.