Xpra: Ticket #2092: connecting to AAAA-only hosts no longer works

xpra 2.4.2 (currently in debian testing and sid) is no longer able to connect to hosts that only have an AAAA DNS record, it fails with

xpra initialization error:
 cannot get IPv4 address of ('foobar.example.com', 22): [Errno -5] No address associated with hostname

In previous versions (not sure which ones precisely) this used to work fine.

From a brief look at the code, it seem xpra will use IPv6 only when an IPv6 literal address is entered.



Wed, 02 Jan 2019 20:54:05 GMT - Antoine Martin: owner changed

@elenril: can you give me any DNS hostname I can use for testing? (it doesn't have to run an xpra server, just trying to make sure that I test with the correct settings)


Wed, 02 Jan 2019 21:05:22 GMT - elenril:

If you need just a hostname without login then e.g. sandro.khirnov.net should work. I could also give you temporary login there if you really need it.


Thu, 03 Jan 2019 09:22:33 GMT - Antoine Martin:

Are you connecting via ssh? AFAICT, this code has not changed for a very long time, what has changed is how we create ssh tunnels, which now uses the same socket code and paramiko (#1646) instead of running openssh in a subprocess.

This socket code has now been updated:

@elenril: does that work for you?

You should be able to test this new code from a python shell:

>>> def socket_connect(dtype, host, port, ipv6=None):
    print("socket_connect%s" % ((dtype, host, port, ipv6),))
    if ipv6 is True:
        assert socket.has_ipv6, "no IPv6 support"
        family = socket.AF_INET6
    elif ipv6 is False:
        family = socket.AF_INET
    else:
        family = 0  #any
    if dtype=="udp":
        socktype = socket.SOCK_DGRAM
    else:
        socktype = socket.SOCK_STREAM
    info = {
        "host" : host,
        "port" : port,
        }
    try:
        addrinfo = socket.getaddrinfo(host, port, family, socktype)
    except Exception as e:
        raise InitException("cannot get %s address of%s: %s" % ({
            socket.AF_INET6 : " IPv6",
            socket.AF_INET  : " IPv4",
            }.get(family, ""), (host, port), e))
    if ipv6 is None:
        prefer = {
            True    : socket.AF_INET6,
            False   : socket.AF_INET,
            }.get(PREFER_IPV6)
        matches = [x for x in addrinfo if x[0]==prefer]
        if matches:
            addrinfo = matches
    #default to the last one:
    sockaddr = addrinfo[0][-1]
    print("using: %s" % (sockaddr,))
>>> PREFER_IPV6 = False
>>> socket_connect("tcp", "google.com", 10000,  None)
socket_connect('tcp', 'google.com', 10000, None)
using: ('74.125.68.139', 10000)
>>> PREFER_IPV6 = True
>>> socket_connect("tcp", "google.com", 10000,  None)
socket_connect('tcp', 'google.com', 10000, None)
using: ('2404:6800:4003:c01::8b', 10000, 0, 0)
>>> PREFER_IPV6 = False
>>> socket_connect("tcp", "sandro.khirnov.net", 10000,  None)
socket_connect('tcp', 'sandro.khirnov.net', 10000, None)
using: ('2001:67c:1138:4308::3', 10000, 0, 0)

Thu, 03 Jan 2019 11:37:56 GMT - elenril:

Thanks a lot, it seems to work fine now. Do you think this deserves a commandline/configfile option -- like ssh and many other programs have -4/-6?


Thu, 03 Jan 2019 17:05:58 GMT - Antoine Martin: status changed; resolution set

Thanks a lot, it seems to work fine now.

Thanks, closing.

Do you think this deserves a commandline/configfile option -- like ssh and many other programs have -4/-6?

Not unless it can be proven that there are use cases that require the use of a such a switch. At present, AFAIK, things should just work.


Thu, 03 Jan 2019 17:40:33 GMT - Antoine Martin:

This change has caused a regression (#2098) and is likely to be reverted from the 2.4 branch.


Thu, 03 Jan 2019 17:46:15 GMT - elenril:

I certainly can think of a use case. E.g. in my home network, I have all the IPv6 addresses I might ever need, but only two public IPv4 addresses. I run a bunch of systems/containers that provide Internet-facing services. For v6 it's simple - every container has its own public v6 address and its DNS hostname resolves to that address. But since I don't have enough v4 addresses, I have to "overload" them, so that hostnames for several containers resolve to the same v4 address and the firewall takes care of things based on the port number. So when I use SSH (and by extension Xpra) I have to force v6. Of course that can be done by the environment variable you just introduced, but it seems to me that an option would make sense as well (at the very least it would be easier for users to find).


Thu, 03 Jan 2019 18:09:42 GMT - elenril:

Now that I looked at your changes more closely - why do you think xpra should even have an opinion on v4 vs. v6 preference? Documentation for getaddrinfo says

There are several reasons why the linked list may have more than one addrinfo structure, including: the network host is multihomed, accessible over multiple protocols (e.g., both AF_INET and AF_INET6); or the same service is available from multiple socket types (one SOCK_STREAM address and another SOCK_DGRAM address, for example). Normally, the application should try using the addresses in the order in which they are returned. The sorting function used within getaddrinfo() is defined in RFC 3484; the order can be tweaked for a particular system by editing /etc/gai.conf (available since glibc 2.5).

So I would expect xpra to just pick the first result (or perhaps try the results in the order in which they are returned), and so respect system-wide preferences for IPv4 vs IPv6.


Thu, 03 Jan 2019 18:12:10 GMT - Antoine Martin:

Regressions fixed: ticket:2098#comment:5.


Thu, 03 Jan 2019 18:57:32 GMT - Antoine Martin:

Normally, the application should try using the addresses in the order in which they are returned.

Thanks for pointing that out, this is implemented in r21283 and will be included in v2.5. (this is not suitable for backports to v2.4)


Thu, 03 Jan 2019 19:13:25 GMT - Antoine Martin:

why do you think xpra should even have an opinion on v4 vs. v6 preference? Documentation for getaddrinfo says...

You're right about that too, that code has been nuked in r21284.


Sat, 23 Jan 2021 05:42:00 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/2092