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 04b1484ed8)
This commit is contained in:
Mark Andrews 2024-12-20 20:24:05 +11:00 committed by Evan Hunt
parent 48b32e64c4
commit 86e65f317a
2 changed files with 37 additions and 30 deletions

View 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

View 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);