]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2921. [bug] The resolver could attempt to destroy a fetch context
authorMark Andrews <marka@isc.org>
Wed, 23 Jun 2010 01:50:55 +0000 (01:50 +0000)
committerMark Andrews <marka@isc.org>
Wed, 23 Jun 2010 01:50:55 +0000 (01:50 +0000)
                        to soon.  [RT #19878]

CHANGES
lib/dns/resolver.c

diff --git a/CHANGES b/CHANGES
index d4933ef84c0856103fbbacabce1476a19c711de1..783d42af71ceb5613b730d2324a4958923aeae0b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2921.  [bug]           The resolver could attempt to destroy a fetch context
+                       to soon.  [RT #19878]
+
 2920.  [func]          Allow 'filter-aaaa-on-v4' to be applied selectively
                        to IPv4 clients.  New acl 'filter-aaaa' (default any).
 
index 3bdf5ddcb5a13e626e6c206bbb24582e9c401fb9..e825e1b0bbbd73f0fd959254865e48c1914960a6 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resolver.c,v 1.413.14.8 2010/04/20 23:49:58 tbox Exp $ */
+/* $Id: resolver.c,v 1.413.14.9 2010/06/23 01:50:55 marka Exp $ */
 
 /*! \file */
 
@@ -6159,13 +6159,40 @@ answer_response(fetchctx_t *fctx) {
        return (result);
 }
 
+static isc_boolean_t
+fctx_decreference(fetchctx_t *fctx) {
+       isc_boolean_t bucket_empty = ISC_FALSE;
+
+       INSIST(fctx->references > 0);
+       fctx->references--;
+       if (fctx->references == 0) {
+                /*
+                 * No one cares about the result of this fetch anymore.
+                 */
+                if (fctx->pending == 0 && fctx->nqueries == 0 &&
+                    ISC_LIST_EMPTY(fctx->validators) && SHUTTINGDOWN(fctx)) {
+                        /*
+                         * This fctx is already shutdown; we were just
+                         * waiting for the last reference to go away.
+                         */
+                        bucket_empty = fctx_destroy(fctx);
+                } else {
+                        /*
+                         * Initiate shutdown.
+                         */
+                        fctx_shutdown(fctx);
+                }
+       }
+       return (bucket_empty);
+}
+
 static void
 resume_dslookup(isc_task_t *task, isc_event_t *event) {
        dns_fetchevent_t *fevent;
        dns_resolver_t *res;
        fetchctx_t *fctx;
        isc_result_t result;
-       isc_boolean_t bucket_empty = ISC_FALSE;
+       isc_boolean_t bucket_empty;
        isc_boolean_t locked = ISC_FALSE;
        unsigned int bucketnum;
        dns_rdataset_t nameservers;
@@ -6269,9 +6296,7 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) {
        isc_event_free(&event);
        if (!locked)
                LOCK(&res->buckets[bucketnum].lock);
-       fctx->references--;
-       if (fctx->references == 0)
-               bucket_empty = fctx_destroy(fctx);
+       bucket_empty = fctx_decreference(fctx);
        UNLOCK(&res->buckets[bucketnum].lock);
        if (bucket_empty)
                empty_bucket(res);
@@ -7158,12 +7183,14 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
                                                  &fctx->nsfetch);
                if (result != ISC_R_SUCCESS)
                        fctx_done(fctx, result, __LINE__);
-               LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
-               fctx->references++;
-               UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
-               result = fctx_stopidletimer(fctx);
-               if (result != ISC_R_SUCCESS)
-                       fctx_done(fctx, result, __LINE__);
+               else {
+                       LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
+                       fctx->references++;
+                       UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
+                       result = fctx_stopidletimer(fctx);
+                       if (result != ISC_R_SUCCESS)
+                               fctx_done(fctx, result, __LINE__);
+               }
        } else {
                /*
                 * We're done.
@@ -8010,7 +8037,7 @@ dns_resolver_destroyfetch(dns_fetch_t **fetchp) {
        dns_fetchevent_t *event, *next_event;
        fetchctx_t *fctx;
        unsigned int bucketnum;
-       isc_boolean_t bucket_empty = ISC_FALSE;
+       isc_boolean_t bucket_empty;
 
        REQUIRE(fetchp != NULL);
        fetch = *fetchp;
@@ -8038,27 +8065,7 @@ dns_resolver_destroyfetch(dns_fetch_t **fetchp) {
                }
        }
 
-       INSIST(fctx->references > 0);
-       fctx->references--;
-       if (fctx->references == 0) {
-               /*
-                * No one cares about the result of this fetch anymore.
-                */
-               if (fctx->pending == 0 && fctx->nqueries == 0 &&
-                   ISC_LIST_EMPTY(fctx->validators) &&
-                   SHUTTINGDOWN(fctx)) {
-                       /*
-                        * This fctx is already shutdown; we were just
-                        * waiting for the last reference to go away.
-                        */
-                       bucket_empty = fctx_destroy(fctx);
-               } else {
-                       /*
-                        * Initiate shutdown.
-                        */
-                       fctx_shutdown(fctx);
-               }
-       }
+       bucket_empty = fctx_decreference(fctx);
 
        UNLOCK(&res->buckets[bucketnum].lock);