From: Matthijs Mekking Date: Mon, 27 Oct 2025 16:04:56 +0000 (+0100) Subject: Update dns_dnssec_sync(update|delete) return code X-Git-Tag: v9.21.17~21^2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1b2646f2b667563980d374f7f49b09b0aed5b62;p=thirdparty%2Fbind9.git Update dns_dnssec_sync(update|delete) return code Update the functions 'dns_dnssec_syncupdate()' and 'dns_dnssec_syncdelete()' to make a distinction between a changed RRset and no changes made. The return code will be used later to determine if we need to send a NOTIFY(CDS) to DSYNC endpoints. --- diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index 2874341be0d..c5be6eda9ab 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -1825,8 +1825,9 @@ add_cds(dns_dnsseckey_t *key, dns_rdata_t *keyrdata, const char *keystr, "CDS (%s) for key %s is now published", algbuf, keystr); addrdata(&cdsrdata, diff, origin, ttl, mctx); + return ISC_R_SUCCESS; } - return ISC_R_SUCCESS; + return DNS_R_UNCHANGED; } static isc_result_t @@ -1850,8 +1851,9 @@ delete_cds(dns_dnsseckey_t *key, dns_rdata_t *keyrdata, const char *keystr, "CDS (%s) for key %s is now deleted", algbuf, keystr); delrdata(&cdsrdata, diff, origin, cds->ttl, mctx); + return ISC_R_SUCCESS; } - return ISC_R_SUCCESS; + return DNS_R_UNCHANGED; } isc_result_t @@ -1861,9 +1863,10 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, bool gencdnskey, dns_ttl_t ttl, dns_diff_t *diff, isc_mem_t *mctx) { unsigned char keybuf[DST_KEY_MAXSIZE]; - isc_result_t result; + isc_result_t result = DNS_R_UNCHANGED; dns_ttl_t cdsttl = ttl; dns_ttl_t cdnskeyttl = ttl; + bool changed = false; REQUIRE(digests != NULL); REQUIRE(keys != NULL); @@ -1890,9 +1893,15 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, dst_key_format(key->key, keystr, sizeof(keystr)); ISC_LIST_FOREACH(*digests, alg, link) { - CHECK(add_cds(key, &cdnskeyrdata, - (const char *)keystr, cds, - alg->digest, cdsttl, diff, mctx)); + result = add_cds(key, &cdnskeyrdata, + (const char *)keystr, cds, + alg->digest, cdsttl, diff, + mctx); + if (result == ISC_R_SUCCESS) { + changed = true; + } else if (result != DNS_R_UNCHANGED) { + goto cleanup; + } } if (gencdnskey && @@ -1906,6 +1915,7 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, keystr); addrdata(&cdnskeyrdata, diff, origin, cdnskeyttl, mctx); + changed = true; } } @@ -1915,15 +1925,32 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, if (dns_rdataset_isassociated(cds)) { /* Delete all possible CDS records */ - delete_cds(key, &cdnskeyrdata, - (const char *)keystr, cds, - DNS_DSDIGEST_SHA1, diff, mctx); - delete_cds(key, &cdnskeyrdata, - (const char *)keystr, cds, - DNS_DSDIGEST_SHA256, diff, mctx); - delete_cds(key, &cdnskeyrdata, - (const char *)keystr, cds, - DNS_DSDIGEST_SHA384, diff, mctx); + for (dns_dsdigest_t digest = DNS_DSDIGEST_SHA1; + digest < DNS_DSDIGEST_TOTAL; digest++) + { + result = delete_cds( + key, &cdnskeyrdata, + (const char *)keystr, cds, + digest, diff, mctx); + + switch (result) { + case ISC_R_SUCCESS: + changed = true; + break; + case DNS_R_UNCHANGED: + case ISC_R_NOTIMPLEMENTED: + /* + * Either the digest is not + * supported and we cannot + * construct the CDS for it, or + * the CDS with this digest is + * not present in the CDS RRset. + */ + break; + default: + goto cleanup; + } + } } if (dns_rdataset_isassociated(cdnskey)) { @@ -1936,6 +1963,7 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, keystr); delrdata(&cdnskeyrdata, diff, origin, cdnskey->ttl, mctx); + changed = true; } } } @@ -1944,7 +1972,10 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, if (!dns_rdataset_isassociated(cds) && !dns_rdataset_isassociated(cdnskey)) { - return ISC_R_SUCCESS; + if (changed) { + return ISC_R_SUCCESS; + } + return DNS_R_UNCHANGED; } /* @@ -1961,12 +1992,30 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, &cdnskeyrdata)); if (dns_rdataset_isassociated(cds)) { - delete_cds(key, &cdnskeyrdata, (const char *)keystr, - cds, DNS_DSDIGEST_SHA1, diff, mctx); - delete_cds(key, &cdnskeyrdata, (const char *)keystr, - cds, DNS_DSDIGEST_SHA256, diff, mctx); - delete_cds(key, &cdnskeyrdata, (const char *)keystr, - cds, DNS_DSDIGEST_SHA384, diff, mctx); + for (dns_dsdigest_t digest = DNS_DSDIGEST_SHA1; + digest < DNS_DSDIGEST_TOTAL; digest++) + { + result = delete_cds(key, &cdnskeyrdata, + (const char *)keystr, cds, + digest, diff, mctx); + switch (result) { + case ISC_R_SUCCESS: + changed = true; + break; + case DNS_R_UNCHANGED: + case ISC_R_NOTIMPLEMENTED: + /* + * Either the digest is not + * supported and we cannot + * construct the CDS for it, or + * the CDS with this digest is + * not present in the CDS RRset. + */ + break; + default: + goto cleanup; + } + } } if (dns_rdataset_isassociated(cdnskey)) { @@ -1978,11 +2027,15 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, keystr); delrdata(&cdnskeyrdata, diff, origin, cdnskey->ttl, mctx); + changed = true; } } } - result = ISC_R_SUCCESS; + if (changed) { + return ISC_R_SUCCESS; + } + return DNS_R_UNCHANGED; cleanup: return result; @@ -1999,6 +2052,7 @@ dns_dnssec_syncdelete(dns_rdataset_t *cds, dns_rdataset_t *cdnskey, dns_rdata_t cds_delete = DNS_RDATA_INIT; dns_rdata_t cdnskey_delete = DNS_RDATA_INIT; isc_region_t r; + bool changed = false; r.base = keybuf; r.length = sizeof(keybuf); @@ -2021,6 +2075,7 @@ dns_dnssec_syncdelete(dns_rdataset_t *cds, dns_rdataset_t *cdnskey, "published", namebuf); addrdata(&cds_delete, diff, origin, ttl, mctx); + changed = true; } } else { if (dns_rdataset_isassociated(cds) && exists(cds, &cds_delete)) @@ -2031,6 +2086,7 @@ dns_dnssec_syncdelete(dns_rdataset_t *cds, dns_rdataset_t *cdnskey, "deleted", namebuf); delrdata(&cds_delete, diff, origin, cds->ttl, mctx); + changed = true; } } @@ -2044,6 +2100,7 @@ dns_dnssec_syncdelete(dns_rdataset_t *cds, dns_rdataset_t *cdnskey, "published", namebuf); addrdata(&cdnskey_delete, diff, origin, ttl, mctx); + changed = true; } } else { if (dns_rdataset_isassociated(cdnskey) && @@ -2056,10 +2113,14 @@ dns_dnssec_syncdelete(dns_rdataset_t *cds, dns_rdataset_t *cdnskey, namebuf); delrdata(&cdnskey_delete, diff, origin, cdnskey->ttl, mctx); + changed = true; } } - return ISC_R_SUCCESS; + if (changed) { + return ISC_R_SUCCESS; + } + return DNS_R_UNCHANGED; } /* diff --git a/lib/dns/include/dns/dnssec.h b/lib/dns/include/dns/dnssec.h index eed02b00da5..14f9e468ae4 100644 --- a/lib/dns/include/dns/dnssec.h +++ b/lib/dns/include/dns/dnssec.h @@ -403,6 +403,7 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, * * Returns: *\li ISC_R_SUCCESS + *\li DNS_R_UNCHANGED - if the CDS and CDNSKEY sets have not changed *\li Other values indicate error */ @@ -421,6 +422,7 @@ dns_dnssec_syncdelete(dns_rdataset_t *cds, dns_rdataset_t *cdnskey, * * Returns: *\li ISC_R_SUCCESS + *\li DNS_R_UNCHANGED - if the CDS and CDNSKEY sets have not changed *\li Other values indicate error */ diff --git a/lib/dns/include/dns/ds.h b/lib/dns/include/dns/ds.h index 9f1e7938de9..edad308ea10 100644 --- a/lib/dns/include/dns/ds.h +++ b/lib/dns/include/dns/ds.h @@ -31,6 +31,9 @@ #define DNS_DSDIGEST_SHA256PRIVATE (7) #define DNS_DSDIGEST_SHA384PRIVATE (8) #define DNS_DSDIGEST_SM3PRIVATE (9) +#define DNS_DSDIGEST_TOTAL (10) +#else +#define DNS_DSDIGEST_TOTAL (7) #endif #define DNS_DSDIGEST_MAX (255) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 64658232af4..0aeaed0b05c 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -21624,7 +21624,10 @@ zone_rekey(dns_zone_t *zone) { result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset, &cdnskeyset, now, &digests, cdnskeypub, ttl, &diff, mctx); - if (result != ISC_R_SUCCESS) { + if (result == ISC_R_SUCCESS) { + dnssec_log(zone, ISC_LOG_DEBUG(3), + "zone_rekey:CDS/CDNSKEY updated"); + } else if (result != DNS_R_UNCHANGED) { dnssec_log(zone, ISC_LOG_ERROR, "zone_rekey:couldn't update CDS/CDNSKEY: %s", isc_result_totext(result)); @@ -21660,7 +21663,10 @@ zone_rekey(dns_zone_t *zone) { result = dns_dnssec_syncdelete( &cdsset, &cdnskeyset, &zone->origin, zone->rdclass, ttl, &diff, mctx, cdsdel, cdnskeydel); - if (result != ISC_R_SUCCESS) { + if (result == ISC_R_SUCCESS) { + dnssec_log(zone, ISC_LOG_DEBUG(3), + "zone_rekey:CDS/CDNSKEY updated (DELETE)"); + } else if (result != DNS_R_UNCHANGED) { dnssec_log(zone, ISC_LOG_ERROR, "zone_rekey:couldn't update CDS/CDNSKEY " "DELETE records: %s",