This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCHv3] resolv: Allow new "timeout-ms" option
Allow an option to specify DNS timeout in milliseconds instead
of seconds.
---
v3 changes:
* Handle situations where the ns shift would have overflowed INT_MAX
* Removed RES_MINWAIT_MS; using 1 second universally, since this is now an
unlikely exceptional condition.
resolv/res_debug.c | 1 +
resolv/res_init.c | 9 +++++++++
resolv/res_send.c | 26 ++++++++++++++++++++++----
resolv/resolv.h | 2 ++
4 files changed, 34 insertions(+), 4 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..4d45335 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -1008,11 +1008,29 @@ send_dg(res_state statp,
/*
* Compute time for the total operation.
*/
- int seconds = (statp->retrans << ns);
+ int operation_time;
+ if (statp->retrans > (INT_MAX >> ns)) {
+ /*
+ * Saturate operation_time if it would have exceeded INT_MAX
+ */
+ operation_time = INT_MAX;
+ } else {
+ operation_time = (statp->retrans << ns);
+ }
if (ns > 0)
- seconds /= statp->nscount;
- if (seconds <= 0)
+ operation_time /= statp->nscount;
+ time_t seconds;
+ long milliseconds;
+ if (operation_time <= 0) {
seconds = 1;
+ milliseconds = 0;
+ } else if ((statp->options & RES_TIMEOUT_MS) != 0) {
+ seconds = operation_time / 1000;
+ milliseconds = operation_time % 1000;
+ } else {
+ seconds = operation_time;
+ milliseconds = 0;
+ }
bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0;
bool single_request = (((statp->options & RES_SNGLKUP) != 0)
| single_request_reopen);
@@ -1025,7 +1043,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..f09754a 100644
--- a/resolv/resolv.h
+++ b/resolv/resolv.h
@@ -221,6 +221,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