diff options
author | Yury Selivanov <yury@magic.io> | 2018-06-29 01:59:32 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-29 01:59:32 (GMT) |
commit | d904c238ca3551750cb97d15d827c3e525970867 (patch) | |
tree | 8a937214dcd97d5f149d24915cda85d129d3d4a5 /Lib | |
parent | 41cb0baea96a80360971908a0bd79d9d40dd5e44 (diff) | |
download | cpython-d904c238ca3551750cb97d15d827c3e525970867.zip cpython-d904c238ca3551750cb97d15d827c3e525970867.tar.gz cpython-d904c238ca3551750cb97d15d827c3e525970867.tar.bz2 |
bpo-27500: Fix static version of getaddrinfo to resolve IPv6 (GH-7993)
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/asyncio/base_events.py | 14 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_base_events.py | 24 |
2 files changed, 32 insertions, 6 deletions
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 6b4756a..dc0ca3f 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -61,6 +61,8 @@ _MIN_CANCELLED_TIMER_HANDLES_FRACTION = 0.5 _FATAL_ERROR_IGNORE = (BrokenPipeError, ConnectionResetError, ConnectionAbortedError) +_HAS_IPv6 = hasattr(socket, 'AF_INET6') + def _format_handle(handle): cb = handle._callback @@ -123,7 +125,7 @@ def _ipaddr_info(host, port, family, type, proto): if family == socket.AF_UNSPEC: afs = [socket.AF_INET] - if hasattr(socket, 'AF_INET6'): + if _HAS_IPv6: afs.append(socket.AF_INET6) else: afs = [family] @@ -139,7 +141,10 @@ def _ipaddr_info(host, port, family, type, proto): try: socket.inet_pton(af, host) # The host has already been resolved. - return af, type, proto, '', (host, port) + if _HAS_IPv6 and af == socket.AF_INET6: + return af, type, proto, '', (host, port, 0, 0) + else: + return af, type, proto, '', (host, port) except OSError: pass @@ -1309,7 +1314,6 @@ class BaseEventLoop(events.AbstractEventLoop): raise ValueError( 'host/port and sock can not be specified at the same time') - AF_INET6 = getattr(socket, 'AF_INET6', 0) if reuse_address is None: reuse_address = os.name == 'posix' and sys.platform != 'cygwin' sockets = [] @@ -1349,7 +1353,9 @@ class BaseEventLoop(events.AbstractEventLoop): # Disable IPv4/IPv6 dual stack support (enabled by # default on Linux) which makes a single socket # listen on both address families. - if af == AF_INET6 and hasattr(socket, 'IPPROTO_IPV6'): + if (_HAS_IPv6 and + af == socket.AF_INET6 and + hasattr(socket, 'IPPROTO_IPV6')): sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, True) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index e333950..bda8cc6 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -97,11 +97,11 @@ class BaseEventTests(test_utils.TestCase): base_events._ipaddr_info('1.2.3.4', 1, INET6, STREAM, TCP)) self.assertEqual( - (INET6, STREAM, TCP, '', ('::3', 1)), + (INET6, STREAM, TCP, '', ('::3', 1, 0, 0)), base_events._ipaddr_info('::3', 1, INET6, STREAM, TCP)) self.assertEqual( - (INET6, STREAM, TCP, '', ('::3', 1)), + (INET6, STREAM, TCP, '', ('::3', 1, 0, 0)), base_events._ipaddr_info('::3', 1, UNSPEC, STREAM, TCP)) # IPv6 address with family IPv4. @@ -1077,6 +1077,26 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): srv.close() self.loop.run_until_complete(srv.wait_closed()) + @unittest.skipUnless(hasattr(socket, 'AF_INET6'), 'no IPv6 support') + def test_create_server_ipv6(self): + async def main(): + srv = await asyncio.start_server( + lambda: None, '::1', 0, loop=self.loop) + try: + self.assertGreater(len(srv.sockets), 0) + finally: + srv.close() + await srv.wait_closed() + + try: + self.loop.run_until_complete(main()) + except OSError as ex: + if (hasattr(errno, 'EADDRNOTAVAIL') and + ex.errno == errno.EADDRNOTAVAIL): + self.skipTest('failed to bind to ::1') + else: + raise + def test_create_datagram_endpoint_wrong_sock(self): sock = socket.socket(socket.AF_INET) with sock: |