diff --git a/CHANGES b/CHANGES index f89272006a..a0eefdb903 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ + 734. [bug] An attempt to re-lock the zone lock could occur if + the zone was shutdown during a zone tranfer. [RT #830] 733. [bug] Reference counts of dns_acl_t objects need to be locked but were not. [RT #801] diff --git a/lib/dns/include/dns/xfrin.h b/lib/dns/include/dns/xfrin.h index 43367cbdcd..2751acf79f 100644 --- a/lib/dns/include/dns/xfrin.h +++ b/lib/dns/include/dns/xfrin.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrin.h,v 1.17 2001/01/09 21:53:41 bwelling Exp $ */ +/* $Id: xfrin.h,v 1.18 2001/02/09 06:04:55 marka Exp $ */ #ifndef DNS_XFRIN_H #define DNS_XFRIN_H 1 @@ -85,9 +85,13 @@ void dns_xfrin_detach(dns_xfrin_ctx_t **xfrp); /* * Detach a reference to a zone transfer object. - * - * (Because there is no attach() method, there can currently - * only be one reference). + * Caller to maintain external locking if required. + */ + +void +dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target); +/* + * Caller to maintain external locking if required. */ ISC_LANG_ENDDECLS diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index b6a2ad6903..3ac7f4cad2 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrin.c,v 1.113 2001/01/17 03:02:01 bwelling Exp $ */ +/* $Id: xfrin.c,v 1.114 2001/02/09 06:04:51 marka Exp $ */ #include @@ -586,6 +586,13 @@ dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) { xfrin_fail(xfr, ISC_R_CANCELED, "shut down"); } +void +dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) { + REQUIRE(target != NULL && *target == NULL); + source->refcount++; + *target = source; +} + void dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) { dns_xfrin_ctx_t *xfr = *xfrp; diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 4997b994ff..3efae86b13 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.303 2001/02/01 21:29:37 marka Exp $ */ +/* $Id: zone.c,v 1.304 2001/02/09 06:04:53 marka Exp $ */ #include @@ -3604,6 +3604,7 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { dns_zone_t *zone = (dns_zone_t *) event->ev_arg; isc_result_t result; isc_boolean_t free_needed; + dns_xfrin_ctx_t *xfr = NULL; UNUSED(task); REQUIRE(DNS_ZONE_VALID(zone)); @@ -3636,7 +3637,7 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { LOCK_ZONE(zone); if (zone->xfr != NULL) - dns_xfrin_shutdown(zone->xfr); + dns_xfrin_attach(zone->xfr, &xfr); if (zone->request != NULL) { dns_request_cancel(zone->request); @@ -3667,6 +3668,12 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); free_needed = exit_check(zone); UNLOCK_ZONE(zone); + if (xfr != NULL) { + dns_xfrin_shutdown(zone->xfr); + LOCK_ZONE(zone); + dns_xfrin_detach(&xfr); + UNLOCK_ZONE(zone); + } if (free_needed) zone_free(zone); }