From 89122c3fde58a7e19c5dd34efd71a550e48ded96 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 20 Dec 2024 20:24:05 +1100 Subject: [PATCH] Re-fetch pending records that failed validation 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 | 6 ----- lib/dns/validator.c | 38 ++++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index eec5b823fa..da8e7fe36c 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -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 diff --git a/lib/dns/validator.c b/lib/dns/validator.c index b98a4bee91..4083a069ec 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -161,6 +161,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_job_cb callback, const char *caller); + /*% * Ensure the validator's rdatasets are marked as expired. */ @@ -621,13 +625,19 @@ validator_callback_dnskey(void *arg) { result = validate_async_run(val, resume_answer); } } else { - if (result != DNS_R_BROKENCHAIN) { - expire_rdatasets(val); - } validator_log(val, ISC_LOG_DEBUG(3), "validator_callback_dnskey: got %s", isc_result_totext(result)); - result = DNS_R_BROKENCHAIN; + 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; + } + } } cleanup: @@ -646,8 +656,7 @@ static void validator_callback_ds(void *arg) { dns_validator_t *subvalidator = (dns_validator_t *)arg; dns_validator_t *val = subvalidator->parent; - isc_result_t result; - isc_result_t eresult = subvalidator->result; + isc_result_t result = subvalidator->result; val->subvalidator = NULL; @@ -657,7 +666,7 @@ validator_callback_ds(void *arg) { } validator_log(val, ISC_LOG_DEBUG(3), "in validator_callback_ds"); - if (eresult == ISC_R_SUCCESS) { + if (result == ISC_R_SUCCESS) { bool have_dsset; dns_name_t *name; validator_log(val, ISC_LOG_DEBUG(3), "%s with trust %s", @@ -680,13 +689,18 @@ validator_callback_ds(void *arg) { result = validate_async_run(val, validate_dnskey); } } 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)); - result = DNS_R_BROKENCHAIN; + isc_result_totext(result)); + if (result != DNS_R_BROKENCHAIN) { + expire_rdatasets(val); + result = create_fetch(val, val->name, dns_rdatatype_ds, + fetch_callback_ds, + "validator_callback_ds"); + if (result == ISC_R_SUCCESS) { + result = DNS_R_WAIT; + } + } } cleanup: