dns: fail if ipv6 is disabled and resolv.conf has only v6 nameserves
authorRich Felker <dalias@aerifal.cx>
Fri, 26 Aug 2022 18:57:52 +0000 (14:57 -0400)
committerRich Felker <dalias@aerifal.cx>
Fri, 26 Aug 2022 18:57:52 +0000 (14:57 -0400)
if resolv.conf lists no nameservers at all, the default of 127.0.0.1
is used. however, another "no nameservers" case arises where the
system has ipv6 support disabled/configured-out and resolv.conf only
contains v6 nameservers. this caused the resolver to repeat socket
operations that will necessarily fail (sending to one or more
wrong-family addresses) while waiting for a timeout.

it would be contrary to configured intent to query 127.0.0.1 in this
case, but the current behavior is not conducive to diagnosing the
configuration problem. instead, fail immediately with EAI_SYSTEM and
errno==EAFNOSUPPORT so that the configuration error is reportable.

src/network/res_msend.c

index 105bf59..9adaea1 100644 (file)
@@ -72,6 +72,11 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,
 
        /* Handle case where system lacks IPv6 support */
        if (fd < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
+               for (i=0; i<nns && conf->ns[nns].family == AF_INET6; i++);
+               if (i==nns) {
+                       pthread_setcancelstate(cs, 0);
+                       return -1;
+               }
                fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
                family = AF_INET;
                sl = sizeof sa.sin;