Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F132337215
D49411.id152429.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D49411.id152429.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D49411: libc/getaddrinfo(2): return EAI_AGAIN on nameserver timeout
Attached
Detach File
Event Timeline
Log In to Comment