mirror of
https://github.com/python/cpython.git
synced 2025-08-27 12:16:04 +00:00
bpo-35545: Fix asyncio discarding IPv6 scopes (GH-11271)
This PR proposes a solution to [bpo-35545](https://bugs.python.org/issue35545) by adding an optional `flowinfo` and `scopeid` to `asyncio.base_events._ipaddr_info` to carry the full address information into `_ipaddr_info` and avoid discarding IPv6 specific information. Changelog entry & regression tests to come. https://bugs.python.org/issue35545
This commit is contained in:
parent
14514d9084
commit
ac8eb8f36b
3 changed files with 27 additions and 3 deletions
|
@ -102,7 +102,7 @@ def _set_reuseport(sock):
|
||||||
'SO_REUSEPORT defined but not implemented.')
|
'SO_REUSEPORT defined but not implemented.')
|
||||||
|
|
||||||
|
|
||||||
def _ipaddr_info(host, port, family, type, proto):
|
def _ipaddr_info(host, port, family, type, proto, flowinfo=0, scopeid=0):
|
||||||
# Try to skip getaddrinfo if "host" is already an IP. Users might have
|
# Try to skip getaddrinfo if "host" is already an IP. Users might have
|
||||||
# handled name resolution in their own code and pass in resolved IPs.
|
# handled name resolution in their own code and pass in resolved IPs.
|
||||||
if not hasattr(socket, 'inet_pton'):
|
if not hasattr(socket, 'inet_pton'):
|
||||||
|
@ -151,7 +151,7 @@ def _ipaddr_info(host, port, family, type, proto):
|
||||||
socket.inet_pton(af, host)
|
socket.inet_pton(af, host)
|
||||||
# The host has already been resolved.
|
# The host has already been resolved.
|
||||||
if _HAS_IPv6 and af == socket.AF_INET6:
|
if _HAS_IPv6 and af == socket.AF_INET6:
|
||||||
return af, type, proto, '', (host, port, 0, 0)
|
return af, type, proto, '', (host, port, flowinfo, scopeid)
|
||||||
else:
|
else:
|
||||||
return af, type, proto, '', (host, port)
|
return af, type, proto, '', (host, port)
|
||||||
except OSError:
|
except OSError:
|
||||||
|
@ -1348,7 +1348,7 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
family=0, type=socket.SOCK_STREAM,
|
family=0, type=socket.SOCK_STREAM,
|
||||||
proto=0, flags=0, loop):
|
proto=0, flags=0, loop):
|
||||||
host, port = address[:2]
|
host, port = address[:2]
|
||||||
info = _ipaddr_info(host, port, family, type, proto)
|
info = _ipaddr_info(host, port, family, type, proto, *address[2:])
|
||||||
if info is not None:
|
if info is not None:
|
||||||
# "host" is already a resolved IP.
|
# "host" is already a resolved IP.
|
||||||
return [info]
|
return [info]
|
||||||
|
|
|
@ -1299,6 +1299,28 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
|
||||||
t.close()
|
t.close()
|
||||||
test_utils.run_briefly(self.loop) # allow transport to close
|
test_utils.run_briefly(self.loop) # allow transport to close
|
||||||
|
|
||||||
|
@patch_socket
|
||||||
|
def test_create_connection_ipv6_scope(self, m_socket):
|
||||||
|
m_socket.getaddrinfo = socket.getaddrinfo
|
||||||
|
sock = m_socket.socket.return_value
|
||||||
|
sock.family = socket.AF_INET6
|
||||||
|
|
||||||
|
self.loop._add_reader = mock.Mock()
|
||||||
|
self.loop._add_reader._is_coroutine = False
|
||||||
|
self.loop._add_writer = mock.Mock()
|
||||||
|
self.loop._add_writer._is_coroutine = False
|
||||||
|
|
||||||
|
coro = self.loop.create_connection(asyncio.Protocol, 'fe80::1%1', 80)
|
||||||
|
t, p = self.loop.run_until_complete(coro)
|
||||||
|
try:
|
||||||
|
sock.connect.assert_called_with(('fe80::1', 80, 0, 1))
|
||||||
|
_, kwargs = m_socket.socket.call_args
|
||||||
|
self.assertEqual(kwargs['family'], m_socket.AF_INET6)
|
||||||
|
self.assertEqual(kwargs['type'], m_socket.SOCK_STREAM)
|
||||||
|
finally:
|
||||||
|
t.close()
|
||||||
|
test_utils.run_briefly(self.loop) # allow transport to close
|
||||||
|
|
||||||
@patch_socket
|
@patch_socket
|
||||||
def test_create_connection_ip_addr(self, m_socket):
|
def test_create_connection_ip_addr(self, m_socket):
|
||||||
self._test_create_connection_ip_addr(m_socket, True)
|
self._test_create_connection_ip_addr(m_socket, True)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix asyncio discarding IPv6 scopes when ensuring hostname resolutions
|
||||||
|
internally
|
Loading…
Add table
Add a link
Reference in a new issue