From 6e2ca5e0d71f0db7412c9cd39c3bfea86d54867c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Mon, 11 Aug 2025 09:39:13 +0200 Subject: [PATCH] Remove the negative type logic from qpcache Previously, when a negative header was stored in the cache, it would be stored in the dns_typepair_t as .type = 0, .covers = . When searching the cache internally, we would have to look for both positive and negative typepair and the slabheader .down list could be a mix of positive and negative types. Remove the extra representation of the negative type and simply use the negative attribute on the slabheader. Other units (namely dns_ncache) can still insert the (0, type) negative rdatasets into the cache, but internally, those will be converted into (type, 0) slabheaders, and vice versa - when binding the rdatasets, the negative (type, 0) slabheader will be converted to (0, type) rdataset. Simple DNS_TYPEPAIR() helper macro was added to simplify converting single rdatatype to typepair value. As a side-effect, the search logic in all places can exit early if there's a negative header for the type we are looking for, f.e. when searching for the zone cut, we don't have to walk through all the slabheaders, if there's a stored negative slabheader. --- lib/dns/db_p.h | 2 - lib/dns/include/dns/rdatatype.h | 6 +- lib/dns/qpcache.c | 221 ++++++++++++++++++++------------ lib/dns/qpzone.c | 4 +- lib/dns/rdataslab.c | 33 +++-- 5 files changed, 163 insertions(+), 103 deletions(-) diff --git a/lib/dns/db_p.h b/lib/dns/db_p.h index 51b6943dab..142e72a2f1 100644 --- a/lib/dns/db_p.h +++ b/lib/dns/db_p.h @@ -19,8 +19,6 @@ #include #include -#define RDATATYPE_NCACHEANY DNS_TYPEPAIR_VALUE(0, dns_rdatatype_any) - #ifdef STRONG_RWLOCK_CHECK #define STRONG_RWLOCK_CHECK(cond) REQUIRE(cond) #else diff --git a/lib/dns/include/dns/rdatatype.h b/lib/dns/include/dns/rdatatype.h index d083d45f26..4d08ef1f03 100644 --- a/lib/dns/include/dns/rdatatype.h +++ b/lib/dns/include/dns/rdatatype.h @@ -49,7 +49,11 @@ DNS__TYPEPAIR_VALUE(base, covers); \ }) -#define DNS_SIGTYPE(type) DNS__TYPEPAIR_VALUE(dns_rdatatype_rrsig, type) +#define DNS_TYPEPAIR(type) DNS__TYPEPAIR_VALUE(type, dns_rdatatype_none) +#define DNS_SIGTYPE(type) DNS__TYPEPAIR_VALUE(dns_rdatatype_rrsig, type) + +constexpr dns_typepair_t dns_typepair_none = DNS_TYPEPAIR(dns_rdatatype_none); +constexpr dns_typepair_t dns_typepair_any = DNS_TYPEPAIR(dns_rdatatype_any); isc_result_t dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source); diff --git a/lib/dns/qpcache.c b/lib/dns/qpcache.c index cdfc60f7bc..1e453162d0 100644 --- a/lib/dns/qpcache.c +++ b/lib/dns/qpcache.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -845,7 +846,7 @@ update_rrsetstats(dns_stats_t *stats, const dns_typepair_t typepair, statattributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN; } else { statattributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET; - base = DNS_TYPEPAIR_COVERS(header->typepair); + base = DNS_TYPEPAIR_TYPE(header->typepair); } } else { base = DNS_TYPEPAIR_TYPE(header->typepair); @@ -1038,8 +1039,15 @@ bindrdataset(qpcache_t *qpdb, qpcnode_t *node, dns_slabheader_t *header, rdataset->methods = &dns_rdataslab_rdatasetmethods; rdataset->rdclass = qpdb->common.rdclass; - rdataset->type = DNS_TYPEPAIR_TYPE(header->typepair); - rdataset->covers = DNS_TYPEPAIR_COVERS(header->typepair); + if (NEGATIVE(header)) { + rdataset->type = dns_rdatatype_none; + rdataset->covers = DNS_TYPEPAIR_TYPE(header->typepair); + INSIST(DNS_TYPEPAIR_COVERS(header->typepair) == + dns_rdatatype_none); + } else { + rdataset->type = DNS_TYPEPAIR_TYPE(header->typepair); + rdataset->covers = DNS_TYPEPAIR_COVERS(header->typepair); + } rdataset->ttl = !ZEROTTL(header) ? header->expire - now : 0; rdataset->trust = header->trust; rdataset->resign = 0; @@ -1150,7 +1158,7 @@ setup_delegation(qpc_search_t *search, dns_dbnode_t **nodep, NODE_UNLOCK(nlock, &nlocktype); } - if (typepair == dns_rdatatype_dname) { + if (typepair == DNS_TYPEPAIR_VALUE(dns_rdatatype_dname, 0)) { return DNS_R_DNAME; } return DNS_R_DELEGATION; @@ -1222,28 +1230,39 @@ check_stale_header(dns_slabheader_t *header, qpc_search_t *search, */ static bool related_headers(dns_slabheader_t *header, dns_typepair_t typepair, - dns_typepair_t sigpair, dns_typepair_t negpair, - dns_slabheader_t **foundp, dns_slabheader_t **foundsigp, - bool *matchp) { + dns_typepair_t sigpair, dns_slabheader_t **foundp, + dns_slabheader_t **foundsigp, bool *matchp) { if (!EXISTS(header) || ANCIENT(header)) { return false; } - if (header->typepair == typepair) { + if (header->typepair == typepair && NEGATIVE(header)) { + /* + * In theory, the RRSIG(type) should not exist, but in reality, + * both the LRU and TTL based cleaning can delete one, but not + * the other. The INSIST below should be restored when we add + * a more strict synchronization between the type and its + * signature. + */ + /* INSIST(*foundsigp == NULL); */ + *foundp = header; + SET_IF_NOT_NULL(matchp, true); + return true; + } else if (header->typepair == typepair) { *foundp = header; SET_IF_NOT_NULL(matchp, true); if (*foundsigp != NULL) { return true; } } else if (header->typepair == sigpair) { + INSIST(!NEGATIVE(header)); *foundsigp = header; SET_IF_NOT_NULL(matchp, true); if (*foundp != NULL) { return true; } - } else if (negpair != 0 && (header->typepair == RDATATYPE_NCACHEANY || - header->typepair == negpair)) - { + } else if (header->typepair == dns_typepair_any) { + INSIST(NEGATIVE(header)); *foundp = header; *foundsigp = NULL; SET_IF_NOT_NULL(matchp, true); @@ -1262,8 +1281,13 @@ both_headers(dns_slabheader_t *header, dns_rdatatype_t type, dns_typepair_t typepair = DNS_TYPEPAIR_VALUE(type, 0); dns_typepair_t sigpair = DNS_SIGTYPE(type); - return related_headers(header, typepair, sigpair, 0, foundp, foundsigp, - NULL); + bool done = related_headers(header, typepair, sigpair, foundp, + foundsigp, NULL); + if (done && NEGATIVE(*foundp)) { + *foundp = NULL; + } + + return done; } static isc_result_t @@ -1271,7 +1295,7 @@ check_zonecut(qpcnode_t *node, void *arg DNS__DB_FLARG) { qpc_search_t *search = arg; dns_slabheader_t *header = NULL; dns_slabheader_t *header_prev = NULL, *header_next = NULL; - dns_slabheader_t *dname_header = NULL, *sigdname_header = NULL; + dns_slabheader_t *found = NULL, *foundsig = NULL; isc_result_t result; isc_rwlock_t *nlock = NULL; isc_rwlocktype_t nlocktype = isc_rwlocktype_none; @@ -1290,16 +1314,15 @@ check_zonecut(qpcnode_t *node, void *arg DNS__DB_FLARG) { continue; } - if (both_headers(header, dns_rdatatype_dname, &dname_header, - &sigdname_header)) + if (both_headers(header, dns_rdatatype_dname, &found, + &foundsig)) { break; } } - if (dname_header != NULL && - (!DNS_TRUST_PENDING(dname_header->trust) || - (search->options & DNS_DBFIND_PENDINGOK) != 0)) + if (found != NULL && (!DNS_TRUST_PENDING(found->trust) || + (search->options & DNS_DBFIND_PENDINGOK) != 0)) { /* * We increment the reference count on node to ensure that @@ -1308,8 +1331,8 @@ check_zonecut(qpcnode_t *node, void *arg DNS__DB_FLARG) { qpcnode_acquire(search->qpdb, node, nlocktype, isc_rwlocktype_none DNS__DB_FLARG_PASS); search->zonecut = node; - search->zonecut_header = dname_header; - search->zonecut_sigheader = sigdname_header; + search->zonecut_header = found; + search->zonecut_sigheader = foundsig; search->need_cleanup = true; result = DNS_R_PARTIALMATCH; } else { @@ -1463,15 +1486,12 @@ find_coveringnsec(qpc_search_t *search, const dns_name_t *name, continue; } - if (DNS_TYPEPAIR_TYPE(header->typepair) == 0) { - continue; - } - if (both_headers(header, dns_rdatatype_nsec, &found, &foundsig)) { break; } } + if (found != NULL) { if (nodep != NULL) { qpcnode_acquire(search->qpdb, node, nlocktype, @@ -1543,7 +1563,7 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, dns_slabheader_t *found = NULL, *nsheader = NULL; dns_slabheader_t *foundsig = NULL, *nssig = NULL, *cnamesig = NULL; dns_slabheader_t *nsecheader = NULL, *nsecsig = NULL; - dns_typepair_t typepair, sigpair, negpair; + dns_typepair_t typepair, sigpair; qpc_search_t search; qpc_search_init(&search, (qpcache_t *)db, options, __now); @@ -1650,9 +1670,8 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, */ found = NULL; foundsig = NULL; - typepair = DNS_TYPEPAIR_VALUE(type, 0); + typepair = DNS_TYPEPAIR(type); sigpair = DNS_SIGTYPE(type); - negpair = DNS_TYPEPAIR_VALUE(0, type); nsheader = NULL; nsecheader = NULL; nssig = NULL; @@ -1687,7 +1706,7 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, } bool match = false; - if (related_headers(header, typepair, sigpair, negpair, &found, + if (related_headers(header, typepair, sigpair, &found, &foundsig, &match) && !MISSING_ANSWER(found, options)) { @@ -1706,6 +1725,18 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, continue; } + if (NEGATIVE(header)) { + /* + * FIXME: As of now, we are not interested in + * the negative headers. This could be + * improved and we can bail out early if we've + * seen all the types below (positive or + * negative), but the code is not yet ready + * for this. + */ + continue; + } + switch (header->typepair) { case dns_rdatatype_cname: if (!cname_ok) { @@ -1746,9 +1777,7 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, break; default: - if (typepair == dns_rdatatype_any && - DNS_TYPEPAIR_TYPE(header->typepair) != 0) - { + if (typepair == dns_typepair_any) { /* QTYPE==ANY, so any anwers will do */ found = header; break; @@ -1856,8 +1885,8 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, result = DNS_R_NCACHENXRRSET; } } else if (typepair != found->typepair && - typepair != dns_rdatatype_any && - found->typepair == dns_rdatatype_cname) + typepair != dns_typepair_any && + found->typepair == DNS_TYPEPAIR(dns_rdatatype_cname)) { /* * We weren't doing an ANY query and we found a CNAME instead @@ -1872,7 +1901,7 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, result = ISC_R_SUCCESS; } - if (typepair != dns_rdatatype_any || result == DNS_R_NCACHENXDOMAIN || + if (typepair != dns_typepair_any || result == DNS_R_NCACHENXDOMAIN || result == DNS_R_NCACHENXRRSET) { bindrdatasets(search.qpdb, node, found, foundsig, search.now, @@ -1921,8 +1950,8 @@ seek_ns_headers(qpc_search_t *search, qpcnode_t *node, dns_dbnode_t **nodep, for (header = node->data; header != NULL; header = header_next) { header_next = header->next; - bool ns = (header->typepair == dns_rdatatype_ns || - header->typepair == DNS_SIGTYPE(dns_rdatatype_ns)); + bool ns = header->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) || + header->typepair == DNS_SIGTYPE(dns_rdatatype_ns); if (check_stale_header(header, search, &header_prev)) { if (ns) { /* @@ -2065,7 +2094,7 @@ qpcache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_slabheader_t *header = NULL; dns_slabheader_t *header_prev = NULL, *header_next = NULL; dns_slabheader_t *found = NULL, *foundsig = NULL; - dns_typepair_t typepair, sigpair, negpair; + dns_typepair_t typepair, sigpair; isc_result_t result = ISC_R_SUCCESS; isc_rwlock_t *nlock = NULL; isc_rwlocktype_t nlocktype = isc_rwlocktype_none; @@ -2078,7 +2107,11 @@ qpcache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, REQUIRE(version == NULL); REQUIRE(type != dns_rdatatype_any); - if (type == dns_rdatatype_none && covers == dns_rdatatype_none) { + if (type == dns_rdatatype_none) { + /* We can't search negative cache directly */ + return ISC_R_NOTFOUND; + } + if (dns_rdatatype_issig(type) && covers == dns_rdatatype_none) { return ISC_R_NOTFOUND; } @@ -2086,9 +2119,8 @@ qpcache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, NODE_RDLOCK(nlock, &nlocktype); typepair = DNS_TYPEPAIR_VALUE(type, covers); - negpair = DNS_TYPEPAIR_VALUE(0, type); - sigpair = (covers == dns_rdatatype_none) ? DNS_SIGTYPE(type) - : dns_rdatatype_none; + sigpair = !dns_rdatatype_issig(type) ? DNS_SIGTYPE(type) + : dns_typepair_none; for (header = qpnode->data; header != NULL; header = header_next) { header_next = header->next; @@ -2097,12 +2129,13 @@ qpcache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, continue; } - if (related_headers(header, typepair, sigpair, negpair, &found, + if (related_headers(header, typepair, sigpair, &found, &foundsig, NULL)) { break; } } + if (found != NULL) { bindrdatasets(qpdb, qpnode, found, foundsig, search.now, nlocktype, isc_rwlocktype_none, rdataset, @@ -2487,12 +2520,6 @@ overmaxtype(qpcache_t *qpdb, uint32_t ntypes) { static bool prio_header(dns_slabheader_t *header) { - if (NEGATIVE(header) && - prio_type(DNS_TYPEPAIR_COVERS(header->typepair))) - { - return true; - } - return prio_type(header->typepair); } @@ -2550,9 +2577,25 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode, dns_slabheader_t *topheader = NULL, *topheader_prev = NULL; dns_slabheader_t *header = NULL, *sigheader = NULL; dns_slabheader_t *prioheader = NULL, *expireheader = NULL; - dns_typepair_t negpair = 0; dns_trust_t trust; uint32_t ntypes = 0; + dns_rdatatype_t rdtype = DNS_TYPEPAIR_TYPE(newheader->typepair); + dns_rdatatype_t covers = DNS_TYPEPAIR_COVERS(newheader->typepair); + dns_typepair_t sigpair = !dns_rdatatype_issig(rdtype) + ? DNS_SIGTYPE(rdtype) + : dns_typepair_none; + + REQUIRE(rdtype != dns_rdatatype_none); + if (dns_rdatatype_issig(rdtype)) { + /* signature must be positive, and cover a type */ + REQUIRE(!NEGATIVE(newheader)); + REQUIRE(covers != dns_rdatatype_none); + } else { + /* otherwise, it must cover nothing */ + REQUIRE(covers == dns_rdatatype_none); + } + /* positive header can't be ANY */ + REQUIRE(rdtype != dns_rdatatype_any || NEGATIVE(newheader)); if ((options & DNS_DBADD_FORCE) != 0) { trust = dns_trust_ultimate; @@ -2561,15 +2604,11 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode, } if (EXISTS(newheader)) { - dns_rdatatype_t rdtype = DNS_TYPEPAIR_TYPE(newheader->typepair); - dns_rdatatype_t covers = - DNS_TYPEPAIR_COVERS(newheader->typepair); - dns_typepair_t sigpair = DNS_SIGTYPE(covers); if (NEGATIVE(newheader)) { /* * We're adding a negative cache entry. */ - if (covers == dns_rdatatype_any) { + if (rdtype == dns_rdatatype_any) { /* * If we're adding an negative cache entry * which covers all types (NXDOMAIN, @@ -2599,27 +2638,37 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode, break; } } - negpair = DNS_TYPEPAIR_VALUE(covers, - dns_rdatatype_none); } else { /* * We're adding something that isn't a - * negative cache entry. Look for an extant - * non-ancient NXDOMAIN/NODATA(QTYPE=ANY) negative - * cache entry. If we're adding an RRSIG, also - * check for an extant non-ancient NODATA ncache - * entry which covers the same type as the RRSIG. + * negative cache entry. */ for (topheader = qpnode->data; topheader != NULL; topheader = topheader->next) { - if ((topheader->typepair == - RDATATYPE_NCACHEANY) || - (newheader->typepair == sigpair && - topheader->typepair == - DNS_TYPEPAIR_VALUE( - dns_rdatatype_none, - covers))) + /* + * Look for any existing negative cache + * entries. + */ + if (!NEGATIVE(topheader)) { + continue; + } + + /* + * If we find a cached NXDOMAIN, don't + * cache anything else. + */ + if (topheader->typepair == dns_typepair_any) { + break; + } + + /* + * Don't cache an RRSIG if it cover a type + * for which we have a cached NODATA record. + */ + if (newheader->typepair == sigpair && + DNS_TYPEPAIR_TYPE(topheader->typepair) == + covers) { break; } @@ -2654,7 +2703,6 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode, topheader = NULL; goto find_header; } - negpair = DNS_TYPEPAIR_VALUE(0, rdtype); } } @@ -2669,9 +2717,7 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode, prioheader = topheader; } - if (topheader->typepair == newheader->typepair || - topheader->typepair == negpair) - { + if (topheader->typepair == newheader->typepair) { break; } topheader_prev = topheader; @@ -2719,8 +2765,9 @@ find_header: * normally further down. */ if (ACTIVE(header, now) && - header->typepair == dns_rdatatype_ns && EXISTS(header) && - EXISTS(newheader) && header->trust >= newheader->trust && + header->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) && + EXISTS(header) && EXISTS(newheader) && + header->trust >= newheader->trust && dns_rdataslab_equalx(header, newheader, qpdb->common.rdclass, DNS_TYPEPAIR_TYPE(header->typepair))) @@ -2762,8 +2809,9 @@ find_header: * ensures the delegations that are withdrawn are honoured. */ if (ACTIVE(header, now) && - header->typepair == dns_rdatatype_ns && EXISTS(header) && - EXISTS(newheader) && header->trust <= newheader->trust) + header->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) && + EXISTS(header) && EXISTS(newheader) && + header->trust <= newheader->trust) { if (newheader->expire > header->expire) { newheader->expire = header->expire; @@ -2771,9 +2819,9 @@ find_header: } if (ACTIVE(header, now) && (options & DNS_DBADD_PREFETCH) == 0 && - (header->typepair == dns_rdatatype_a || - header->typepair == dns_rdatatype_aaaa || - header->typepair == dns_rdatatype_ds || + (header->typepair == DNS_TYPEPAIR(dns_rdatatype_a) || + header->typepair == DNS_TYPEPAIR(dns_rdatatype_aaaa) || + header->typepair == DNS_TYPEPAIR(dns_rdatatype_ds) || header->typepair == DNS_SIGTYPE(dns_rdatatype_ds)) && EXISTS(header) && EXISTS(newheader) && header->trust >= newheader->trust && @@ -3132,13 +3180,24 @@ qpcache_deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_slabheader_t *newheader = NULL; isc_rwlocktype_t nlocktype = isc_rwlocktype_none; isc_rwlock_t *nlock = NULL; + uint16_t attributes = DNS_SLABHEADERATTR_NONEXISTENT; REQUIRE(VALID_QPDB(qpdb)); REQUIRE(version == NULL); + /* Positive ANY type can't be in the cache. */ if (type == dns_rdatatype_any) { return ISC_R_NOTIMPLEMENTED; } + + /* Convert the negative type into positive type. */ + if (type == dns_rdatatype_none && covers != dns_rdatatype_none) { + type = covers; + covers = dns_rdatatype_none; + attributes |= DNS_SLABHEADERATTR_NEGATIVE; + } + + /* RRSIG must have covered type */ if (type == dns_rdatatype_rrsig && covers == dns_rdatatype_none) { return ISC_R_NOTIMPLEMENTED; } @@ -3146,7 +3205,7 @@ qpcache_deleterdataset(dns_db_t *db, dns_dbnode_t *node, newheader = dns_slabheader_new(db, node); newheader->typepair = DNS_TYPEPAIR_VALUE(type, covers); setttl(newheader, 0); - atomic_init(&newheader->attributes, DNS_SLABHEADERATTR_NONEXISTENT); + atomic_init(&newheader->attributes, attributes); nlock = &qpdb->buckets[qpnode->locknum].lock; NODE_WRLOCK(nlock, &nlocktype); diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index bb3fb9f562..107209dc56 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -1648,7 +1648,7 @@ qpzone_findrdataset(dns_db_t *db, dns_dbnode_t *dbnode, if (covers == dns_rdatatype_none) { sigpair = DNS_SIGTYPE(type); } else { - sigpair = dns_rdatatype_none; + sigpair = dns_typepair_none; } for (header = node->data; header != NULL; header = header_next) { @@ -3110,7 +3110,7 @@ find_closest_nsec(qpz_search_t *search, dns_dbnode_t **nodep, dns_name_t *name = dns_fixedname_initname(&fname); dns_rdatatype_t matchtype = nsec3 ? dns_rdatatype_nsec3 : dns_rdatatype_nsec; - dns_typepair_t typepair = DNS_TYPEPAIR_VALUE(matchtype, 0); + dns_typepair_t typepair = DNS_TYPEPAIR(matchtype); dns_typepair_t sigpair = DNS_SIGTYPE(matchtype); bool wraps = nsec3; bool first = true; diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index c12c2904c4..f5d4cb2454 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -350,10 +350,23 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, result = makeslab(rdataset, mctx, region, maxrrperset); if (result == ISC_R_SUCCESS) { dns_slabheader_t *new = (dns_slabheader_t *)region->base; + dns_typepair_t typepair; + + if (rdataset->attributes.negative) { + INSIST(rdataset->type == dns_rdatatype_none); + INSIST(rdataset->covers != dns_rdatatype_none); + typepair = DNS_TYPEPAIR_VALUE(rdataset->covers, + dns_rdatatype_none); + } else { + INSIST(rdataset->type != dns_rdatatype_none); + INSIST(dns_rdatatype_issig(rdataset->type) || + rdataset->covers == dns_rdatatype_none); + typepair = DNS_TYPEPAIR_VALUE(rdataset->type, + rdataset->covers); + } *new = (dns_slabheader_t){ - .typepair = DNS_TYPEPAIR_VALUE(rdataset->type, - rdataset->covers), + .typepair = typepair, .trust = rdataset->trust, .ttl = rdataset->ttl, .link = ISC_LINK_INITIALIZER, @@ -940,25 +953,11 @@ dns_slabheader_freeproof(isc_mem_t *mctx, dns_slabheader_proof_t **proofp) { dns_slabheader_t * dns_slabheader_top(dns_slabheader_t *header) { - dns_typepair_t typepair, negpair; - dns_rdatatype_t rdtype, covers; - - typepair = header->typepair; - rdtype = DNS_TYPEPAIR_TYPE(header->typepair); - if (NEGATIVE(header)) { - covers = DNS_TYPEPAIR_COVERS(header->typepair); - negpair = DNS_TYPEPAIR_VALUE(covers, 0); - } else { - negpair = DNS_TYPEPAIR_VALUE(0, rdtype); - } - /* * Find the start of the header chain for the next type * by walking back up the list. */ - while (header->up != NULL && (header->up->typepair == typepair || - header->up->typepair == negpair)) - { + while (header->up != NULL && header->up->typepair == header->typepair) { header = header->up; }