summaryrefslogtreecommitdiff
path: root/libc/resolv
diff options
context:
space:
mode:
authorjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2009-04-14 19:46:20 +0000
committerjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2009-04-14 19:46:20 +0000
commitb8ff540f38004e2c1dd4f9f9a7936e2d2057a03d (patch)
treee7eaef673c5d50d544ef0fa9741e82c1d94f9003 /libc/resolv
parent636dc71c0c0c0300fbe44498b2fc903140edc010 (diff)
Merge changes between r8126 and r8289 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@8290 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/resolv')
-rw-r--r--libc/resolv/nss_dns/dns-host.c2
-rw-r--r--libc/resolv/res_hconf.c2
-rw-r--r--libc/resolv/res_init.c3
-rw-r--r--libc/resolv/res_send.c37
-rw-r--r--libc/resolv/resolv.h1
5 files changed, 32 insertions, 13 deletions
diff --git a/libc/resolv/nss_dns/dns-host.c b/libc/resolv/nss_dns/dns-host.c
index a9462ae97..62e67e8b0 100644
--- a/libc/resolv/nss_dns/dns-host.c
+++ b/libc/resolv/nss_dns/dns-host.c
@@ -824,7 +824,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
switch (type)
{
case T_PTR:
- if (__builtin_expect (__strcasecmp (tname, bp) != 0, 0))
+ if (__builtin_expect (strcasecmp (tname, bp) != 0, 0))
{
syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp);
cp += n;
diff --git a/libc/resolv/res_hconf.c b/libc/resolv/res_hconf.c
index 25f739792..ed55bec29 100644
--- a/libc/resolv/res_hconf.c
+++ b/libc/resolv/res_hconf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995-2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995-2006, 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by David Mosberger (davidm@azstarnet.com).
diff --git a/libc/resolv/res_init.c b/libc/resolv/res_init.c
index 2bf830cc9..8841fe9fa 100644
--- a/libc/resolv/res_init.c
+++ b/libc/resolv/res_init.c
@@ -540,6 +540,9 @@ res_setoptions(res_state statp, const char *options, const char *source) {
statp->options |= RES_NOCHECKNAME;
} else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
statp->options |= RES_USE_EDNS0;
+ } else if (!strncmp(cp, "single-request",
+ sizeof("single-request") - 1)) {
+ statp->options |= RES_SNGLKUP;
} else {
/* XXX - print a warning here? */
}
diff --git a/libc/resolv/res_send.c b/libc/resolv/res_send.c
index f75a26ec2..0490b52fc 100644
--- a/libc/resolv/res_send.c
+++ b/libc/resolv/res_send.c
@@ -923,12 +923,12 @@ send_dg(res_state statp,
struct pollfd pfd[1];
int ptimeout;
struct sockaddr_in6 from;
- int resplen, seconds, n;
+ int resplen, n;
if (EXT(statp).nssocks[ns] == -1) {
/* only try IPv6 if IPv6 NS and if not failed before */
if ((EXT(statp).nscount6 > 0) && !statp->ipv6_unavail) {
- if (__have_o_nonblock >= 0) {
+ if (__builtin_expect (__have_o_nonblock >= 0, 1)) {
EXT(statp).nssocks[ns] =
socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK,
0);
@@ -939,7 +939,7 @@ send_dg(res_state statp,
&& errno == EINVAL ? -1 : 1);
#endif
}
- if (__have_o_nonblock < 0)
+ if (__builtin_expect (__have_o_nonblock < 0, 0))
EXT(statp).nssocks[ns] =
socket(PF_INET6, SOCK_DGRAM, 0);
if (EXT(statp).nssocks[ns] < 0)
@@ -950,7 +950,7 @@ send_dg(res_state statp,
convaddr4to6(nsap);
}
if (EXT(statp).nssocks[ns] < 0) {
- if (__have_o_nonblock >= 0) {
+ if (__builtin_expect (__have_o_nonblock >= 0, 1)) {
EXT(statp).nssocks[ns]
= socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK,
0);
@@ -961,7 +961,7 @@ send_dg(res_state statp,
&& errno == EINVAL ? -1 : 1);
#endif
}
- if (__have_o_nonblock < 0)
+ if (__builtin_expect (__have_o_nonblock < 0, 0))
EXT(statp).nssocks[ns]
= socket(PF_INET, SOCK_DGRAM, 0);
}
@@ -989,7 +989,7 @@ send_dg(res_state statp,
__res_iclose(statp, false);
return (0);
}
- if (__have_o_nonblock < 0) {
+ if (__builtin_expect (__have_o_nonblock < 0, 0)) {
/* Make socket non-blocking. */
int fl = __fcntl (EXT(statp).nssocks[ns], F_GETFL);
if (fl != -1)
@@ -1003,11 +1003,14 @@ send_dg(res_state statp,
/*
* Compute time for the total operation.
*/
- seconds = (statp->retrans << ns);
+ int seconds = (statp->retrans << ns);
if (ns > 0)
seconds /= statp->nscount;
if (seconds <= 0)
seconds = 1;
+ bool single_request = ((statp->options) & RES_SNGLKUP) != 0;// XXX
+ int save_gotsomewhere = *gotsomewhere;
+ retry:
evNowTime(&now);
evConsTime(&timeout, seconds, 0);
evAddTime(&finish, &now, &timeout);
@@ -1031,6 +1034,7 @@ send_dg(res_state statp,
return (0);
}
evSubTime(&timeout, &finish, &now);
+ need_recompute = 0;
}
/* Convert struct timespec in milliseconds. */
ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
@@ -1046,8 +1050,16 @@ send_dg(res_state statp,
Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
if (resplen > 1 && (recvresp1 || (buf2 != NULL && recvresp2)))
{
- *resplen2 = 1;
- return resplen;
+ /* There are quite a few broken name servers out
+ there which don't handle two outstanding
+ requests from the same source. There are also
+ broken firewall settings. If we time out after
+ having received one answer switch to the mode
+ where we send the second request only once we
+ have received the first answer. */
+ single_request = true;
+ *gotsomewhere = save_gotsomewhere;
+ goto retry;
}
*gotsomewhere = 1;
@@ -1073,7 +1085,7 @@ send_dg(res_state statp,
Perror(statp, stderr, "send", errno);
goto err_out;
}
- if (nwritten != 0 || buf2 == NULL)
+ if (nwritten != 0 || buf2 == NULL || single_request)
pfd[0].events = POLLIN;
else
pfd[0].events = POLLIN | POLLOUT;
@@ -1286,8 +1298,11 @@ send_dg(res_state statp,
else
recvresp2 = 1;
/* Repeat waiting if we have a second answer to arrive. */
- if ((recvresp1 & recvresp2) == 0)
+ if ((recvresp1 & recvresp2) == 0) {
+ if (single_request)
+ pfd[0].events = POLLOUT;
goto wait;
+ }
/*
* All is well, or the error is fatal. Signal that the
* next nameserver ought not be tried.
diff --git a/libc/resolv/resolv.h b/libc/resolv/resolv.h
index a0de320d0..c6e695dc7 100644
--- a/libc/resolv/resolv.h
+++ b/libc/resolv/resolv.h
@@ -215,6 +215,7 @@ struct res_sym {
#define RES_NOIP6DOTINT 0x00080000 /* Do not use .ip6.int in IPv6
reverse lookup */
#define RES_USE_EDNS0 0x00100000 /* Use EDNS0. */
+#define RES_SNGLKUP 0x00200000 /* one outstanding request at a time */
#define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT)