fix handling of errors resolving one of paired A+AAAA query
authorRich Felker <dalias@aerifal.cx>
Tue, 19 May 2020 23:11:16 +0000 (19:11 -0400)
committerRich Felker <dalias@aerifal.cx>
Tue, 19 May 2020 23:11:16 +0000 (19:11 -0400)
the old logic here likely dates back, at least in inspiration, to
before it was recognized that transient errors must not be allowed to
reflect the contents of successful results and must be reported to the
application.

here, the dns backend for getaddrinfo, when performing a paired query
for v4 and v6 addresses, accepted results for one address family even
if the other timed out. (the __res_msend backend does not propagate
error rcodes back to the caller, but continues to retry until timeout,
so other error conditions were not actually possible.)

this patch moves the checks to take place before answer parsing, and
performs them for each answer rather than only the answer to the first
query. if nxdomain is seen it's assumed to apply to both queries since
that's how dns semantics work.

src/network/lookup_name.c

index c4d994a169c1bbcfd2d2a1f9d78c1150a6c26f62..aae0d95a041504b60cd1827278ba4ee1a3bee4c0 100644 (file)
@@ -157,14 +157,17 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static
        if (__res_msend_rc(nq, qp, qlens, ap, alens, sizeof *abuf, conf) < 0)
                return EAI_SYSTEM;
 
+       for (i=0; i<nq; i++) {
+               if (alens[i] < 4 || (abuf[i][3] & 15) == 2) return EAI_AGAIN;
+               if ((abuf[i][3] & 15) == 3) return 0;
+               if ((abuf[i][3] & 15) != 0) return EAI_FAIL;
+       }
+
        for (i=0; i<nq; i++)
                __dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
 
        if (ctx.cnt) return ctx.cnt;
-       if (alens[0] < 4 || (abuf[0][3] & 15) == 2) return EAI_AGAIN;
-       if ((abuf[0][3] & 15) == 0) return EAI_NONAME;
-       if ((abuf[0][3] & 15) == 3) return 0;
-       return EAI_FAIL;
+       return EAI_NONAME;
 }
 
 static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)