diff --git a/CHANGES b/CHANGES index a8219d205e..e0165f47c5 100644 --- a/CHANGES +++ b/CHANGES @@ -5,7 +5,9 @@ multiple dnssec-lookaside namespaces (not yet implemented). -1647. [placeholder] rt11445 +1647. [bug] It was possible trigger a INSIST when chasing a DS + record that required walking back over a empty node. + [RT #11445] 1646. [bug] win32: logging file versions didn't work with non-UNC filenames. [RT#11486] @@ -125,7 +127,6 @@ 1605. [func] New dns_db_find() option DNS_DBFIND_COVERINGNSEC. - 1604. [bug] A xfrout_ctx_create() failure would result in xfrout_ctx_destroy() being called with a partially initaliased structure. diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 7f89953253..c35b15348b 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.288 2004/05/14 04:45:56 marka Exp $ */ +/* $Id: resolver.c,v 1.289 2004/06/07 03:28:55 marka Exp $ */ #include @@ -4716,6 +4716,9 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { isc_boolean_t bucket_empty = ISC_FALSE; isc_boolean_t locked = ISC_FALSE; unsigned int bucketnum; + dns_rdataset_t nameservers; + dns_fixedname_t fixed; + dns_name_t *domain; REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); fevent = (dns_fetchevent_t *)event; @@ -4731,15 +4734,17 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { if (fevent->db != NULL) dns_db_detach(&fevent->db); - dns_resolver_destroyfetch(&fctx->nsfetch); + dns_rdataset_init(&nameservers); bucketnum = fctx->bucketnum; - if (fevent->result == ISC_R_CANCELED) + if (fevent->result == ISC_R_CANCELED) { + dns_resolver_destroyfetch(&fctx->nsfetch); fctx_done(fctx, ISC_R_CANCELED); - else if (fevent->result == ISC_R_SUCCESS) { + } else if (fevent->result == ISC_R_SUCCESS) { FCTXTRACE("resuming DS lookup"); + dns_resolver_destroyfetch(&fctx->nsfetch); if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); dns_rdataset_clone(fevent->rdataset, &fctx->nameservers); @@ -4758,22 +4763,29 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { } else { unsigned int n; + /* + * Retrieve state from fctx->nsfetch before we destroy it. + */ + dns_fixedname_init(&fixed); + domain = dns_fixedname_name(&fixed); + dns_name_copy(&fctx->nsfetch->private->domain, domain, NULL); + dns_rdataset_clone(&fctx->nsfetch->private->nameservers, + &nameservers); + dns_resolver_destroyfetch(&fctx->nsfetch); + if (dns_name_equal(&fctx->nsname, domain)) { + fctx_done(fctx, DNS_R_SERVFAIL); + goto cleanup; + } n = dns_name_countlabels(&fctx->nsname); dns_name_getlabelsequence(&fctx->nsname, 1, n - 1, &fctx->nsname); - if (dns_name_equal(&fctx->nsname, &fctx->domain)) { - fctx_done(fctx, DNS_R_SERVFAIL); - goto cleanup; - } if (dns_rdataset_isassociated(fevent->rdataset)) dns_rdataset_disassociate(fevent->rdataset); FCTXTRACE("continuing to look for parent's NS records"); result = dns_resolver_createfetch(fctx->res, &fctx->nsname, - dns_rdatatype_ns, - &fctx->domain, - &fctx->nameservers, NULL, - 0, task, + dns_rdatatype_ns, domain, + &nameservers, NULL, 0, task, resume_dslookup, fctx, &fctx->nsrrset, NULL, &fctx->nsfetch); @@ -4787,6 +4799,8 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { } cleanup: + if (dns_rdataset_isassociated(&nameservers)) + dns_rdataset_disassociate(&nameservers); if (dns_rdataset_isassociated(fevent->rdataset)) dns_rdataset_disassociate(fevent->rdataset); INSIST(fevent->sigrdataset == NULL);