From fef10e2071903d130645dfa44b443f42fca992d4 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 5 Jan 2004 08:02:17 +0000 Subject: [PATCH] 1534. [bug] Race condition when priming cache. [RT# 9940] --- CHANGES | 2 ++ lib/dns/resolver.c | 33 ++++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index b4db8b2147..4f5d97c437 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,8 @@ 1535. [bug] When parsing APL records it was possible to silently accept out of range ADDRESSFAMILY values. [RT# 9979] +1534. [bug] Race condition when priming cache. [RT# 9940] + 1532. [port] netbsd: the configure test for requires . diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 82dfcd921f..3c3bb87656 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.218.2.18.4.25 2004/01/05 05:46:03 marka Exp $ */ +/* $Id: resolver.c,v 1.218.2.18.4.26 2004/01/05 08:02:17 marka Exp $ */ #include @@ -264,6 +264,7 @@ struct dns_resolver { isc_mem_t * mctx; isc_mutex_t lock; isc_mutex_t nlock; + isc_mutex_t primelock; dns_rdataclass_t rdclass; isc_socketmgr_t * socketmgr; isc_timermgr_t * timermgr; @@ -285,6 +286,7 @@ struct dns_resolver { isc_eventlist_t whenshutdown; unsigned int activebuckets; isc_boolean_t priming; + /* Locked by primelock. */ dns_fetch_t * primefetch; /* Locked by nlock. */ unsigned int nfctx; @@ -5117,6 +5119,7 @@ destroy(dns_resolver_t *res) { INSIST(res->nfctx == 0); + DESTROYLOCK(&res->primelock); DESTROYLOCK(&res->nlock); DESTROYLOCK(&res->lock); for (i = 0; i < res->nbuckets; i++) { @@ -5265,12 +5268,19 @@ dns_resolver_create(dns_view_t *view, if (result != ISC_R_SUCCESS) goto cleanup_lock; + result = isc_mutex_init(&res->primelock); + if (result != ISC_R_SUCCESS) + goto cleanup_nlock; + res->magic = RES_MAGIC; *resp = res; return (ISC_R_SUCCESS); + cleanup_nlock: + DESTROYLOCK(&res->nlock); + cleanup_lock: DESTROYLOCK(&res->lock); @@ -5312,8 +5322,10 @@ prime_done(isc_task_t *task, isc_event_t *event) { INSIST(res->priming); res->priming = ISC_FALSE; + LOCK(&res->primelock); fetch = res->primefetch; res->primefetch = NULL; + UNLOCK(&res->primelock); UNLOCK(&res->lock); @@ -5334,7 +5346,6 @@ prime_done(isc_task_t *task, isc_event_t *event) { void dns_resolver_prime(dns_resolver_t *res) { isc_boolean_t want_priming = ISC_FALSE; - dns_fetch_t *fetch; dns_rdataset_t *rdataset; isc_result_t result; @@ -5374,21 +5385,21 @@ dns_resolver_prime(dns_resolver_t *res) { return; } dns_rdataset_init(rdataset); - fetch = NULL; + LOCK(&res->primelock); result = dns_resolver_createfetch(res, dns_rootname, dns_rdatatype_ns, NULL, NULL, NULL, 0, res->buckets[0].task, prime_done, - res, rdataset, NULL, &fetch); - LOCK(&res->lock); - INSIST(res->priming); - INSIST(res->primefetch == NULL); - if (result == ISC_R_SUCCESS) - res->primefetch = fetch; - else + res, rdataset, NULL, + &res->primefetch); + UNLOCK(&res->primelock); + if (result != ISC_R_SUCCESS) { + LOCK(&res->lock); + INSIST(res->priming); res->priming = ISC_FALSE; - UNLOCK(&res->lock); + UNLOCK(&res->lock); + } } }