]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Re-fetch pending records that failed validation
authorMark Andrews <marka@isc.org>
Fri, 20 Dec 2024 09:24:05 +0000 (20:24 +1100)
committerEvan Hunt <each@isc.org>
Tue, 18 Feb 2025 23:59:10 +0000 (23:59 +0000)
If a deferred validation on data that was originally queried with
CD=1 fails, we now repeat the query, since the zone data may have
changed in the meantime.

(cherry picked from commit 04b1484ed8308baede372e642d1ed7c05c523a94)

bin/tests/system/dnssec/tests.sh
lib/dns/validator.c

index 9f29018c0625db27be836a1212f79c366068f346..061a27262a7f24647959f4a1b2e9621ee765c63b 100644 (file)
@@ -196,9 +196,6 @@ cp ns2/dnskey-rrsigs-stripped.db.next ns2/dnskey-rrsigs-stripped.db.signed
 nextpart ns2/named.run >/dev/null
 rndccmd 10.53.0.2 reload dnskey-rrsigs-stripped | sed 's/^/ns2 /' | cat_i
 wait_for_log 5 "zone dnskey-rrsigs-stripped/IN: loaded serial 2000042408" ns2/named.run || ret=1
-# make a query that flushes the unsigned DNSKEY RRset
-dig_with_opts +noauth a.dnskey-rrsigs-stripped. @10.53.0.4 a >dig.out.ns4.test$n || ret=1
-# make a second query that should now validate
 dig_with_opts +noauth b.dnskey-rrsigs-stripped. @10.53.0.2 a >dig.out.ns2.test$n || ret=1
 dig_with_opts +noauth b.dnskey-rrsigs-stripped. @10.53.0.4 a >dig.out.ns4.test$n || ret=1
 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
@@ -219,9 +216,6 @@ cp ns2/ds-rrsigs-stripped.db.next ns2/ds-rrsigs-stripped.db.signed
 nextpart ns2/named.run >/dev/null
 rndccmd 10.53.0.2 reload ds-rrsigs-stripped | sed 's/^/ns2 /' | cat_i
 wait_for_log 5 "zone ds-rrsigs-stripped/IN: loaded serial 2000042408" ns2/named.run || ret=1
-# make a query that flushes the unsigned DS RRset
-dig_with_opts +noauth a.child.ds-rrsigs-stripped. @10.53.0.4 a >dig.out.ns4.test$n || ret=1
-# make a second query that should now validate
 dig_with_opts +noauth b.child.ds-rrsigs-stripped. @10.53.0.2 a >dig.out.ns2.test$n || ret=1
 dig_with_opts +noauth b.child.ds-rrsigs-stripped. @10.53.0.4 a >dig.out.ns4.test$n || ret=1
 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
index 1313c9f8540a9dec1e144672683beeddb273b4b7..b76f1c53a3b038d2a8b7d1dadb66ec83cea65dc7 100644 (file)
@@ -137,6 +137,10 @@ validator_logcreate(dns_validator_t *val, dns_name_t *name,
                    dns_rdatatype_t type, const char *caller,
                    const char *operation);
 
+static isc_result_t
+create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
+            isc_taskaction_t callback, const char *caller);
+
 /*%
  * Ensure the validator's rdatasets are marked as expired.
  */
@@ -641,7 +645,6 @@ validator_callback_dnskey(isc_task_t *task, isc_event_t *event) {
        dns_validator_t *val;
        bool want_destroy;
        isc_result_t result;
-       isc_result_t eresult;
        isc_result_t saved_result;
 
        UNUSED(task);
@@ -649,7 +652,7 @@ validator_callback_dnskey(isc_task_t *task, isc_event_t *event) {
 
        devent = (dns_validatorevent_t *)event;
        val = devent->ev_arg;
-       eresult = devent->result;
+       result = devent->result;
 
        isc_event_free(&event);
        dns_validator_destroy(&val->subvalidator);
@@ -659,8 +662,8 @@ validator_callback_dnskey(isc_task_t *task, isc_event_t *event) {
        validator_log(val, ISC_LOG_DEBUG(3), "in validator_callback_dnskey");
        LOCK(&val->lock);
        if (CANCELED(val)) {
-               validator_done(val, ISC_R_CANCELED);
-       } else if (eresult == ISC_R_SUCCESS) {
+               result = ISC_R_CANCELED;
+       } else if (result == ISC_R_SUCCESS) {
                validator_log(val, ISC_LOG_DEBUG(3), "keyset with trust %s",
                              dns_trust_totext(val->frdataset.trust));
                /*
@@ -681,17 +684,23 @@ validator_callback_dnskey(isc_task_t *task, isc_event_t *event) {
                                result = saved_result;
                        }
                }
-               if (result != DNS_R_WAIT) {
-                       validator_done(val, result);
-               }
        } else {
-               if (eresult != DNS_R_BROKENCHAIN) {
-                       expire_rdatasets(val);
-               }
                validator_log(val, ISC_LOG_DEBUG(3),
                              "validator_callback_dnskey: got %s",
-                             isc_result_totext(eresult));
-               validator_done(val, DNS_R_BROKENCHAIN);
+                             isc_result_totext(result));
+               if (result != DNS_R_BROKENCHAIN) {
+                       expire_rdatasets(val);
+                       result = create_fetch(val, &val->siginfo->signer,
+                                             dns_rdatatype_dnskey,
+                                             fetch_callback_dnskey,
+                                             "validator_callback_dnskey");
+                       if (result == ISC_R_SUCCESS) {
+                               result = DNS_R_WAIT;
+                       }
+               }
+       }
+       if (result != DNS_R_WAIT) {
+               validator_done(val, result);
        }
 
        want_destroy = exit_check(val);
@@ -712,14 +721,13 @@ validator_callback_ds(isc_task_t *task, isc_event_t *event) {
        dns_validator_t *val;
        bool want_destroy;
        isc_result_t result;
-       isc_result_t eresult;
 
        UNUSED(task);
        INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
 
        devent = (dns_validatorevent_t *)event;
        val = devent->ev_arg;
-       eresult = devent->result;
+       result = devent->result;
 
        isc_event_free(&event);
        dns_validator_destroy(&val->subvalidator);
@@ -729,8 +737,8 @@ validator_callback_ds(isc_task_t *task, isc_event_t *event) {
        validator_log(val, ISC_LOG_DEBUG(3), "in validator_callback_ds");
        LOCK(&val->lock);
        if (CANCELED(val)) {
-               validator_done(val, ISC_R_CANCELED);
-       } else if (eresult == ISC_R_SUCCESS) {
+               result = ISC_R_CANCELED;
+       } else if (result == ISC_R_SUCCESS) {
                bool have_dsset;
                dns_name_t *name;
                validator_log(val, ISC_LOG_DEBUG(3), "%s with trust %s",
@@ -754,17 +762,22 @@ validator_callback_ds(isc_task_t *task, isc_event_t *event) {
                } else {
                        result = validate_dnskey(val);
                }
-               if (result != DNS_R_WAIT) {
-                       validator_done(val, result);
-               }
        } else {
-               if (eresult != DNS_R_BROKENCHAIN) {
-                       expire_rdatasets(val);
-               }
                validator_log(val, ISC_LOG_DEBUG(3),
                              "validator_callback_ds: got %s",
-                             isc_result_totext(eresult));
-               validator_done(val, DNS_R_BROKENCHAIN);
+                             isc_result_totext(result));
+               if (result != DNS_R_BROKENCHAIN) {
+                       expire_rdatasets(val);
+                       result = create_fetch(
+                               val, val->event->name, dns_rdatatype_ds,
+                               fetch_callback_ds, "validator_callback_ds");
+                       if (result == ISC_R_SUCCESS) {
+                               result = DNS_R_WAIT;
+                       }
+               }
+       }
+       if (result != DNS_R_WAIT) {
+               validator_done(val, result);
        }
 
        want_destroy = exit_check(val);