mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
* resolv/resolv.h (RES_SNGLKUP): Define.
* resolv/res_init.c (res_setoptions): Recognize single-request option. * resolv/res_send.c (send_dg): If we sent two requests at once and only get one reply before timeout switch to mode where we send the second request only after the first answer has been received.
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
2009-04-06 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* resolv/resolv.h (RES_SNGLKUP): Define.
|
||||||
|
* resolv/res_init.c (res_setoptions): Recognize single-request option.
|
||||||
|
* resolv/res_send.c (send_dg): If we sent two requests at once and
|
||||||
|
only get one reply before timeout switch to mode where we send the
|
||||||
|
second request only after the first answer has been received.
|
||||||
|
|
||||||
2009-04-05 Ulrich Drepper <drepper@redhat.com>
|
2009-04-05 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* sysdeps/x86_64/strlen.S: Optimize by using SSE2 instructions.
|
* sysdeps/x86_64/strlen.S: Optimize by using SSE2 instructions.
|
||||||
|
@ -540,6 +540,9 @@ res_setoptions(res_state statp, const char *options, const char *source) {
|
|||||||
statp->options |= RES_NOCHECKNAME;
|
statp->options |= RES_NOCHECKNAME;
|
||||||
} else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
|
} else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
|
||||||
statp->options |= RES_USE_EDNS0;
|
statp->options |= RES_USE_EDNS0;
|
||||||
|
} else if (!strncmp(cp, "single-request",
|
||||||
|
sizeof("single-request") - 1)) {
|
||||||
|
statp->options |= RES_SNGLKUP;
|
||||||
} else {
|
} else {
|
||||||
/* XXX - print a warning here? */
|
/* XXX - print a warning here? */
|
||||||
}
|
}
|
||||||
|
@ -923,12 +923,12 @@ send_dg(res_state statp,
|
|||||||
struct pollfd pfd[1];
|
struct pollfd pfd[1];
|
||||||
int ptimeout;
|
int ptimeout;
|
||||||
struct sockaddr_in6 from;
|
struct sockaddr_in6 from;
|
||||||
int resplen, seconds, n;
|
int resplen, n;
|
||||||
|
|
||||||
if (EXT(statp).nssocks[ns] == -1) {
|
if (EXT(statp).nssocks[ns] == -1) {
|
||||||
/* only try IPv6 if IPv6 NS and if not failed before */
|
/* only try IPv6 if IPv6 NS and if not failed before */
|
||||||
if ((EXT(statp).nscount6 > 0) && !statp->ipv6_unavail) {
|
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] =
|
EXT(statp).nssocks[ns] =
|
||||||
socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK,
|
socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK,
|
||||||
0);
|
0);
|
||||||
@ -939,7 +939,7 @@ send_dg(res_state statp,
|
|||||||
&& errno == EINVAL ? -1 : 1);
|
&& errno == EINVAL ? -1 : 1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (__have_o_nonblock < 0)
|
if (__builtin_expect (__have_o_nonblock < 0, 0))
|
||||||
EXT(statp).nssocks[ns] =
|
EXT(statp).nssocks[ns] =
|
||||||
socket(PF_INET6, SOCK_DGRAM, 0);
|
socket(PF_INET6, SOCK_DGRAM, 0);
|
||||||
if (EXT(statp).nssocks[ns] < 0)
|
if (EXT(statp).nssocks[ns] < 0)
|
||||||
@ -950,7 +950,7 @@ send_dg(res_state statp,
|
|||||||
convaddr4to6(nsap);
|
convaddr4to6(nsap);
|
||||||
}
|
}
|
||||||
if (EXT(statp).nssocks[ns] < 0) {
|
if (EXT(statp).nssocks[ns] < 0) {
|
||||||
if (__have_o_nonblock >= 0) {
|
if (__builtin_expect (__have_o_nonblock >= 0, 1)) {
|
||||||
EXT(statp).nssocks[ns]
|
EXT(statp).nssocks[ns]
|
||||||
= socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK,
|
= socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK,
|
||||||
0);
|
0);
|
||||||
@ -961,7 +961,7 @@ send_dg(res_state statp,
|
|||||||
&& errno == EINVAL ? -1 : 1);
|
&& errno == EINVAL ? -1 : 1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (__have_o_nonblock < 0)
|
if (__builtin_expect (__have_o_nonblock < 0, 0))
|
||||||
EXT(statp).nssocks[ns]
|
EXT(statp).nssocks[ns]
|
||||||
= socket(PF_INET, SOCK_DGRAM, 0);
|
= socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
}
|
}
|
||||||
@ -989,7 +989,7 @@ send_dg(res_state statp,
|
|||||||
__res_iclose(statp, false);
|
__res_iclose(statp, false);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
if (__have_o_nonblock < 0) {
|
if (__builtin_expect (__have_o_nonblock < 0, 0)) {
|
||||||
/* Make socket non-blocking. */
|
/* Make socket non-blocking. */
|
||||||
int fl = __fcntl (EXT(statp).nssocks[ns], F_GETFL);
|
int fl = __fcntl (EXT(statp).nssocks[ns], F_GETFL);
|
||||||
if (fl != -1)
|
if (fl != -1)
|
||||||
@ -1003,11 +1003,14 @@ send_dg(res_state statp,
|
|||||||
/*
|
/*
|
||||||
* Compute time for the total operation.
|
* Compute time for the total operation.
|
||||||
*/
|
*/
|
||||||
seconds = (statp->retrans << ns);
|
int seconds = (statp->retrans << ns);
|
||||||
if (ns > 0)
|
if (ns > 0)
|
||||||
seconds /= statp->nscount;
|
seconds /= statp->nscount;
|
||||||
if (seconds <= 0)
|
if (seconds <= 0)
|
||||||
seconds = 1;
|
seconds = 1;
|
||||||
|
bool single_request = ((statp->options) & RES_SNGLKUP) != 0;// XXX
|
||||||
|
int save_gotsomewhere = *gotsomewhere;
|
||||||
|
retry:
|
||||||
evNowTime(&now);
|
evNowTime(&now);
|
||||||
evConsTime(&timeout, seconds, 0);
|
evConsTime(&timeout, seconds, 0);
|
||||||
evAddTime(&finish, &now, &timeout);
|
evAddTime(&finish, &now, &timeout);
|
||||||
@ -1031,6 +1034,7 @@ send_dg(res_state statp,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
evSubTime(&timeout, &finish, &now);
|
evSubTime(&timeout, &finish, &now);
|
||||||
|
need_recompute = 0;
|
||||||
}
|
}
|
||||||
/* Convert struct timespec in milliseconds. */
|
/* Convert struct timespec in milliseconds. */
|
||||||
ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
|
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"));
|
Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
|
||||||
if (resplen > 1 && (recvresp1 || (buf2 != NULL && recvresp2)))
|
if (resplen > 1 && (recvresp1 || (buf2 != NULL && recvresp2)))
|
||||||
{
|
{
|
||||||
*resplen2 = 1;
|
/* There are quite a few broken name servers out
|
||||||
return resplen;
|
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;
|
*gotsomewhere = 1;
|
||||||
@ -1073,7 +1085,7 @@ send_dg(res_state statp,
|
|||||||
Perror(statp, stderr, "send", errno);
|
Perror(statp, stderr, "send", errno);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
if (nwritten != 0 || buf2 == NULL)
|
if (nwritten != 0 || buf2 == NULL || single_request)
|
||||||
pfd[0].events = POLLIN;
|
pfd[0].events = POLLIN;
|
||||||
else
|
else
|
||||||
pfd[0].events = POLLIN | POLLOUT;
|
pfd[0].events = POLLIN | POLLOUT;
|
||||||
@ -1286,8 +1298,11 @@ send_dg(res_state statp,
|
|||||||
else
|
else
|
||||||
recvresp2 = 1;
|
recvresp2 = 1;
|
||||||
/* Repeat waiting if we have a second answer to arrive. */
|
/* 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;
|
goto wait;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* All is well, or the error is fatal. Signal that the
|
* All is well, or the error is fatal. Signal that the
|
||||||
* next nameserver ought not be tried.
|
* next nameserver ought not be tried.
|
||||||
|
@ -215,6 +215,7 @@ struct res_sym {
|
|||||||
#define RES_NOIP6DOTINT 0x00080000 /* Do not use .ip6.int in IPv6
|
#define RES_NOIP6DOTINT 0x00080000 /* Do not use .ip6.int in IPv6
|
||||||
reverse lookup */
|
reverse lookup */
|
||||||
#define RES_USE_EDNS0 0x00100000 /* Use EDNS0. */
|
#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)
|
#define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user