8000 bpo-27500: Fix static version of getaddrinfo to resolve IPv6 (GH-7993) · python/cpython@3ed4414 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3ed4414

Browse files
miss-islington1st1
andauthored
bpo-27500: Fix static version of getaddrinfo to resolve IPv6 (GH-7993)
(cherry picked from commit d904c23) Co-authored-by: Yury Selivanov <yury@magic.io>
1 parent 9d92524 commit 3ed4414

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

Lib/asyncio/base_events.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
_FATAL_ERROR_IGNORE = (BrokenPipeError,
6262
ConnectionResetError, ConnectionAbortedError)
6363

64+
_HAS_IPv6 = hasattr(socket, 'AF_INET6')
65+
6466

6567
def _format_handle(handle):
6668
cb = handle._callback
@@ -123,7 +125,7 @@ def _ipaddr_info(host, port, family, type, proto):
123125

124126
if family == socket.AF_UNSPEC:
125127
afs = [socket.AF_INET]
126-
if hasattr(socket, 'AF_INET6'):
128+
if _HAS_IPv6:
127129
afs.append(socket.AF_INET6)
128130
else:
129131
afs = [family]
@@ -139,7 +141,10 @@ def _ipaddr_info(host, port, family, type, proto):
139141
try:
140142
socket.inet_pton(af, host)
141143
# The host has already been resolved.
142-
return af, type, proto, '', (host, port)
144+
if _HAS_IPv6 and af == socket.AF_INET6:
145+
return af, type, proto, '', (host, port, 0, 0)
146+
else:
147+
return af, type, proto, '', (host, port)
143148
except OSError:
144149
pass
145150

@@ -1309,7 +1314,6 @@ async def create_server(
13091314
raise ValueError(
13101315
'host/port and sock can not be specified at the same time')
13111316

1312-
AF_INET6 = getattr(socket, 'AF_INET6', 0)
13131317
if reuse_address is None:
13141318
reuse_address = os.name == 'posix' and sys.platform != 'cygwin'
13151319
sockets = []
@@ -1349,7 +1353,9 @@ async def create_server(
13491353
# Disable IPv4/IPv6 dual stack support (enabled by
13501354
# default on Linux) which makes a single socket
13511355
# listen on both address families.
1352-
if af == AF_INET6 and hasattr(socket, 'IPPROTO_IPV6'):
1356+
if (_HAS_IPv6 and
1357+
af == socket.AF_INET6 and
1358+
hasattr(socket, 'IPPROTO_IPV6')):
13531359
sock.setsockopt(socket.IPPROTO_IPV6,
13541360
socket.IPV6_V6ONLY,
13551361
True)

Lib/test/test_asyncio/test_base_events.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ def test_ipaddr_info(self):
9393
base_events._ipaddr_info('1.2.3.4', 1, INET6, STREAM, TCP))
9494

9595
self.assertEqual(
96-
(INET6, STREAM, TCP, '', ('::3', 1)),
96+
(INET6, STREAM, TCP, '', ('::3', 1, 0, 0)),
9797
base_events._ipaddr_info('::3', 1, INET6, STREAM, TCP))
9898

9999
self.assertEqual(
100-
(INET6, STREAM, TCP, '', ('::3', 1)),
100+
(INET6, STREAM, TCP, '', ('::3', 1, 0, 0)),
101101
base_events._ipaddr_info('::3', 1, UNSPEC, STREAM, TCP))
102102

103103
# IPv6 address with family IPv4.
@@ -1073,6 +1073,26 @@ def test_create_server_stream_bittype(self):
10731073
srv.close()
10741074
self.loop.run_until_complete(srv.wait_closed())
10751075

1076+
@unittest.skipUnless(hasattr(socket, 'AF_INET6'), 'no IPv6 support')
1077+
def test_create_server_ipv6(self):
1078+
async def main():
1079+
srv = await asyncio.start_server(
1080+
lambda: None, '::1', 0, loop=self.loop)
1081+
try:
1082+
self.assertGreater(len(srv.sockets), 0)
1083+
finally:
1084+
srv.close()
1085+
await srv.wait_closed()
1086+
1087+
try:
1088+
self.loop.run_until_complete(main())
1089+
except OSError as ex:
1090+
if (hasattr(errno, 'EADDRNOTAVAIL') and
1091+
ex.errno == errno.EADDRNOTAVAIL):
1092+
self.skipTest('failed to bind to ::1')
1093+
else:
1094+
raise
1095+
10761096
def test_create_datagram_endpoint_wrong_sock(self):
10771097
sock = socket.socket(socket.AF_INET)
10781098
with sock:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix getaddrinfo to resolve IPv6 addresses correctly.

0 commit comments

Comments
 (0)
0