From d62aec3ffabf77655c6bd028cf45213e034522fb Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 17 Mar 2021 13:53:52 +0000 Subject: bugfix: s6dns_resolve_aaaaa API on double nodata --- src/clients/s6-dnsip.c | 2 +- src/libs6dns/s6dns_resolven_loop.c | 17 +++++++++++------ src/libs6dns/s6dns_resolvenoq_aaaaa.c | 9 ++++++++- src/libs6dns/s6dns_resolveq_aaaaa.c | 22 +++++++++++++--------- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/clients/s6-dnsip.c b/src/clients/s6-dnsip.c index f4c1a58..3b86fe0 100644 --- a/src/clients/s6-dnsip.c +++ b/src/clients/s6-dnsip.c @@ -48,7 +48,7 @@ int main (int argc, char const *const *argv) { int r = s6dns_resolve_aaaaa_g(&ips, argv[0], strlen(argv[0]), flagqualify, &deadline) ; if (r < 0) strerr_diefu2sys((errno == ETIMEDOUT) ? 99 : 111, "resolve ", argv[0]) ; - if (!r) strerr_diefu4x(2, "resolve ", argv[0], ": ", s6dns_constants_error_str(errno)) ; + if (!r && errno) strerr_diefu4x(2, "resolve ", argv[0], ": ", s6dns_constants_error_str(errno)) ; } if (!genalloc_len(ip46full_t, &ips)) return 1 ; diff --git a/src/libs6dns/s6dns_resolven_loop.c b/src/libs6dns/s6dns_resolven_loop.c index 23b1c36..2cc5da0 100644 --- a/src/libs6dns/s6dns_resolven_loop.c +++ b/src/libs6dns/s6dns_resolven_loop.c @@ -15,7 +15,8 @@ int s6dns_resolven_loop (s6dns_engine_t *dt, unsigned int n, unsigned int or, ta { iopause_fd x[n] ; unsigned int count = 0 ; - for (;;) + unsigned int got = 0 ; + while (got < n) { tain_t localdeadline = *deadline ; int r ; @@ -34,19 +35,23 @@ int s6dns_resolven_loop (s6dns_engine_t *dt, unsigned int n, unsigned int or, ta else if (!r) { if (tain_less(deadline, stamp)) return (errno = ETIMEDOUT, -1) ; - for (i = 0 ; i < n ; i++) if (dt[i].status == EAGAIN) - if (s6dns_engine_timeout(dt + i, stamp) && (or >= 2)) return i ; + for (i = 0 ; i < n ; i++) if (dt[i].status == EAGAIN && s6dns_engine_timeout(dt + i, stamp)) + { + got++ ; + if (or >= 2) return i ; + } } else { for (i = 0 ; i < n ; i++) if (dt[i].status == EAGAIN) { r = s6dns_engine_event(dt + i, stamp) ; - if (or) + if (r) { - if (r && ((r > 0) || (or >= 2))) return i ; + got++ ; + if (r > 0) count++ ; + if (or && (r > 0 || or >= 2)) return i ; } - else if (r > 0) count++ ; } } } diff --git a/src/libs6dns/s6dns_resolvenoq_aaaaa.c b/src/libs6dns/s6dns_resolvenoq_aaaaa.c index 7012594..378a70a 100644 --- a/src/libs6dns/s6dns_resolvenoq_aaaaa.c +++ b/src/libs6dns/s6dns_resolvenoq_aaaaa.c @@ -1,8 +1,11 @@ /* ISC license. */ +#include + #include #include #include + #include #include #include @@ -25,7 +28,11 @@ int s6dns_resolvenoq_aaaaa_r (genalloc *ips, char const *name, size_t len, s6dns blob[1].parsefunc = &s6dns_message_parse_answer_a ; blob[1].data = &sa[1] ; if (!s6dns_resolven_parse_r(blob, 2, servers, dbh, deadline, stamp)) return -1 ; - if (blob[0].status && blob[1].status) return (errno = blob[1].status, 0) ; + if (!sa[0].len && !sa[1].len) + { + errno = blob[1].status ? blob[1].status : blob[0].status ; + return 0 ; + } if (!genalloc_readyplus(ip46full_t, ips, (sa[0].len >> 4) + (sa[1].len >> 2))) { stralloc_free(&sa[0]) ; diff --git a/src/libs6dns/s6dns_resolveq_aaaaa.c b/src/libs6dns/s6dns_resolveq_aaaaa.c index 460956e..fe564ae 100644 --- a/src/libs6dns/s6dns_resolveq_aaaaa.c +++ b/src/libs6dns/s6dns_resolveq_aaaaa.c @@ -71,7 +71,8 @@ int s6dns_resolveq_aaaaa_r (genalloc *ips, char const *name, size_t len, s6dns_r if (pinned && !(best & 1)) goto end ; if (best >= n << 1) goto notfound ; if (error_isagain(dtl[best].status)) break ; - if (dtl[best].status) { errno = dtl[best].status ; goto err ; } + errno = dtl[best].status ; + if (errno) goto err ; r = s6dns_message_parse(&h, s6dns_engine_packet(dtl + best), s6dns_engine_packetlen(dtl + best), (best & 1) ? &s6dns_message_parse_answer_a : s6dns_message_parse_answer_aaaa, &data) ; if (r < 0) goto err ; else if (r) @@ -81,16 +82,19 @@ int s6dns_resolveq_aaaaa_r (genalloc *ips, char const *name, size_t len, s6dns_r data.len = 0 ; pinned = 1 ; } - else switch (errno) + else { - case EBUSY : - case ENOENT : - case ECONNREFUSED : - case EIO : - break ; - default : goto err ; + switch (errno) + { + case EBUSY : + case ENOENT : + case ECONNREFUSED : + case EIO : + break ; + default : goto err ; + } + if (!best) e = errno ; } - if (!best) e = errno ; } } } -- cgit v1.2.3