Page MenuHomeFreeBSD

D49411.id152429.diff
No OneTemporary

D49411.id152429.diff

diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c
--- a/lib/libc/net/getaddrinfo.c
+++ b/lib/libc/net/getaddrinfo.c
@@ -2341,9 +2341,14 @@
if (res_searchN(hostname, &q, res) < 0) {
free(buf);
free(buf2);
- if (res->res_h_errno == NO_DATA)
+ switch (res->res_h_errno) {
+ case NO_DATA:
return (NS_ADDRFAMILY);
- return (NS_NOTFOUND);
+ case TRY_AGAIN:
+ return (NS_TRYAGAIN);
+ default:
+ return (NS_NOTFOUND);
+ }
}
/* prefer IPv6 */
if (q.next) {
@@ -2705,9 +2710,18 @@
int n;
u_int oflags;
struct res_target *t;
- int rcode;
+ u_int rcode;
int ancount;
+ /*
+ * Extend rcode values in the scope of this function. The DNS header
+ * rcode we use in this function (hp->rcode) is limited by 4 bits, so
+ * anything starting from 16 is safe wrt aliasing. However, nameser.h
+ * already has extended enum __ns_rcode, so for future safety let's use
+ * even larger values.
+ */
+#define RCODE_UNREACH 32
+#define RCODE_TIMEDOUT 33
rcode = NOERROR;
ancount = 0;
@@ -2768,7 +2782,29 @@
printf(";; res_nquery: retry without EDNS0\n");
goto again;
}
- rcode = hp->rcode; /* record most recent error */
+ /*
+ * Historically if a DNS server replied with ICMP port
+ * unreach res_nsend() would signal that with
+ * ECONNREFUSED and the upper layers would convert that
+ * into TRY_AGAIN. See 3a0b3b673936b and deeper.
+ * Also, res_nsend() may set errno to ECONNREFUSED due
+ * to internal failures. This may not be intentional,
+ * but we also treat that as soft failures.
+ *
+ * A more practical case is when a DNS server(s) were
+ * queried and didn't respond anything, which usually
+ * indicates a soft network failure.
+ */
+ switch (errno) {
+ case ECONNREFUSED:
+ rcode = RCODE_UNREACH;
+ break;
+ case ETIMEDOUT:
+ rcode = RCODE_TIMEDOUT;
+ break;
+ default:
+ rcode = hp->rcode;
+ }
#ifdef DEBUG
if (res->options & RES_DEBUG)
printf(";; res_query: send error\n");
@@ -2800,6 +2836,8 @@
case NXDOMAIN:
RES_SET_H_ERRNO(res, HOST_NOT_FOUND);
break;
+ case RCODE_UNREACH:
+ case RCODE_TIMEDOUT:
case SERVFAIL:
RES_SET_H_ERRNO(res, TRY_AGAIN);
break;
@@ -2862,10 +2900,6 @@
ret = res_querydomainN(name, NULL, target, res);
if (ret > 0 || trailing_dot)
return (ret);
- if (errno == ECONNREFUSED) {
- RES_SET_H_ERRNO(res, TRY_AGAIN);
- return (-1);
- }
switch (res->res_h_errno) {
case NO_DATA:
case HOST_NOT_FOUND:
@@ -2906,7 +2940,6 @@
ret = res_querydomainN(name, *domain, target, res);
if (ret > 0)
return (ret);
-
/*
* If no server present, give up.
* If name isn't found in this domain,
@@ -2920,11 +2953,6 @@
* but try the input name below in case it's
* fully-qualified.
*/
- if (errno == ECONNREFUSED) {
- RES_SET_H_ERRNO(res, TRY_AGAIN);
- return (-1);
- }
-
switch (res->res_h_errno) {
case NO_DATA:
got_nodata++;
@@ -2933,8 +2961,8 @@
/* keep trying */
break;
case TRY_AGAIN:
- got_servfail++;
if (hp->rcode == SERVFAIL) {
+ got_servfail++;
/* try next search element, if any */
break;
}
diff --git a/lib/libc/tests/net/getaddrinfo/getaddrinfo2.c b/lib/libc/tests/net/getaddrinfo/getaddrinfo2.c
--- a/lib/libc/tests/net/getaddrinfo/getaddrinfo2.c
+++ b/lib/libc/tests/net/getaddrinfo/getaddrinfo2.c
@@ -119,19 +119,14 @@
resconf = badresolvconf;
rv = getaddrinfo(goodname, NULL, &hints, &res);
- /*
- * XXXGL: EAI_ADDRFAMILY is most likely a regression from 144361386696.
- * Error code on timeout used to be EAI_NONAME for many years and IMHO
- * this is not correct either. Should be EAI_AGAIN.
- */
- ATF_REQUIRE_MSG(rv == EAI_ADDRFAMILY,
- "Expected %d (EAI_ADDRFAMILY), got %d (%s)",
- EAI_ADDRFAMILY, rv, gai_strerror(rv));
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
rv = getaddrinfo(goodname_dot, NULL, &hints, &res);
- ATF_REQUIRE_MSG(rv == EAI_ADDRFAMILY,
- "Expected %d (EAI_ADDRFAMILY), got %d (%s)",
- EAI_ADDRFAMILY, rv, gai_strerror(rv));
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
}
ATF_TC_WITHOUT_HEAD(timeout_specific);
@@ -146,14 +141,14 @@
resconf = badresolvconf;
rv = getaddrinfo(goodname, "666", &hints, &res);
- ATF_REQUIRE_MSG(rv == EAI_ADDRFAMILY,
- "Expected %d (EAI_ADDRFAMILY), got %d (%s)",
- EAI_ADDRFAMILY, rv, gai_strerror(rv));
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
rv = getaddrinfo(goodname_dot, "666", &hints, &res);
- ATF_REQUIRE_MSG(rv == EAI_ADDRFAMILY,
- "Expected %d (EAI_ADDRFAMILY), got %d (%s)",
- EAI_ADDRFAMILY, rv, gai_strerror(rv));
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
}
ATF_TC_WITHOUT_HEAD(timeout2);
@@ -167,14 +162,14 @@
resconf = badresolvconf2;
rv = getaddrinfo(goodname, NULL, &hints, &res);
- ATF_REQUIRE_MSG(rv == EAI_ADDRFAMILY,
- "Expected %d (EAI_ADDRFAMILY), got %d (%s)",
- EAI_ADDRFAMILY, rv, gai_strerror(rv));
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
rv = getaddrinfo(goodname_dot, NULL, &hints, &res);
- ATF_REQUIRE_MSG(rv == EAI_ADDRFAMILY,
- "Expected %d (EAI_ADDRFAMILY), got %d (%s)",
- EAI_ADDRFAMILY, rv, gai_strerror(rv));
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
}
/*
@@ -191,14 +186,14 @@
send_error = ENETDOWN;
rv = getaddrinfo(goodname, NULL, &hints, &res);
- ATF_REQUIRE_MSG(rv == EAI_NONAME,
- "Expected %d (EAI_NONAME), got %d (%s)",
- EAI_NONAME, rv, gai_strerror(rv));
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
rv = getaddrinfo(goodname_dot, NULL, &hints, &res);
- ATF_REQUIRE_MSG(rv == EAI_ADDRFAMILY,
- "Expected %d (EAI_ADDRFAMILY), got %d (%s)",
- EAI_ADDRFAMILY, rv, gai_strerror(rv));
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
}
/*

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 17, 12:50 AM (1 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23811004
Default Alt Text
D49411.id152429.diff (6 KB)

Event Timeline