diff options
| -rw-r--r-- | lib/libc/net/res_query.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c index 65e87ad6855f..11b43b8110eb 100644 --- a/lib/libc/net/res_query.c +++ b/lib/libc/net/res_query.c @@ -273,11 +273,24 @@ res_search(name, class, type, answer, anslen) /* keep trying */ break; case TRY_AGAIN: - if (hp->rcode == SERVFAIL) { - /* try next search element, if any */ - got_servfail++; - break; - } + /* + * This can occur due to a server failure + * (that is, all listed servers have failed), + * or all listed servers have timed out. + * hp->rcode may not be set to SERVFAIL in the + * case of a timeout. + * + * Either way we must terminate the search + * and return TRY_AGAIN in order to avoid + * non-deterministic return codes. For + * example, loaded name servers or races + * against network startup/validation (dhcp, + * ppp, etc) can cause the search to timeout + * on one search element, e.g. 'fu.bar.com', + * and return a definitive failure on the + * next search element, e.g. 'fu.'. + */ + ++got_servfail; /* FALLTHROUGH */ default: /* anything else implies that we're done */ |
