This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]