[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: inability to resolve localhost to 127.0.0.1 in IPv6-only environments



On Fri, 01 Dec 2023 at 09:24:00 +0100, Vincent Bernat wrote:
> This does not prevent to have 127.0.0.1. I don't think this is a good use of
> time to fix builds broken because there is no IPv4 loopback. This is the
> same kind of artificial conditions as the 1-core builders.

Unfortunately, no, it's a bit more complicated than that.

I agree that we should consider a working 127.0.0.1 to be "part of the
API" that packages (and in particular their test-suites) can assume,
even if there is no other IPv4 connectivity.

However, the situation for some Debian buildds is that there *is* a
working 127.0.0.1, but resolving localhost with the AI_ADDRCONFIG option
(which is the default under some circumstances, and widely regarded as a
good idea to enable) will only return ::1, excluding 127.0.0.1 even though
actually it works fine.

This is unexpected, but it's actually AI_ADDRCONFIG behaving as documented:

    If hints.ai_flags includes the AI_ADDRCONFIG flag, then IPv4 addresses
    are returned in the list pointed to by res only if the local system
    has at least one IPv4 address configured, and IPv6 addresses are
    returned only if the local system has at least one IPv6 address
    configured. The loopback address is not considered for this case as
    valid as a configured address.
    — getaddrinfo(3)

and no exception to this rule is made for names like "localhost" that we
expect to be able to resolve statically via /etc/hosts, libnss-myhostname
or systemd-resolved without creating DNS traffic.

For "real" addresses, the AI_ADDRCONFIG behaviour is desirable: when you
resolve (say) "www.debian.org", it stops your application from wasting
time on resolving and trying to contact 130.89.148.77 if it only has IPv6
connectivity, or resolving and trying to contact 2001:67c:2564:a119::77
if it only has IPv4 connectivity, either of which would be a performance
penalty. However, AI_ADDRCONFIG doesn't seem to be useful for "localhost"
specifically: we probably want "localhost" to resolve to both 127.0.0.1
and ::1, even if there is no external connectivity on the matching
protocol.

One solution to this is for libraries and applications that resolve
names to have a special exception for "localhost", and possibly also
"*.localdomain" and other reserved names: hard-coding those names to
resolve to 127.0.0.1 and/or ::1 without ever calling getaddrinfo(). This
approach was suggested in RFC draft
https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-let-localhost-be-localhost-02
(which unfortunately never made it to RFC status, I don't know why not),
and is implemented in several web browsers and in GLib's GResolver
(https://gitlab.gnome.org/GNOME/glib/-/blob/2.78.1/gio/gresolver.c?ref_type=tags#L485).
However, this requires code changes in any library or application that
calls getaddrinfo() directly, which is a boil-the-ocean sort of effort,
because many software authors consider minimal dependencies to be a virtue
and strongly prefer not to rely on a higher-level library like GLib that
is in a position to solve this somewhat centrally for them.

Another solution to this is for libraries and applications that resolve
names to have a more narrowly-scoped exception for "localhost" and similar
names: special-case those names to specify hints that do not include
AI_ADDRCONFIG. This is what older versions of Mozilla (NSPR/Firefox) used
to do, before switching to hard-coding the result of resolving localhost:
https://hg.mozilla.org/releases/mozilla-1.9.2/rev/c5d74bcd7421
Again, this requires code changes in anything that calls getaddrinfo()
directly.

Doing name resolution with AF_UNSPEC happens to be a workaround for
this, but only because of https://bugs.debian.org/854301, which is at
least arguably a bug in its own right; so we should probably not rely
on that one.

Or, glibc itself could change its behaviour (but I have not seen any
response from glibc maintainers to bug reports about this in the past,
so that doesn't seem particularly likely to happen soon). I believe
some Fedora developers were trying to make this happen in the past,
but that seems to have stalled.

See https://bugs.debian.org/952740 for a previous writeup of this, with
links to numerous related issues.

    smcv


Reply to: