From d228dc63c1f168d5250ad88d6ae4cdc0e2b85ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Tue, 6 Feb 2024 14:05:08 +0100 Subject: [PATCH 1/4] Fix missing RRSIG for CNAME with different slabheader order The cachedb was missing piece of code (already found in zonedb) that would make lookups in the slabheaders to miss the RRSIGs for CNAME if the order of CNAME and RRSIG(CNAME) was reversed in the node->data. (cherry picked from commit 5070c7f5c74a143f74775515d65fad01f398ecd1) --- lib/dns/rbtdb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 7793be859e..13b8574104 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -5086,13 +5086,18 @@ cache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, */ found = header; if (header->type == dns_rdatatype_cname && - cname_ok && cnamesig != NULL) + cname_ok) { /* * If we've already got the * CNAME RRSIG, use it. */ - foundsig = cnamesig; + if (cnamesig != NULL) { + foundsig = cnamesig; + } else { + sigtype = + RBTDB_RDATATYPE_SIGCNAME; + } } } else if (header->type == sigtype) { /* From 6557abc8bc995bba14f0d0a92bd149b295b3addd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Mon, 29 Jan 2024 16:36:30 +0100 Subject: [PATCH 2/4] Optimize the slabheader placement for certain RRTypes Mark the infrastructure RRTypes as "priority" types and place them at the beginning of the rdataslab header data graph. The non-priority types either go right after the priority types (if any). (cherry picked from commit 3ac482be7fd058d284e89873021339579fad0615) --- lib/dns/rbtdb.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 13b8574104..9746401b20 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -906,6 +906,30 @@ set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) { } } +static bool +prio_type(rbtdb_rdatatype_t type) { + switch (type) { + case dns_rdatatype_soa: + case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_soa): + case dns_rdatatype_a: + case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_a): + case dns_rdatatype_aaaa: + case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_aaaa): + case dns_rdatatype_nsec: + case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec): + case dns_rdatatype_nsec3: + case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec3): + case dns_rdatatype_ns: + case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ns): + case dns_rdatatype_ds: + case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ds): + case dns_rdatatype_cname: + case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_cname): + return (true); + } + return (false); +} + /*% * These functions allow the heap code to rank the priority of each * element. It returns true if v1 happens "sooner" than v2. @@ -6172,6 +6196,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename, rbtdb_changed_t *changed = NULL; rdatasetheader_t *topheader = NULL, *topheader_prev = NULL; rdatasetheader_t *header = NULL, *sigheader = NULL; + rdatasetheader_t *prioheader = NULL; unsigned char *merged = NULL; isc_result_t result; bool header_nx; @@ -6318,6 +6343,9 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename, for (topheader = rbtnode->data; topheader != NULL; topheader = topheader->next) { + if (prio_type(topheader->type)) { + prioheader = topheader; + } if (topheader->type == newheader->type || topheader->type == negtype) { @@ -6684,9 +6712,21 @@ find_header: /* * No rdatasets of the given type exist at the node. */ - newheader->next = rbtnode->data; newheader->down = NULL; - rbtnode->data = newheader; + + if (prio_type(newheader->type)) { + /* This is a priority type, prepend it */ + newheader->next = rbtnode->data; + rbtnode->data = newheader; + } else if (prioheader != NULL) { + /* Append after the priority headers */ + newheader->next = prioheader->next; + prioheader->next = newheader; + } else { + /* There were no priority headers */ + newheader->next = rbtnode->data; + rbtnode->data = newheader; + } } } From d43a955d0c036073ba15de97fa622f7a1a8a6993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Mon, 29 Jan 2024 16:36:30 +0100 Subject: [PATCH 3/4] Optimize cname_and_other_data to stop as earliest as possible Stop the cname_and_other_data processing if we already know that the result is true. Also, we know that CNAME will be placed in the priority headers, so we can stop looking for CNAME if we haven't found CNAME and we are past the priority headers. (cherry picked from commit 3f774c2a8ac46b2bbf1b3a4fa1d8d8c3ed3d78a9) --- bin/tests/system/resolver/tests.sh | 4 ++-- lib/dns/rbtdb.c | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh index 1ec5f867af..f24939e1c3 100755 --- a/bin/tests/system/resolver/tests.sh +++ b/bin/tests/system/resolver/tests.sh @@ -606,10 +606,10 @@ dig_with_opts @10.53.0.5 fetchall.tld any >dig.out.2.${n} || ret=1 ttl2=$(awk '/"A" "short" "ttl"/ { print $2 }' dig.out.2.${n}) sleep 1 # check that prefetch occurred; -# note that only one record is prefetched, which is the TXT record in this case, +# note that only one record is prefetched, which is the AAAA record in this case, # because of the order of the records in the cache dig_with_opts @10.53.0.5 fetchall.tld any >dig.out.3.${n} || ret=1 -ttl3=$(awk '/"A" "short" "ttl"/ { print $2 }' dig.out.3.${n}) +ttl3=$(awk '/::1/ { print $2 }' dig.out.3.${n}) test "${ttl3:-0}" -gt "${ttl2:-1}" || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 9746401b20..5eb553ddc1 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -6048,7 +6048,7 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, static bool cname_and_other_data(dns_rbtnode_t *node, rbtdb_serial_t serial) { rdatasetheader_t *header, *header_next; - bool cname, other_data; + bool cname = false, other_data = false; dns_rdatatype_t rdtype; /* @@ -6058,10 +6058,16 @@ cname_and_other_data(dns_rbtnode_t *node, rbtdb_serial_t serial) { /* * Look for CNAME and "other data" rdatasets active in our version. */ - cname = false; - other_data = false; for (header = node->data; header != NULL; header = header_next) { header_next = header->next; + if (!prio_type(header->type)) { + /* + * CNAME is in the priority list, so if we are done + * with the priority list, we know there will not be + * CNAME, so we are safe to skip the rest of the types. + */ + return (false); + } if (header->type == dns_rdatatype_cname) { /* * Look for an active extant CNAME. @@ -6121,10 +6127,9 @@ cname_and_other_data(dns_rbtnode_t *node, rbtdb_serial_t serial) { } } } - } - - if (cname && other_data) { - return (true); + if (cname && other_data) { + return (true); + } } return (false); From 29aa9723146780d382841f3409c5e7534692a120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Tue, 6 Feb 2024 18:05:41 +0100 Subject: [PATCH 4/4] Add CHANGES note for [GL !8675] (cherry picked from commit 6e81717cffe650216ce1bd17f2fe1713690661d6) --- CHANGES | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 85e06f518e..215d1d7182 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +6338. [func] Optimize slabheader placement, so the infrastructure + records are put in the beginning of the slabheader + linked list. [GL !8675] + 6334. [doc] Improve ARM parental-agents definition. [GL #4531] 6333. [bug] Fix the DNS_GETDB_STALEFIRST flag, which was defined