diff --git a/src/aioquic/asyncio/client.py b/src/aioquic/asyncio/client.py index a8e41702b..211ae36c9 100644 --- a/src/aioquic/asyncio/client.py +++ b/src/aioquic/asyncio/client.py @@ -47,13 +47,6 @@ async def connect( * ``local_port`` is the UDP port number that this client wants to bind. """ loop = asyncio.get_event_loop() - local_host = "::" - - # lookup remote address - infos = await loop.getaddrinfo(host, port, type=socket.SOCK_DGRAM) - addr = infos[0][4] - if len(addr) == 2: - addr = ("::ffff:" + addr[0], addr[1], 0, 0) # prepare QUIC connection if configuration is None: @@ -66,16 +59,28 @@ async def connect( token_handler=token_handler, ) - # explicitly enable IPv4/IPv6 dual stack - sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) + # lookup remote address + infos = await loop.getaddrinfo(host, port, type=socket.SOCK_DGRAM, flags=socket.AI_ADDRCONFIG) + + addr = infos[0][4] + # addr is 2-tuple for AF_INET and 4-tuple for AF_INET6 + if len(addr) == 2: + local_tuple = ("0.0.0.0", local_port) + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + elif len(addr) == 4: + local_tuple = ("::", local_port, 0, 0) + sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) + else: + raise Exception("Unsupported response from getaddrinfo") + completed = False try: - sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) - sock.bind((local_host, local_port, 0, 0)) + sock.bind(local_tuple) completed = True finally: if not completed: sock.close() + # connect transport, protocol = await loop.create_datagram_endpoint( lambda: create_protocol(connection, stream_handler=stream_handler),