xpra icon
Bug tracker and wiki

Opened 11 months ago

Closed 11 months ago

Last modified 11 months ago

#2092 closed defect (fixed)

connecting to AAAA-only hosts no longer works

Reported by: elenril Owned by: elenril
Priority: major Milestone:
Component: client Version: 2.4.x
Keywords: ipv6 Cc:

Description

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.

Change History (11)

comment:1 Changed 11 months ago by Antoine Martin

Owner: changed from Antoine Martin to elenril

@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)

comment:2 Changed 11 months ago by 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.

comment:3 Changed 11 months ago by 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:

  • r21276 figure out which types of sockets are available (don't assume ipv4 only)
  • r21277 make it possible to prefer ipv6 over ipv4 (defaults to ipv4 if both are available)

@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)

comment:4 Changed 11 months ago by 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?

comment:5 Changed 11 months ago by Antoine Martin

Resolution: fixed
Status: newclosed

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.

comment:6 Changed 11 months ago by Antoine Martin

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

comment:7 Changed 11 months ago by 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).

comment:8 Changed 11 months ago by 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.

comment:9 Changed 11 months ago by Antoine Martin

Regressions fixed: ticket:2098#comment:5.

comment:10 Changed 11 months ago by 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)

comment:11 Changed 11 months ago by 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.

Note: See TracTickets for help on using tickets.