Comment 3 for bug 2020142

Revision history for this message
Simon Déziel (sdeziel) wrote :

The problem is when "::" is attempted to be resolved as an IPv4 it seems:

# cat << "EOF" > snippet.py
import socket
from socket import (
    AF_INET,
    AF_INET6,
    EAI_NODATA,
    EAI_NONAME,
    gaierror,
    getaddrinfo,
    IPPROTO_TCP,
)

def resolve_host_to_addrinfo(
    hostname, ip_version=4, port=0, proto=IPPROTO_TCP
):
    """Wrapper around `getaddrinfo`: return address information for `hostname`.

    :param hostname: Host name (or IP address).
    :param ip_version: Look for addresses of this IP version only: 4 for IPv4,
        6 for IPv6, or 0 for both. (Default: 4)
    :param port: port number, if any specified. (Default: 0)
    :return: a list of 5-tuples (family, type, proto, canonname, sockaddr)
        suitable for creating sockets and connecting. If `hostname` does not
        resolve (for that `ip_version`), then the list is empty.
    """
    addr_families = {4: AF_INET, 6: AF_INET6, 0: 0}
    assert ip_version in addr_families
    try:
        address_info = getaddrinfo(
            hostname, port, family=addr_families[ip_version], proto=proto
        )
    except gaierror as e:
        if e.errno in (EAI_NONAME, EAI_NODATA):
            # Name does not resolve.
            address_info = []
        else:
            raise
    return address_info

print(resolve_host_to_addrinfo("0.0.0.0", 4))
print(resolve_host_to_addrinfo("0.0.0.0", 0))
print(resolve_host_to_addrinfo("0.0.0.0"))
print(resolve_host_to_addrinfo("::", 6))
print(resolve_host_to_addrinfo("::", 0))
print(resolve_host_to_addrinfo("::")) # fails
EOF

# python3 snippet.py
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('0.0.0.0', 0))]
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('0.0.0.0', 0))]
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('0.0.0.0', 0))]
[(<AddressFamily.AF_INET6: 10>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('::', 0, 0, 0))]
[(<AddressFamily.AF_INET6: 10>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('::', 0, 0, 0))]
Traceback (most recent call last):
  File "/root/snippet.py", line 44, in <module>
    print(resolve_host_to_addrinfo("::")) # fails
  File "/root/snippet.py", line 28, in resolve_host_to_addrinfo
    address_info = getaddrinfo(
  File "/usr/lib/python3.10/socket.py", line 955, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -9] Address family for hostname not supported