This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] resolv: Allow new "timeout-ms" option
- From: Paul Stewart <pstew at chromium dot org>
- To: libc-alpha at sourceware dot org
- Cc: vapier at chromium dot org
- Date: Thu, 21 Jun 2012 06:26:30 -0700
- Subject: [PATCH] resolv: Allow new "timeout-ms" option
Allow an option to specify DNS timeout in milliseconds instead
of seconds.
---
resolv/res_debug.c | 1 +
resolv/res_init.c | 9 +++++++++
resolv/res_send.c | 23 ++++++++++++++++++-----
resolv/resolv.h | 3 +++
4 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
index 3daa44e..e4915f8 100644
--- a/resolv/res_debug.c
+++ b/resolv/res_debug.c
@@ -589,6 +589,7 @@ p_option(u_long option) {
case RES_USE_EDNS0: return "edns0";
case RES_USE_DNSSEC: return "dnssec";
case RES_NOTLDQUERY: return "no-tld-query";
+ case RES_TIMEOUT_MS: return "timeout-in-milliseconds";
/* XXX nonreentrant */
default: sprintf(nbuf, "?0x%lx?", (u_long)option);
return (nbuf);
diff --git a/resolv/res_init.c b/resolv/res_init.c
index c58c763..d00a7b0 100644
--- a/resolv/res_init.c
+++ b/resolv/res_init.c
@@ -501,11 +501,20 @@ res_setoptions(res_state statp, const char *options, const char *source) {
printf(";;\tndots=%d\n", statp->ndots);
#endif
} else if (!strncmp(cp, "timeout:", sizeof("timeout:") - 1)) {
+ statp->options &= ~RES_TIMEOUT_MS;
i = atoi(cp + sizeof("timeout:") - 1);
if (i <= RES_MAXRETRANS)
statp->retrans = i;
else
statp->retrans = RES_MAXRETRANS;
+ } else if (!strncmp(cp, "timeout-ms:",
+ sizeof("timeout-ms:") - 1)) {
+ statp->options |= RES_TIMEOUT_MS;
+ i = atoi(cp + sizeof("timeout-ms:") - 1);
+ if (i <= RES_MAXRETRANS * 1000)
+ statp->retrans = i;
+ else
+ statp->retrans = RES_MAXRETRANS * 1000;
} else if (!strncmp(cp, "attempts:", sizeof("attempts:") - 1)){
i = atoi(cp + sizeof("attempts:") - 1);
if (i <= RES_MAXRETRY)
diff --git a/resolv/res_send.c b/resolv/res_send.c
index 0a28cd7..31b116f 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -1008,11 +1008,24 @@ send_dg(res_state statp,
/*
* Compute time for the total operation.
*/
- int seconds = (statp->retrans << ns);
+ int operation_time = (statp->retrans << ns);
+ int seconds = 0;
+ int milliseconds = 0;
if (ns > 0)
- seconds /= statp->nscount;
- if (seconds <= 0)
- seconds = 1;
+ operation_time /= statp->nscount;
+ if ((statp->options & RES_TIMEOUT_MS) != 0) {
+ seconds = operation_time / 1000;
+ milliseconds = operation_time % 1000;
+ if (seconds < 0 ||
+ (seconds == 0 && milliseconds < RES_MINWAIT_MS)) {
+ seconds = 0;
+ milliseconds = RES_MINWAIT_MS;
+ }
+ } else {
+ seconds = operation_time;
+ if (seconds <= 0)
+ seconds = 1;
+ }
bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0;
bool single_request = (((statp->options & RES_SNGLKUP) != 0)
| single_request_reopen);
@@ -1025,7 +1038,7 @@ send_dg(res_state statp,
return retval;
retry:
evNowTime(&now);
- evConsTime(&timeout, seconds, 0);
+ evConsTime(&timeout, seconds, milliseconds * 1000000L);
evAddTime(&finish, &now, &timeout);
int need_recompute = 0;
int nwritten = 0;
diff --git a/resolv/resolv.h b/resolv/resolv.h
index ed15a70..8b02f00 100644
--- a/resolv/resolv.h
+++ b/resolv/resolv.h
@@ -100,6 +100,7 @@ typedef res_sendhookact (*res_send_rhook) (const struct sockaddr_in *__ns,
# define RES_MAXRETRY 5 /* only for resolv.conf/RES_OPTIONS */
# define RES_DFLRETRY 2 /* Default #/tries. */
# define RES_MAXTIME 65535 /* Infinity, in milliseconds. */
+# define RES_MINWAIT_MS 5 /* Minimum wait time, in milliseconds */
struct __res_state {
int retrans; /* retransmition time interval */
@@ -221,6 +222,8 @@ struct res_sym {
#define RES_USE_DNSSEC 0x00800000 /* use DNSSEC using OK bit in OPT */
#define RES_NOTLDQUERY 0x01000000 /* Do not look up unqualified name
as a TLD. */
+#define RES_TIMEOUT_MS 0x02000000 /* Timeout is specified in
+ milliseconds instead of seconds. */
#define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT)
--
1.7.7.3