mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 01:59:26 +00:00
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 = <negative type>. 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.
This commit is contained in:
parent
3445362918
commit
6e2ca5e0d7
@ -19,8 +19,6 @@
|
||||
#include <dns/nsec3.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
#define RDATATYPE_NCACHEANY DNS_TYPEPAIR_VALUE(0, dns_rdatatype_any)
|
||||
|
||||
#ifdef STRONG_RWLOCK_CHECK
|
||||
#define STRONG_RWLOCK_CHECK(cond) REQUIRE(cond)
|
||||
#else
|
||||
|
@ -49,8 +49,12 @@
|
||||
DNS__TYPEPAIR_VALUE(base, covers); \
|
||||
})
|
||||
|
||||
#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);
|
||||
/*%<
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <dns/rdatasetiter.h>
|
||||
#include <dns/rdataslab.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/rdatatype.h>
|
||||
#include <dns/stats.h>
|
||||
#include <dns/time.h>
|
||||
#include <dns/view.h>
|
||||
@ -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;
|
||||
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,15 +1314,14 @@ 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) ||
|
||||
if (found != NULL && (!DNS_TRUST_PENDING(found->trust) ||
|
||||
(search->options & DNS_DBFIND_PENDINGOK) != 0))
|
||||
{
|
||||
/*
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user