[PATCH v5 1/2] resolv: implement ipv4+ipv6 flags in resolv.conf (bug 30544)

Petr Menšík pemensik@redhat.com
Mon Oct 20 10:02:51 GMT 2025


On 17/10/2025 14:07, Florian Weimer wrote:
> * Petr Menšík:
>
>> Do you know any nss module, which is using _res.options parsed by
>> glibc and would use information provided in /etc/resolv.conf?
> Historically, it used in some cases to change behavior when
> RES_USE_INET6 was set.  Here's an example from code that's clearly
> outside glibc (unlike say nss-altfiles, which was originally copied from
> glibc sources):
>
> <https://arthurdejong.org/git/nss-pam-ldapd/tree/nslcd/host.c?id=432cb4f71939e9675f9e29a610124a2cd687352b#n210>
>
> This also shows why the _res.options interface is problematic: as far as
> I can tell, this is on the daemon side (the d part) of the codebase.
> This means that application-specific resolver settings via RES_OPTIONS
> (or direct _res.options changes) do not influence the resolution
> behavior.
That code does not try to use getaddrinfo. It is trying to use mapped 
addresses in IPv6 format. That is completely different use case. It 
would be equivalent to AI_V4MAPPED flag. I don't want to change that. It 
does not seem to have support for AF_UNSPEC, it should not be affected.
>
>> Many programs parse /etc/resolv.conf themselves and do not use any
>> glibc interface for it, just fopen (). That is true to bind utilities
>> like dig or host. For unbound-host tool as well, drill from ldns. In
>> general, anything using DNS exclusively, like c-ares library, adns,
>> ldns, unbound-libs...
> Why would a DNS library change its processing logic based on the
> setting?  Even the otherwise rather high-level Unbound library seems
> pretty much tied to a specific address type.
>
> The low level glibc APIs do not react to this flag, either:
>
> +/* res_send-like modes do not perform error translation.  */

The only code, which should react to this flag, is the one using 
AF_UNSPEC to start both A and AAAA request. If the library provide 
getaddrinfo implementation with AF_UNSPEC ability, then it should use 
flags in similar way.

If there a support for res_nquery to query for both A and AAAA in single 
library call, then it should react to this. But I do not think this is 
the case.

ldns_getaddrinfo is provided by ldns library, but that requires explicit 
A or AAAA. Cannot request both. So in this case, it should not modify 
anything.

ares_getaddrinfo from c-ares should be modified to behave similar way 
however. Because I am sure it parses /etc/resolv.conf and supports hints 
with ai_family == AF_UNSPEC.

>> Yes, they can implement similar change if they wish in their parsers
>> and I would recommend it to them. The only nsswitch plugin doing DNS
>> resolution outside libc's dns is resolve from systemd-resolved.
> Ahh, so you want a different address policy for (unicast) DNS and for
> other name resolution services such as LDAP?  This seems rather
> specialized to me.
Yes. Because DNS without any route, except link local or loopback, will 
always fail connecting to service of that name. I want to modify 
semantics of AF_UNSPEC from get all addresses *known* to get all 
addresses *useful*. Any NSS plugin able to provide link-local address 
including scope can work, such plugins should not be affected.
>
>> If for example NetworkManager should manage these flags, it would have
>> to pass information about it to whatever manages
>> /etc/resolv.conf. From end applications it should not differ. This is
>> change of dns nsswitch plugin only. If they use different module, it
>> may have different preferences.
> Isn't this in argument in favor of NetworkManager managing /etc/gai.conf
> directly?
>
> On the other hand, it seems that NetworkManager can get much the same
> effect if it creates a route with an unreachable type.  From what I've
> seen, the way this is generally expected to work (‘happy eyeballs’) is
> that we produce an abundance of addresses, the application attempts
> parallel non-blocking connect to a few of them, and the network is
> supposed to provide ICMP error responses (preferably on ingress) if it
> encounters an unsupported address family/address scope.  NetworkManager
> creating routes to express that if available networks do not provide
> this behavior natively looks like an acceptable workaround to me.

My question is, why should we rely on IPv4 only host connection contains 
failed attempt to IPv6 address first. Yes, that failure is very fast. 
But even then is completely unnecessary. As is the lookup for that AAAA 
address. This change should change only DNS clients and they are always 
configured by /etc/resolv.conf. That is why I want to store that 
instruction in that file. Added advantage is many of them already 
monitor /etc/resolv.conf for changes and can catch change in flags in 
them. If NetworkManager would change flags when IPv6 route appears or 
disappears, many clients will handle it. Not all, but most of them.

If we put the same thing into /etc/gai.conf, they would have to 
implement watching that for changes too. Or a new glibc call would have 
to be provided for that. Instead, we have this already implemented in 
dns plugin, where we can reuse it.

This change is not in conflict with happy eyeballs. But it makes 
possible to not wait for AAAA queries response, because maybe they are 
not even started.

>> I wrote it before. I want getent ahosts example.local to still return
>> both addresses for link local protocols like nss-mdns plugin. It
>> should provide also both addresses for localhost or other /etc/hosts
>> entries. Even if options ipv4 in resolv.conf should prevent getent
>> ahosts example.org from fetching and printing AAAA address. Because
>> link-local protocol can use AAAA address it receives (including link
>> scope_id) and is able to make communication with it. I think there
>> should not be any other module accessing _res.options. If they have
>> resolv.conf parser, they should parse it from text form instead. I
>> would not oppose making _res internal only and static in libc.
> See above, I don't see the need to filter out addresses if there is
> prompt notification of unreachability.
Yes, but you have to make AAAA query first. If you misconfigure your 
dnsmasq to forward AAAA somewhere, where it timeouts, you suddenly have 
very noticeable delays. Unfortunately that is not uncommon. Caused by 
AAAA lookup, which would fail immediately even if it worked. Never used 
on IPv4-only network. Draining your battery, filling your cache, wasting 
CPU cycles. It is small improvement to omit those, but still improvement.
>
> The existing noaaaa option is intended as a debugging tool in case
> someone claims that the extra AAAA queries cause problems.  With it you
> can set noaaaa, observe that the problem persists, and move on.  It was
> never intended as the start of a general policy engine for nss_dns.
>
> Thanks,
> Florian

Yes, no-aaaa is a bit drastic solution. I think my solution allows the 
same thing, but also for production usage. Not just for debugging. It 
leaves possible to try IPv6 connection with curl -6 example.org and see 
what error it emits or how fast. Can disable just the default behavior 
in applications using AF_UNSPEC.

Even if those failures are fast, we are wasting CPU cycles on local 
machine, per each connection. We are also sending unnecessary AAAA 
queries, which some people are blocking then on DNS server. 
filter-aaaa.so (man filter-aaaa with bind installed) is for that. 
Dnsmasq has also --filter-AAAA option. But it is much better to avoid 
asking unnecessary questions. That is my solution here. Ask A question 
if on IPv4-only network, even when client uses AF_UNSPEC. Ask AAAA only 
if on IPv6 only network.

I think macos has something similar implemented in scutil [1]. Microsoft 
has this also in their host cache. We could implement this into nscd, if 
it were not deprecated. DNS protocol cache does not have distinction 
between AF_INET and AF_UNSPEC, so it cannot react to that. There it sees 
only A or AAAA request, it is too late to handle it there.

Thanks for review,
Petr

1. 
https://apple.stackexchange.com/questions/304215/how-to-add-aaaa-flag-ipv6-to-dns-resolver-configuration-on-sierra

-- 
Petr Menšík
Senior Software Engineer, RHEL
Red Hat, https://www.redhat.com/
PGP: DFCF908DB7C87E8E529925BC4931CA5B6C9FC5CB



More information about the Libc-alpha mailing list