2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 15:05:23 +00:00

4317. [bug] Age all unused servers on fetch timeout. [RT #41597]

This commit is contained in:
Mark Andrews
2016-02-12 12:32:58 +11:00
parent 6632721990
commit d372f426ca
2 changed files with 36 additions and 23 deletions

View File

@@ -1,3 +1,5 @@
4317. [bug] Age all unused servers on fetch timeout. [RT #41597]
4316. [func] Add option to tools to print RRs in unknown 4316. [func] Add option to tools to print RRs in unknown
presentation format [RT #41595]. presentation format [RT #41595].

View File

@@ -881,7 +881,8 @@ resquery_destroy(resquery_t **queryp) {
static void static void
fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp, fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
isc_time_t *finish, isc_boolean_t no_response) isc_time_t *finish, isc_boolean_t no_response,
isc_boolean_t age_untried)
{ {
fetchctx_t *fctx; fetchctx_t *fctx;
resquery_t *query; resquery_t *query;
@@ -993,14 +994,14 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
* Age RTTs of servers not tried. * Age RTTs of servers not tried.
*/ */
isc_stdtime_get(&now); isc_stdtime_get(&now);
if (finish != NULL) if (finish != NULL || age_untried)
for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs); for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
addrinfo != NULL; addrinfo != NULL;
addrinfo = ISC_LIST_NEXT(addrinfo, publink)) addrinfo = ISC_LIST_NEXT(addrinfo, publink))
if (UNMARKED(addrinfo)) if (UNMARKED(addrinfo))
dns_adb_agesrtt(fctx->adb, addrinfo, now); dns_adb_agesrtt(fctx->adb, addrinfo, now);
if (finish != NULL && TRIEDFIND(fctx)) if ((finish != NULL || age_untried) && TRIEDFIND(fctx))
for (find = ISC_LIST_HEAD(fctx->finds); for (find = ISC_LIST_HEAD(fctx->finds);
find != NULL; find != NULL;
find = ISC_LIST_NEXT(find, publink)) find = ISC_LIST_NEXT(find, publink))
@@ -1011,7 +1012,7 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
dns_adb_agesrtt(fctx->adb, addrinfo, dns_adb_agesrtt(fctx->adb, addrinfo,
now); now);
if (finish != NULL && TRIEDALT(fctx)) { if ((finish != NULL || age_untried) && TRIEDALT(fctx)) {
for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs); for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
addrinfo != NULL; addrinfo != NULL;
addrinfo = ISC_LIST_NEXT(addrinfo, publink)) addrinfo = ISC_LIST_NEXT(addrinfo, publink))
@@ -1082,7 +1083,9 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
} }
static void static void
fctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response) { fctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response,
isc_boolean_t age_untried)
{
resquery_t *query, *next_query; resquery_t *query, *next_query;
FCTXTRACE("cancelqueries"); FCTXTRACE("cancelqueries");
@@ -1091,7 +1094,8 @@ fctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response) {
query != NULL; query != NULL;
query = next_query) { query = next_query) {
next_query = ISC_LIST_NEXT(query, link); next_query = ISC_LIST_NEXT(query, link);
fctx_cancelquery(&query, NULL, NULL, no_response); fctx_cancelquery(&query, NULL, NULL, no_response,
age_untried);
} }
} }
@@ -1158,9 +1162,11 @@ fctx_cleanupaltaddrs(fetchctx_t *fctx) {
} }
static inline void static inline void
fctx_stopeverything(fetchctx_t *fctx, isc_boolean_t no_response) { fctx_stopeverything(fetchctx_t *fctx, isc_boolean_t no_response,
isc_boolean_t age_untried)
{
FCTXTRACE("stopeverything"); FCTXTRACE("stopeverything");
fctx_cancelqueries(fctx, no_response); fctx_cancelqueries(fctx, no_response, age_untried);
fctx_cleanupfinds(fctx); fctx_cleanupfinds(fctx);
fctx_cleanupaltfinds(fctx); fctx_cleanupaltfinds(fctx);
fctx_cleanupforwaddrs(fctx); fctx_cleanupforwaddrs(fctx);
@@ -1398,6 +1404,7 @@ static void
fctx_done(fetchctx_t *fctx, isc_result_t result, int line) { fctx_done(fetchctx_t *fctx, isc_result_t result, int line) {
dns_resolver_t *res; dns_resolver_t *res;
isc_boolean_t no_response = ISC_FALSE; isc_boolean_t no_response = ISC_FALSE;
isc_boolean_t age_untried = ISC_FALSE;
REQUIRE(line >= 0); REQUIRE(line >= 0);
@@ -1411,10 +1418,11 @@ fctx_done(fetchctx_t *fctx, isc_result_t result, int line) {
*/ */
log_edns(fctx); log_edns(fctx);
no_response = ISC_TRUE; no_response = ISC_TRUE;
} } else if (result == ISC_R_TIMEDOUT)
age_untried = ISC_TRUE;
fctx->reason = NULL; fctx->reason = NULL;
fctx_stopeverything(fctx, no_response); fctx_stopeverything(fctx, no_response, age_untried);
LOCK(&res->buckets[fctx->bucketnum].lock); LOCK(&res->buckets[fctx->bucketnum].lock);
@@ -1464,7 +1472,8 @@ process_sendevent(resquery_t *query, isc_event_t *event) {
*/ */
add_bad(fctx, query->addrinfo, sevent->result, add_bad(fctx, query->addrinfo, sevent->result,
badns_unreachable); badns_unreachable);
fctx_cancelquery(&query, NULL, NULL, ISC_TRUE); fctx_cancelquery(&query, NULL, NULL, ISC_TRUE,
ISC_FALSE);
retry = ISC_TRUE; retry = ISC_TRUE;
break; break;
@@ -1473,7 +1482,8 @@ process_sendevent(resquery_t *query, isc_event_t *event) {
"unexpected event result; responding", "unexpected event result; responding",
sevent->result); sevent->result);
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); fctx_cancelquery(&query, NULL, NULL, ISC_FALSE,
ISC_FALSE);
break; break;
} }
} }
@@ -2636,7 +2646,8 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
FCTXTRACE("query canceled: idle timer failed; " FCTXTRACE("query canceled: idle timer failed; "
"responding"); "responding");
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); fctx_cancelquery(&query, NULL, NULL, ISC_FALSE,
ISC_FALSE);
fctx_done(fctx, result, __LINE__); fctx_done(fctx, result, __LINE__);
break; break;
} }
@@ -2675,7 +2686,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
FCTXTRACE("query canceled: " FCTXTRACE("query canceled: "
"resquery_send() failed; responding"); "resquery_send() failed; responding");
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); fctx_cancelquery(&query, NULL, NULL, ISC_FALSE, ISC_FALSE);
fctx_done(fctx, result, __LINE__); fctx_done(fctx, result, __LINE__);
} }
break; break;
@@ -2694,7 +2705,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
* No route to remote. * No route to remote.
*/ */
isc_socket_detach(&query->tcpsocket); isc_socket_detach(&query->tcpsocket);
fctx_cancelquery(&query, NULL, NULL, ISC_TRUE); fctx_cancelquery(&query, NULL, NULL, ISC_TRUE, ISC_FALSE);
retry = ISC_TRUE; retry = ISC_TRUE;
break; break;
@@ -2704,7 +2715,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
sevent->result); sevent->result);
isc_socket_detach(&query->tcpsocket); isc_socket_detach(&query->tcpsocket);
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); fctx_cancelquery(&query, NULL, NULL, ISC_FALSE, ISC_FALSE);
break; break;
} }
} }
@@ -3680,7 +3691,7 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
if (addrinfo == NULL) { if (addrinfo == NULL) {
/* We have no more addresses. Start over. */ /* We have no more addresses. Start over. */
fctx_cancelqueries(fctx, ISC_TRUE); fctx_cancelqueries(fctx, ISC_TRUE, ISC_FALSE);
fctx_cleanupfinds(fctx); fctx_cleanupfinds(fctx);
fctx_cleanupaltfinds(fctx); fctx_cleanupaltfinds(fctx);
fctx_cleanupforwaddrs(fctx); fctx_cleanupforwaddrs(fctx);
@@ -3890,7 +3901,7 @@ fctx_timeout(isc_task_t *task, isc_event_t *event) {
isc_time_compare(&tevent->due, &query->start) >= 0) isc_time_compare(&tevent->due, &query->start) >= 0)
{ {
FCTXTRACE("query timed out; no response"); FCTXTRACE("query timed out; no response");
fctx_cancelquery(&query, NULL, NULL, ISC_TRUE); fctx_cancelquery(&query, NULL, NULL, ISC_TRUE, ISC_FALSE);
} }
fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
@@ -3984,7 +3995,7 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) {
* fetch. To avoid deadlock with the ADB, we must do this * fetch. To avoid deadlock with the ADB, we must do this
* before we lock the bucket lock. * before we lock the bucket lock.
*/ */
fctx_stopeverything(fctx, ISC_FALSE); fctx_stopeverything(fctx, ISC_FALSE, ISC_FALSE);
LOCK(&res->buckets[bucketnum].lock); LOCK(&res->buckets[bucketnum].lock);
@@ -8444,7 +8455,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
* *
* XXXRTH Don't cancel the query if waiting for validation? * XXXRTH Don't cancel the query if waiting for validation?
*/ */
fctx_cancelquery(&query, &devent, finish, no_response); fctx_cancelquery(&query, &devent, finish, no_response, ISC_FALSE);
if (keep_trying) { if (keep_trying) {
if (result == DNS_R_FORMERR) if (result == DNS_R_FORMERR)
@@ -8508,7 +8519,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
} }
fctx->ns_ttl = fctx->nameservers.ttl; fctx->ns_ttl = fctx->nameservers.ttl;
fctx->ns_ttl_ok = ISC_TRUE; fctx->ns_ttl_ok = ISC_TRUE;
fctx_cancelqueries(fctx, ISC_TRUE); fctx_cancelqueries(fctx, ISC_TRUE, ISC_FALSE);
fctx_cleanupfinds(fctx); fctx_cleanupfinds(fctx);
fctx_cleanupaltfinds(fctx); fctx_cleanupaltfinds(fctx);
fctx_cleanupforwaddrs(fctx); fctx_cleanupforwaddrs(fctx);
@@ -8541,7 +8552,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
* DNSSEC validator to validate the answer. * DNSSEC validator to validate the answer.
*/ */
FCTXTRACE("wait for validator"); FCTXTRACE("wait for validator");
fctx_cancelqueries(fctx, ISC_TRUE); fctx_cancelqueries(fctx, ISC_TRUE, ISC_FALSE);
/* /*
* We must not retransmit while the validator is working; * We must not retransmit while the validator is working;
* it has references to the current rmessage. * it has references to the current rmessage.
@@ -8552,7 +8563,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
} else if (result == DNS_R_CHASEDSSERVERS) { } else if (result == DNS_R_CHASEDSSERVERS) {
unsigned int n; unsigned int n;
add_bad(fctx, addrinfo, result, broken_type); add_bad(fctx, addrinfo, result, broken_type);
fctx_cancelqueries(fctx, ISC_TRUE); fctx_cancelqueries(fctx, ISC_TRUE, ISC_FALSE);
fctx_cleanupfinds(fctx); fctx_cleanupfinds(fctx);
fctx_cleanupforwaddrs(fctx); fctx_cleanupforwaddrs(fctx);