2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

2921. [bug] The resolver could attempt to destroy a fetch context

to soon.  [RT #19878]
This commit is contained in:
Mark Andrews
2010-06-23 01:31:43 +00:00
parent 945b6a3ae4
commit 4a8dc5f8ef
2 changed files with 43 additions and 33 deletions

View File

@@ -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 2920. [func] Allow 'filter-aaaa-on-v4' to be applied selectively
to IPv4 clients. New acl 'filter-aaaa' (default any). to IPv4 clients. New acl 'filter-aaaa' (default any).

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: resolver.c,v 1.421 2010/04/20 23:51:12 tbox Exp $ */ /* $Id: resolver.c,v 1.422 2010/06/23 01:31:43 marka Exp $ */
/*! \file */ /*! \file */
@@ -6159,13 +6159,40 @@ answer_response(fetchctx_t *fctx) {
return (result); 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 static void
resume_dslookup(isc_task_t *task, isc_event_t *event) { resume_dslookup(isc_task_t *task, isc_event_t *event) {
dns_fetchevent_t *fevent; dns_fetchevent_t *fevent;
dns_resolver_t *res; dns_resolver_t *res;
fetchctx_t *fctx; fetchctx_t *fctx;
isc_result_t result; isc_result_t result;
isc_boolean_t bucket_empty = ISC_FALSE; isc_boolean_t bucket_empty;
isc_boolean_t locked = ISC_FALSE; isc_boolean_t locked = ISC_FALSE;
unsigned int bucketnum; unsigned int bucketnum;
dns_rdataset_t nameservers; dns_rdataset_t nameservers;
@@ -6269,9 +6296,7 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event); isc_event_free(&event);
if (!locked) if (!locked)
LOCK(&res->buckets[bucketnum].lock); LOCK(&res->buckets[bucketnum].lock);
fctx->references--; bucket_empty = fctx_decreference(fctx);
if (fctx->references == 0)
bucket_empty = fctx_destroy(fctx);
UNLOCK(&res->buckets[bucketnum].lock); UNLOCK(&res->buckets[bucketnum].lock);
if (bucket_empty) if (bucket_empty)
empty_bucket(res); empty_bucket(res);
@@ -7158,12 +7183,14 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
&fctx->nsfetch); &fctx->nsfetch);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
fctx_done(fctx, result, __LINE__); fctx_done(fctx, result, __LINE__);
LOCK(&fctx->res->buckets[fctx->bucketnum].lock); else {
fctx->references++; LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); fctx->references++;
result = fctx_stopidletimer(fctx); UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
if (result != ISC_R_SUCCESS) result = fctx_stopidletimer(fctx);
fctx_done(fctx, result, __LINE__); if (result != ISC_R_SUCCESS)
fctx_done(fctx, result, __LINE__);
}
} else { } else {
/* /*
* We're done. * We're done.
@@ -8010,7 +8037,7 @@ dns_resolver_destroyfetch(dns_fetch_t **fetchp) {
dns_fetchevent_t *event, *next_event; dns_fetchevent_t *event, *next_event;
fetchctx_t *fctx; fetchctx_t *fctx;
unsigned int bucketnum; unsigned int bucketnum;
isc_boolean_t bucket_empty = ISC_FALSE; isc_boolean_t bucket_empty;
REQUIRE(fetchp != NULL); REQUIRE(fetchp != NULL);
fetch = *fetchp; fetch = *fetchp;
@@ -8038,27 +8065,7 @@ dns_resolver_destroyfetch(dns_fetch_t **fetchp) {
} }
} }
INSIST(fctx->references > 0); bucket_empty = fctx_decreference(fctx);
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);
}
}
UNLOCK(&res->buckets[bucketnum].lock); UNLOCK(&res->buckets[bucketnum].lock);