diff --git a/CHANGES b/CHANGES index ddc71de48f..0cd20df58d 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] + 6337. [bug] Nsupdate could assert while shutting down. [GL #4529] 6336. [func] Expose the zones with the 'first refresh' flag set in diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh index d9f2ab6f7a..65ef9b928b 100755 --- a/bin/tests/system/resolver/tests.sh +++ b/bin/tests/system/resolver/tests.sh @@ -482,10 +482,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/rbt-cachedb.c b/lib/dns/rbt-cachedb.c index ea2ff08996..f4f3d25be6 100644 --- a/lib/dns/rbt-cachedb.c +++ b/lib/dns/rbt-cachedb.c @@ -909,13 +909,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) { /* diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 900b580058..7b2df98ca7 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -335,6 +335,30 @@ dns__rbtdb_setttl(dns_slabheader_t *header, dns_ttl_t newttl) { } } +static bool +prio_type(dns_typepair_t type) { + switch (type) { + case dns_rdatatype_soa: + case DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_soa): + case dns_rdatatype_a: + case DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_a): + case dns_rdatatype_aaaa: + case DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_aaaa): + case dns_rdatatype_nsec: + case DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec): + case dns_rdatatype_nsec3: + case DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec3): + case dns_rdatatype_ns: + case DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ns): + case dns_rdatatype_ds: + case DNS_TYPEPAIR_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ds): + case dns_rdatatype_cname: + case DNS_TYPEPAIR_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. @@ -2367,7 +2391,7 @@ dns__rbtdb_allrdatasets(dns_db_t *db, dns_dbnode_t *node, static bool cname_and_other_data(dns_rbtnode_t *node, uint32_t serial) { dns_slabheader_t *header = NULL, *header_next = NULL; - bool cname, other_data; + bool cname = false, other_data = false; dns_rdatatype_t rdtype; /* @@ -2377,10 +2401,16 @@ cname_and_other_data(dns_rbtnode_t *node, uint32_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. @@ -2440,10 +2470,9 @@ cname_and_other_data(dns_rbtnode_t *node, uint32_t serial) { } } } - } - - if (cname && other_data) { - return (true); + if (cname && other_data) { + return (true); + } } return (false); @@ -2482,6 +2511,7 @@ dns__rbtdb_add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_changed_t *changed = NULL; dns_slabheader_t *topheader = NULL, *topheader_prev = NULL; dns_slabheader_t *header = NULL, *sigheader = NULL; + dns_slabheader_t *prioheader = NULL; unsigned char *merged = NULL; isc_result_t result; bool header_nx; @@ -2615,6 +2645,9 @@ dns__rbtdb_add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, for (topheader = rbtnode->data; topheader != NULL; topheader = topheader->next) { + if (prio_type(topheader->type)) { + prioheader = topheader; + } if (topheader->type == newheader->type || topheader->type == negtype) { @@ -2999,9 +3032,21 @@ find_header: /* * No rdatasets of the given type exist at the node. */ - newheader->next = rbtnode->data; - newheader->down = NULL; - rbtnode->data = newheader; + INSIST(newheader->down == NULL); + + 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; + } } } diff --git a/tests/bench/load-names.c b/tests/bench/load-names.c index f4562aa6db..bf41222311 100644 --- a/tests/bench/load-names.c +++ b/tests/bench/load-names.c @@ -374,7 +374,7 @@ add_qp(void *qp, size_t count) { static void sqz_qp(void *qp) { - dns_qp_compact(qp, DNS_QPGC_ALL); + dns_qp_compact(qp, DNS_QPGC_MAYBE); } static isc_result_t