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]

[PATCHv2] resolv: Allow new "timeout-ms" option


Allow an option to specify DNS timeout in milliseconds instead
of seconds.
---
v2 changes:

 * Changed minimum timeout to 1ms
 * Relaxed initialization of seconds, milliseconds
 * Switched to glibc style for "||" expression (first use
   of this style in this module)

 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..62b4109 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);
 	if (ns > 0)
-		seconds /= statp->nscount;
-	if (seconds <= 0)
-		seconds = 1;
+		operation_time /= statp->nscount;
+	int seconds, milliseconds;
+	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;
+		milliseconds = 0;
+	}
 	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..555a629 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		1	/* 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


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