t_info("The default timeout is %d second%s\n", default_timeout,
(default_timeout == 1 ? "" : "s"));
- dns_resolver_settimeout(resolver, default_timeout - 1);
+ dns_resolver_settimeout(resolver, default_timeout + 1);
timeout = dns_resolver_gettimeout(resolver);
t_info("The new timeout is %d second%s\n", timeout,
(timeout == 1 ? "" : "s"));
- test_result = (timeout == default_timeout - 1) ? T_PASS : T_FAIL;
+ test_result = (timeout == default_timeout + 1) ? T_PASS : T_FAIL;
destroy_resolver(&resolver);
teardown();
#define QTRACE(m)
#endif
+#define US_PER_SEC 1000000U
+/*
+ * The maximum time we will wait for a single query.
+ */
+#define MAX_SINGLE_QUERY_TIMEOUT 9U
+#define MAX_SINGLE_QUERY_TIMEOUT_US (MAX_SINGLE_QUERY_TIMEOUT*US_PER_SEC)
+
+/*
+ * We need to allow a individual query time to complete / timeout.
+ */
+#define MINIMUM_QUERY_TIMEOUT (MAX_SINGLE_QUERY_TIMEOUT + 1U)
+
+/* The default time in seconds for the whole query to live. */
#ifndef DEFAULT_QUERY_TIMEOUT
-#define DEFAULT_QUERY_TIMEOUT 10 /* The default time in seconds for the whole query to live. */
+#define DEFAULT_QUERY_TIMEOUT MINIMUM_QUERY_TIMEOUT
#endif
#ifndef MAXIMUM_QUERY_TIMEOUT
*/
INSIST(no_response);
rtt = query->addrinfo->srtt + 200000;
- if (rtt > 10000000)
- rtt = 10000000;
+ if (rtt > MAX_SINGLE_QUERY_TIMEOUT_US)
+ rtt = MAX_SINGLE_QUERY_TIMEOUT_US;
/*
* Replace the current RTT with our value.
*/
us = (800000 << (fctx->restarts - 2));
/*
- * Double the round-trip time.
+ * Add a fudge factor to the expected rtt based on the current
+ * estimate.
*/
- rtt *= 2;
+ if (rtt < 50000)
+ rtt += 50000;
+ else if (rtt < 100000)
+ rtt += 100000;
+ else
+ rtt += 200000;
/*
- * Always wait for at least the doubled round-trip time.
+ * Always wait for at least the expected rtt.
*/
if (us < rtt)
us = rtt;
/*
* But don't ever wait for more than 10 seconds.
*/
- if (us > 10000000)
- us = 10000000;
+ if (us > MAX_SINGLE_QUERY_TIMEOUT_US)
+ us = MAX_SINGLE_QUERY_TIMEOUT_US;
- seconds = us / 1000000;
- us -= seconds * 1000000;
+ seconds = us / US_PER_SEC;
+ us -= seconds * US_PER_SEC;
isc_interval_set(&fctx->interval, seconds, us * 1000);
}
task = res->buckets[fctx->bucketnum].task;
srtt = addrinfo->srtt;
+
+ /*
+ * A forwarder needs to make multiple queries. Give it at least
+ * a second to do these in.
+ */
if (ISFORWARDER(addrinfo) && srtt < 1000000)
srtt = 1000000;
"timeout:%u,lame:%u,neterr:%u,badresp:%u,"
"adberr:%u,findfail:%u,valfail:%u]",
__FILE__, fctx->exitline, fctx->info,
- fctx->duration / 1000000,
- fctx->duration % 1000000,
+ fctx->duration / US_PER_SEC,
+ fctx->duration % US_PER_SEC,
isc_result_totext(fctx->result),
isc_result_totext(fctx->vresult), domainbuf,
fctx->referrals, fctx->restarts,
seconds = DEFAULT_QUERY_TIMEOUT;
if (seconds > MAXIMUM_QUERY_TIMEOUT)
seconds = MAXIMUM_QUERY_TIMEOUT;
+ if (seconds < MINIMUM_QUERY_TIMEOUT)
+ seconds = MINIMUM_QUERY_TIMEOUT;
resolver->query_timeout = seconds;
}