aboutsummaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2020-05-19 19:11:16 -0400
committerRich Felker <dalias@aerifal.cx>2020-05-19 19:11:16 -0400
commit5cf1ac2443ad0dba263559a3fe043d929e0e5c4c (patch)
tree38fc87c133680050def3847af545c466ec1987f1 /src/network
parentfd7ec068efd590c0393a612599a4fab9bb0a8633 (diff)
downloadmusl-5cf1ac2443ad0dba263559a3fe043d929e0e5c4c.zip
musl-5cf1ac2443ad0dba263559a3fe043d929e0e5c4c.tar.gz
musl-5cf1ac2443ad0dba263559a3fe043d929e0e5c4c.tar.bz2
fix handling of errors resolving one of paired A+AAAA query
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.
Diffstat (limited to 'src/network')
-rw-r--r--src/network/lookup_name.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c
index c4d994a..aae0d95 100644
--- a/src/network/lookup_name.c
+++ b/src/network/lookup_name.c
@@ -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)