From: Brian Wellington Date: Tue, 25 Jul 2000 22:03:25 +0000 (+0000) Subject: Support for the cd (checking disabled) bit. Also remove data from the X-Git-Tag: v9.2.0a1^10~25 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=69a761838bc6ff2271627b6e735cfc7817fdd186;p=thirdparty%2Fbind9.git Support for the cd (checking disabled) bit. Also remove data from the cache if validation fails. --- diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index a1bff420a79..7bb1df8b371 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: resolver.c,v 1.152 2000/07/24 23:55:19 gson Exp $ */ +/* $Id: resolver.c,v 1.153 2000/07/25 22:03:25 bwelling Exp $ */ #include @@ -2267,6 +2267,7 @@ validated(isc_task_t *task, isc_event_t *event) { dns_rdataset_t *asigrdataset = NULL; dns_dbnode_t *node = NULL; isc_boolean_t negative; + isc_boolean_t sentresponse; UNUSED(task); /* for now */ @@ -2289,19 +2290,23 @@ validated(isc_task_t *task, isc_event_t *event) { negative = ISC_TF(vevent->rdataset == NULL); + sentresponse = ISC_TF((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0); + /* * If shutting down, ignore the results. Check to see if we're * done waiting for validator completions and ADB pending events; if * so, destroy the fctx. */ - if (SHUTTINGDOWN(fctx)) { + if (SHUTTINGDOWN(fctx) && !sentresponse ) { maybe_destroy(fctx); goto cleanup_event; } /* - * We're not shutting down. - */ + * Either we're not shutting down, or we are shutting down but want + * to cache the result anyway (if this was a validation started by + * a query with cd set) + */ hevent = ISC_LIST_HEAD(fctx->events); if (hevent != NULL) { @@ -2320,6 +2325,22 @@ validated(isc_task_t *task, isc_event_t *event) { if (vevent->result != ISC_R_SUCCESS) { FCTXTRACE("validation failed"); + if (vevent->rdataset != NULL) { + result = dns_db_findnode(fctx->res->view->cachedb, + vevent->name, ISC_TRUE, + &node); + if (result != ISC_R_SUCCESS) + goto noanswer_response; + (void)dns_db_deleterdataset(fctx->res->view->cachedb, + node, NULL, + vevent->type, 0); + if (vevent->sigrdataset != NULL) + (void)dns_db_deleterdataset( + fctx->res->view->cachedb, + node, NULL, + dns_rdatatype_sig, + vevent->type); + } result = vevent->result; goto noanswer_response; } @@ -2381,6 +2402,17 @@ validated(isc_task_t *task, isc_event_t *event) { goto noanswer_response; } + if (sentresponse) { + /* + * If we only deferred the destroy because we wanted to cache + * the data, destroy now. + */ + if (SHUTTINGDOWN(fctx)) + maybe_destroy(fctx); + + goto cleanup_event; + } + if (fctx->validating > 0) { INSIST(!negative); INSIST(fctx->type == dns_rdatatype_any || @@ -2432,7 +2464,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) { dns_db_t **adbp; dns_name_t *aname; dns_resolver_t *res; - isc_boolean_t need_validation, have_answer; + isc_boolean_t need_validation, secure_domain, have_answer; isc_result_t result, eresult; dns_fetchevent_t *event; unsigned int options; @@ -2445,6 +2477,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) { res = fctx->res; need_validation = ISC_FALSE; + secure_domain = ISC_FALSE; have_answer = ISC_FALSE; eresult = ISC_R_SUCCESS; task = res->buckets[fctx->bucketnum].task; @@ -2453,10 +2486,15 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) { * Is DNSSEC validation required for this name? */ result = dns_keytable_issecuredomain(res->view->secroots, name, - &need_validation); + &secure_domain); if (result != ISC_R_SUCCESS) return (result); + if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0) + need_validation = ISC_FALSE; + else + need_validation = secure_domain; + adbp = NULL; aname = NULL; anodep = NULL; @@ -2509,7 +2547,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) { * If this rrset is in a secure domain, do DNSSEC validation * for it, unless it is glue. */ - if (need_validation && rdataset->trust != dns_trust_glue) { + if (secure_domain && rdataset->trust != dns_trust_glue) { /* * SIGs are validated as part of validating the * type they cover. @@ -2527,7 +2565,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) { break; } if (sigrdataset == NULL) { - if (!ANSWER(rdataset)) { + if (!ANSWER(rdataset) && need_validation) { /* * Ignore non-answer rdatasets that * are missing signatures. @@ -2552,23 +2590,34 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) { rdataset->trust = dns_trust_pending; if (sigrdataset != NULL) sigrdataset->trust = dns_trust_pending; + if (!need_validation) + addedrdataset = ardataset; + else + addedrdataset = NULL; result = dns_db_addrdataset(res->view->cachedb, node, NULL, now, - rdataset, 0, NULL); + rdataset, 0, + addedrdataset); if (result == DNS_R_UNCHANGED) result = ISC_R_SUCCESS; if (result != ISC_R_SUCCESS) break; if (sigrdataset != NULL) { + if (!need_validation) + addedrdataset = asigrdataset; + else + addedrdataset = NULL; result = dns_db_addrdataset(res->view->cachedb, node, NULL, now, sigrdataset, 0, - NULL); + addedrdataset); if (result == DNS_R_UNCHANGED) result = ISC_R_SUCCESS; if (result != ISC_R_SUCCESS) break; - } + } else + continue; + if (ANSWER(rdataset)) { if (fctx->type != dns_rdatatype_any && fctx->type != dns_rdatatype_sig) {