]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Support for the cd (checking disabled) bit. Also remove data from the
authorBrian Wellington <source@isc.org>
Tue, 25 Jul 2000 22:03:25 +0000 (22:03 +0000)
committerBrian Wellington <source@isc.org>
Tue, 25 Jul 2000 22:03:25 +0000 (22:03 +0000)
cache if validation fails.

lib/dns/resolver.c

index a1bff420a79840b2032cb18a164b7713dd950bc4..7bb1df8b371ed1cbb6a2d6717b6f26dd69a43d05 100644 (file)
@@ -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 <config.h>
 
@@ -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) {