]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4317. [bug] Age all unused servers on fetch timeout. [RT #41597]
authorMark Andrews <marka@isc.org>
Fri, 12 Feb 2016 01:32:58 +0000 (12:32 +1100)
committerMark Andrews <marka@isc.org>
Fri, 12 Feb 2016 01:32:58 +0000 (12:32 +1100)
CHANGES
lib/dns/resolver.c

diff --git a/CHANGES b/CHANGES
index 968823246902ece2107899fa964b9aa37bfa0270..33c580c4d52f51486a48154febe554d824a0bf71 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -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
                        presentation format [RT #41595].
 
index 83c740a2d448843d3549701644415215d3c01973..4708392b3387dc2a4e9ac9bb59a36c9e75f13958 100644 (file)
@@ -881,7 +881,8 @@ resquery_destroy(resquery_t **queryp) {
 
 static void
 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;
        resquery_t *query;
@@ -993,14 +994,14 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
         * Age RTTs of servers not tried.
         */
        isc_stdtime_get(&now);
-       if (finish != NULL)
+       if (finish != NULL || age_untried)
                for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
                     addrinfo != NULL;
                     addrinfo = ISC_LIST_NEXT(addrinfo, publink))
                        if (UNMARKED(addrinfo))
                                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);
                     find != NULL;
                     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,
                                                        now);
 
-       if (finish != NULL && TRIEDALT(fctx)) {
+       if ((finish != NULL || age_untried) && TRIEDALT(fctx)) {
                for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
                     addrinfo != NULL;
                     addrinfo = ISC_LIST_NEXT(addrinfo, publink))
@@ -1082,7 +1083,9 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
 }
 
 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;
 
        FCTXTRACE("cancelqueries");
@@ -1091,7 +1094,8 @@ fctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response) {
             query != NULL;
             query = next_query) {
                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
-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");
-       fctx_cancelqueries(fctx, no_response);
+       fctx_cancelqueries(fctx, no_response, age_untried);
        fctx_cleanupfinds(fctx);
        fctx_cleanupaltfinds(fctx);
        fctx_cleanupforwaddrs(fctx);
@@ -1398,6 +1404,7 @@ static void
 fctx_done(fetchctx_t *fctx, isc_result_t result, int line) {
        dns_resolver_t *res;
        isc_boolean_t no_response = ISC_FALSE;
+       isc_boolean_t age_untried = ISC_FALSE;
 
        REQUIRE(line >= 0);
 
@@ -1411,10 +1418,11 @@ fctx_done(fetchctx_t *fctx, isc_result_t result, int line) {
                 */
                log_edns(fctx);
                no_response = ISC_TRUE;
-       }
+       } else if (result == ISC_R_TIMEDOUT)
+               age_untried = ISC_TRUE;
 
        fctx->reason = NULL;
-       fctx_stopeverything(fctx, no_response);
+       fctx_stopeverything(fctx, no_response, age_untried);
 
        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,
                                badns_unreachable);
-                       fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
+                       fctx_cancelquery(&query, NULL, NULL, ISC_TRUE,
+                                        ISC_FALSE);
                        retry = ISC_TRUE;
                        break;
 
@@ -1473,7 +1482,8 @@ process_sendevent(resquery_t *query, isc_event_t *event) {
                                   "unexpected event result; responding",
                                   sevent->result);
 
-                       fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
+                       fctx_cancelquery(&query, NULL, NULL, ISC_FALSE,
+                                        ISC_FALSE);
                        break;
                }
        }
@@ -2636,7 +2646,8 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
                                FCTXTRACE("query canceled: idle timer failed; "
                                          "responding");
 
-                               fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
+                               fctx_cancelquery(&query, NULL, NULL, ISC_FALSE,
+                                                ISC_FALSE);
                                fctx_done(fctx, result, __LINE__);
                                break;
                        }
@@ -2675,7 +2686,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
                                FCTXTRACE("query canceled: "
                                          "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__);
                        }
                        break;
@@ -2694,7 +2705,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
                         * No route to remote.
                         */
                        isc_socket_detach(&query->tcpsocket);
-                       fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
+                       fctx_cancelquery(&query, NULL, NULL, ISC_TRUE, ISC_FALSE);
                        retry = ISC_TRUE;
                        break;
 
@@ -2704,7 +2715,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
                                   sevent->result);
 
                        isc_socket_detach(&query->tcpsocket);
-                       fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
+                       fctx_cancelquery(&query, NULL, NULL, ISC_FALSE, ISC_FALSE);
                        break;
                }
        }
@@ -3680,7 +3691,7 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
 
        if (addrinfo == NULL) {
                /* We have no more addresses.  Start over. */
-               fctx_cancelqueries(fctx, ISC_TRUE);
+               fctx_cancelqueries(fctx, ISC_TRUE, ISC_FALSE);
                fctx_cleanupfinds(fctx);
                fctx_cleanupaltfinds(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)
                {
                        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;
 
@@ -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
         * before we lock the bucket lock.
         */
-       fctx_stopeverything(fctx, ISC_FALSE);
+       fctx_stopeverything(fctx, ISC_FALSE, ISC_FALSE);
 
        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?
         */
-       fctx_cancelquery(&query, &devent, finish, no_response);
+       fctx_cancelquery(&query, &devent, finish, no_response, ISC_FALSE);
 
        if (keep_trying) {
                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_ok = ISC_TRUE;
-                       fctx_cancelqueries(fctx, ISC_TRUE);
+                       fctx_cancelqueries(fctx, ISC_TRUE, ISC_FALSE);
                        fctx_cleanupfinds(fctx);
                        fctx_cleanupaltfinds(fctx);
                        fctx_cleanupforwaddrs(fctx);
@@ -8541,7 +8552,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
                 * DNSSEC validator to validate the answer.
                 */
                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;
                 * 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) {
                unsigned int n;
                add_bad(fctx, addrinfo, result, broken_type);
-               fctx_cancelqueries(fctx, ISC_TRUE);
+               fctx_cancelqueries(fctx, ISC_TRUE, ISC_FALSE);
                fctx_cleanupfinds(fctx);
                fctx_cleanupforwaddrs(fctx);