2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

fix: usr: Prevent spurious SERVFAILs for certain 0-TTL resource records

Under certain circumstances, BIND 9 can return SERVFAIL when updating
existing entries in the cache with new NS, A, AAAA, or DS records with 0-TTL.

Closes #5294

Merge branch '5294-preserve-ZEROTTL-on-cache-update' into 'main'

See merge request isc-projects/bind9!10897
This commit is contained in:
Ondřej Surý 2025-08-26 21:03:43 +02:00
commit 72189af7bf

View File

@ -2734,29 +2734,22 @@ find_header:
} }
/* /*
* Don't replace existing NS, A and AAAA RRsets in the * Don't replace existing NS in the cache if they already exist
* cache if they already exist. This prevents named * and replacing the existing one would increase the TTL. This
* being locked to old servers. Don't lower trust of * prevents named being locked to old servers. Don't lower trust
* existing record if the update is forced. Nothing * of existing record if the update is forced. Nothing special
* special to be done w.r.t stale data; it gets replaced * to be done w.r.t stale data; it gets replaced normally
* normally further down. * further down.
*/ */
if (ACTIVE(header, now) && if (ACTIVE(header, now) &&
top->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) && top->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) &&
EXISTS(header) && EXISTS(newheader) && EXISTS(header) && EXISTS(newheader) &&
header->trust >= newheader->trust && header->trust >= newheader->trust &&
header->expire < newheader->expire &&
dns_rdataslab_equalx(header, newheader, dns_rdataslab_equalx(header, newheader,
qpdb->common.rdclass, qpdb->common.rdclass,
DNS_TYPEPAIR_TYPE(top->typepair))) DNS_TYPEPAIR_TYPE(top->typepair)))
{ {
/*
* Honour the new ttl if it is less than the
* older one.
*/
if (header->expire > newheader->expire) {
setttl(header, newheader->expire);
}
qpcache_hit(qpdb, header); qpcache_hit(qpdb, header);
if (header->noqname == NULL && if (header->noqname == NULL &&
@ -2790,6 +2783,11 @@ find_header:
header->trust <= newheader->trust) header->trust <= newheader->trust)
{ {
if (newheader->expire > header->expire) { if (newheader->expire > header->expire) {
if (ZEROTTL(header)) {
DNS_SLABHEADER_SETATTR(
newheader,
DNS_SLABHEADERATTR_ZEROTTL);
}
newheader->expire = header->expire; newheader->expire = header->expire;
} }
} }
@ -2801,16 +2799,9 @@ find_header:
top->typepair == DNS_SIGTYPEPAIR(dns_rdatatype_ds)) && top->typepair == DNS_SIGTYPEPAIR(dns_rdatatype_ds)) &&
EXISTS(header) && EXISTS(newheader) && EXISTS(header) && EXISTS(newheader) &&
header->trust >= newheader->trust && header->trust >= newheader->trust &&
header->expire < newheader->expire &&
dns_rdataslab_equal(header, newheader)) dns_rdataslab_equal(header, newheader))
{ {
/*
* Honour the new ttl if it is less than the
* older one.
*/
if (header->expire > newheader->expire) {
setttl(header, newheader->expire);
}
qpcache_hit(qpdb, header); qpcache_hit(qpdb, header);
if (header->noqname == NULL && if (header->noqname == NULL &&