return sizeof(*header);
}
+static dns_slabheader_t *
+first_header(dns_slabtop_t *top) {
+ return top->header;
+}
+
+static dns_slabheader_t *
+first_existing_header(dns_slabtop_t *top) {
+ dns_slabheader_t *header = first_header(top);
+ if (EXISTS(top->header)) {
+ return header;
+ }
+ return NULL;
+}
+
static void
expire_lru_headers(qpcache_t *qpdb, uint32_t idx, size_t requested,
isc_rwlocktype_t *nlocktypep,
ISC_SIEVE_UNLINK(qpdb->buckets[idx].sieve, top, link);
- dns_slabheader_t *header = top->header;
+ dns_slabheader_t *header = first_header(top);
expired += rdataset_size(header);
*/
static void
-clean_stale_headers(dns_slabheader_t *top) {
- dns_slabheader_t *d = NULL, *down_next = NULL;
+clean_cache_headers(dns_slabtop_t *top) {
+ if (top->header == NULL) {
+ return;
+ }
- for (d = top->down; d != NULL; d = down_next) {
- down_next = d->down;
- dns_slabheader_destroy(&d);
+ dns_slabheader_t *header = top->header, *header_down = NULL;
+ for (header = header->down; header != NULL; header = header_down) {
+ header_down = header->down;
+ dns_slabheader_destroy(&header);
}
- top->down = NULL;
+ top->header->down = NULL;
}
static void
*/
DNS_SLABTOP_FOREACH(top, node->data) {
- clean_stale_headers(top->header);
+ clean_cache_headers(top);
/*
- * If current header is nonexistent, ancient, or stale and
- * we are not keeping stale, we can clean it up.
+ * If current top header is nonexistent, ancient, or stale
+ * and we are not keeping stale, we can clean it up too.
*/
if (!EXISTS(top->header) || ANCIENT(top->header) ||
(STALE(top->header) && !KEEPSTALE(qpdb)))
}
/*
- * If current slabtype is empty, we can also clean it up.
+ * If current slabtop is empty, we can clean it up.
*/
if (top->header == NULL) {
if (top_prev != NULL) {
* Look for a DNAME or RRSIG DNAME rdataset.
*/
DNS_SLABTOP_FOREACH(top, node->data) {
- if (check_stale_header(top->header, search)) {
+ dns_slabheader_t *header = first_header(top);
+ if (header == NULL) {
+ continue;
+ }
+
+ if (check_stale_header(header, search)) {
continue;
}
- if (both_headers(top->header, dns_rdatatype_dname, &found,
+ if (both_headers(header, dns_rdatatype_dname, &found,
&foundsig))
{
break;
* Look for NS and RRSIG NS rdatasets.
*/
DNS_SLABTOP_FOREACH(top, node->data) {
- if (check_stale_header(top->header, search)) {
+ dns_slabheader_t *header = first_header(top);
+ if (header == NULL) {
+ continue;
+ }
+
+ if (check_stale_header(header, search)) {
continue;
}
- if (both_headers(top->header, dns_rdatatype_ns, &found,
+ if (both_headers(header, dns_rdatatype_ns, &found,
&foundsig))
{
break;
nlock = &search->qpdb->buckets[node->locknum].lock;
NODE_RDLOCK(nlock, &nlocktype);
DNS_SLABTOP_FOREACH(top, node->data) {
- if (check_stale_header(top->header, search)) {
+ dns_slabheader_t *header = first_header(top);
+ if (header == NULL) {
continue;
}
- if (both_headers(top->header, dns_rdatatype_nsec, &found,
- &foundsig))
+ if (check_stale_header(header, search)) {
+ continue;
+ }
+
+ if (both_headers(header, dns_rdatatype_nsec, &found, &foundsig))
{
break;
}
cnamesig = NULL;
empty_node = true;
DNS_SLABTOP_FOREACH(top, node->data) {
- if (check_stale_header(top->header, &search)) {
+ dns_slabheader_t *header = first_header(top);
+ if (header == NULL) {
continue;
}
- if (!EXISTS(top->header) || ANCIENT(top->header)) {
+ if (check_stale_header(header, &search)) {
+ continue;
+ }
+
+ if (!EXISTS(header) || ANCIENT(header)) {
continue;
}
*/
empty_node = false;
- if (top->header->noqname != NULL &&
- top->header->trust == dns_trust_secure)
+ if (header->noqname != NULL &&
+ header->trust == dns_trust_secure)
{
found_noqname = true;
}
- if (!NEGATIVE(top->header)) {
+ if (!NEGATIVE(header)) {
all_negative = false;
}
bool match = false;
- if (related_headers(top->header, typepair, sigpair, &found,
+ if (related_headers(header, typepair, sigpair, &found,
&foundsig, &match) &&
!MISSING_ANSWER(found, options))
{
continue;
}
- if (NEGATIVE(top->header)) {
+ if (NEGATIVE(header)) {
/*
* FIXME: As of now, we are not interested in
* the negative headers. This could be
break;
}
- found = top->header;
+ found = header;
if (cnamesig != NULL) {
/* We already have CNAME signature */
foundsig = cnamesig;
break;
}
- cnamesig = top->header;
+ cnamesig = header;
break;
case dns_rdatatype_ns:
/* Remember the NS rdataset */
- nsheader = top->header;
+ nsheader = header;
break;
case DNS_SIGTYPEPAIR(dns_rdatatype_ns):
/* ...and its signature */
- nssig = top->header;
+ nssig = header;
break;
case dns_rdatatype_nsec:
- nsecheader = top->header;
+ nsecheader = header;
break;
case DNS_SIGTYPEPAIR(dns_rdatatype_nsec):
- nsecsig = top->header;
+ nsecsig = header;
break;
default:
if (typepair == dns_typepair_any) {
/* QTYPE==ANY, so any anwers will do */
- found = top->header;
+ found = header;
break;
}
}
DNS_SLABTOP_FOREACH(top, node->data) {
bool ns = top->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) ||
top->typepair == DNS_SIGTYPEPAIR(dns_rdatatype_ns);
- if (check_stale_header(top->header, search)) {
+ dns_slabheader_t *header = first_header(top);
+ if (header == NULL) {
+ continue;
+ }
+
+ if (check_stale_header(header, search)) {
if (ns) {
/*
* We found a cached NS, but was either
continue;
}
- if (both_headers(top->header, dns_rdatatype_ns, &found,
- &foundsig))
- {
+ if (both_headers(header, dns_rdatatype_ns, &found, &foundsig)) {
break;
}
}
: dns_typepair_none;
DNS_SLABTOP_FOREACH(top, qpnode->data) {
- if (check_stale_header(top->header, &search)) {
+ dns_slabheader_t *header = first_header(top);
+ if (header == NULL) {
continue;
}
- if (related_headers(top->header, typepair, sigpair, &found,
+ if (check_stale_header(header, &search)) {
+ continue;
+ }
+
+ if (related_headers(header, typepair, sigpair, &found,
&foundsig, NULL))
{
break;
(sigpair != dns_rdatatype_none && newheader->typepair == sigpair &&
DNS_TYPEPAIR_TYPE(top->typepair) == covers))
{
- if (trust < top->header->trust) {
+ dns_slabheader_t *header = first_header(top);
+ if (header == NULL) {
+ return DNS_R_CONTINUE;
+ }
+
+ if (trust < header->trust) {
/*
* The NXDOMAIN/NODATA(QTYPE=ANY) is more trusted.
*/
- qpcache_hit(qpdb, top->header);
- bindrdataset(qpdb, qpnode, top->header, now, nlocktype,
+ qpcache_hit(qpdb, header);
+ bindrdataset(qpdb, qpnode, header, now, nlocktype,
tlocktype,
addedrdataset DNS__DB_FLARG_PASS);
return DNS_R_UNCHANGED;
/*
* The new rdataset is better. Expire the ncache entry.
*/
- mark_ancient(top->header);
+ mark_ancient(header);
return DNS_R_CONTINUE;
}
unsigned int options, dns_rdataset_t *addedrdataset, isc_stdtime_t now,
isc_rwlocktype_t nlocktype, isc_rwlocktype_t tlocktype DNS__DB_FLARG) {
dns_slabtop_t *priotop = NULL, *expiretop = NULL;
- dns_slabheader_t *header = NULL, *sigheader = NULL;
+ dns_slabheader_t *oldheader = NULL, *oldsigheader = NULL;
dns_trust_t trust;
uint32_t ntypes = 0;
dns_rdatatype_t rdtype = DNS_TYPEPAIR_TYPE(newheader->typepair);
}
DNS_SLABTOP_FOREACH(top, qpnode->data) {
+ dns_slabheader_t *header = first_header(top);
+ if (header == NULL) {
+ continue;
+ }
+
if (EXISTS(newheader) && NEGATIVE(newheader) &&
rdtype == dns_rdatatype_any)
{
* rdataset that can be found at this node is the
* negative cache entry.
*/
- mark_ancient(top->header);
+ mark_ancient(header);
}
if (EXISTS(newheader) && NEGATIVE(newheader) &&
if (DNS_TYPEPAIR_TYPE(top->typepair) ==
dns_rdatatype_rrsig)
{
- mark_ancient(top->header);
+ mark_ancient(header);
}
}
if (EXISTS(newheader) && !NEGATIVE(newheader) &&
- NEGATIVE(top->header) && EXISTS(top->header) &&
- ACTIVE(top->header, now))
+ NEGATIVE(header) && EXISTS(header) && ACTIVE(header, now))
{
/*
* Look for existing active NXDOMAIN or negative
INSIST(result == DNS_R_CONTINUE);
}
- if (ACTIVE(top->header, now)) {
+ if (ACTIVE(header, now)) {
++ntypes;
expiretop = top;
}
}
if (top->typepair == newheader->typepair) {
- INSIST(header == NULL);
- header = top->header;
+ INSIST(oldheader == NULL);
+ oldheader = top->header;
}
if (sigpair != dns_rdatatype_none && top->typepair == sigpair) {
- INSIST(sigheader == NULL);
- sigheader = top->header;
+ INSIST(oldsigheader == NULL);
+ oldsigheader = top->header;
}
}
- if (header != NULL) {
+ if (oldheader != NULL) {
/*
* Deleting an already non-existent rdataset has no effect.
*/
- if (!EXISTS(header) && !EXISTS(newheader)) {
+ if (!EXISTS(oldheader) && !EXISTS(newheader)) {
return DNS_R_UNCHANGED;
}
* data will supersede it below. Unclear what the best
* policy is here.
*/
- if (trust < header->trust &&
- (ACTIVE(header, now) || !EXISTS(header)))
+ if (trust < oldheader->trust &&
+ (ACTIVE(oldheader, now) || !EXISTS(oldheader)))
{
- qpcache_hit(qpdb, header);
- bindrdataset(qpdb, qpnode, header, now, nlocktype,
+ qpcache_hit(qpdb, oldheader);
+ bindrdataset(qpdb, qpnode, oldheader, now, nlocktype,
tlocktype,
addedrdataset DNS__DB_FLARG_PASS);
- if (ACTIVE(header, now) &&
+ if (ACTIVE(oldheader, now) &&
(options & DNS_DBADD_EQUALOK) != 0 &&
dns_rdataslab_equalx(
- header, newheader, qpdb->common.rdclass,
- DNS_TYPEPAIR_TYPE(header->typepair)))
+ oldheader, newheader, qpdb->common.rdclass,
+ DNS_TYPEPAIR_TYPE(oldheader->typepair)))
{
/*
* Updated by caller to ISC_R_SUCCESS after
* to be done w.r.t stale data; it gets replaced normally
* further down.
*/
- if (ACTIVE(header, now) &&
- header->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) &&
- EXISTS(header) && EXISTS(newheader) &&
- header->trust >= newheader->trust &&
- header->expire < newheader->expire &&
- dns_rdataslab_equalx(header, newheader,
- qpdb->common.rdclass,
- DNS_TYPEPAIR_TYPE(header->typepair)))
+ if (ACTIVE(oldheader, now) &&
+ oldheader->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) &&
+ EXISTS(oldheader) && EXISTS(newheader) &&
+ oldheader->trust >= newheader->trust &&
+ oldheader->expire < newheader->expire &&
+ dns_rdataslab_equalx(
+ oldheader, newheader, qpdb->common.rdclass,
+ DNS_TYPEPAIR_TYPE(oldheader->typepair)))
{
- if (header->noqname == NULL &&
+ if (oldheader->noqname == NULL &&
newheader->noqname != NULL)
{
- header->noqname = newheader->noqname;
+ oldheader->noqname = newheader->noqname;
newheader->noqname = NULL;
}
- if (header->closest == NULL &&
+ if (oldheader->closest == NULL &&
newheader->closest != NULL)
{
- header->closest = newheader->closest;
+ oldheader->closest = newheader->closest;
newheader->closest = NULL;
}
- qpcache_hit(qpdb, header);
- bindrdataset(qpdb, qpnode, header, now, nlocktype,
+ qpcache_hit(qpdb, oldheader);
+ bindrdataset(qpdb, qpnode, oldheader, now, nlocktype,
tlocktype,
addedrdataset DNS__DB_FLARG_PASS);
if ((options & DNS_DBADD_EQUALOK) != 0) {
* to be no more than the current NS RRset's TTL. This
* ensures the delegations that are withdrawn are honoured.
*/
- if (ACTIVE(header, now) &&
- header->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) &&
- EXISTS(header) && EXISTS(newheader) &&
- header->trust <= newheader->trust)
+ if (ACTIVE(oldheader, now) &&
+ oldheader->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) &&
+ EXISTS(oldheader) && EXISTS(newheader) &&
+ oldheader->trust <= newheader->trust)
{
- if (newheader->expire > header->expire) {
- if (ZEROTTL(header)) {
+ if (newheader->expire > oldheader->expire) {
+ if (ZEROTTL(oldheader)) {
DNS_SLABHEADER_SETATTR(
newheader,
DNS_SLABHEADERATTR_ZEROTTL);
}
- newheader->expire = header->expire;
+ newheader->expire = oldheader->expire;
}
}
- if (ACTIVE(header, now) &&
+ if (ACTIVE(oldheader, now) &&
(options & DNS_DBADD_PREFETCH) == 0 &&
- (header->typepair == DNS_TYPEPAIR(dns_rdatatype_a) ||
- header->typepair == DNS_TYPEPAIR(dns_rdatatype_aaaa) ||
- header->typepair == DNS_TYPEPAIR(dns_rdatatype_ds) ||
- header->typepair == DNS_SIGTYPEPAIR(dns_rdatatype_ds)) &&
- EXISTS(header) && EXISTS(newheader) &&
- header->trust >= newheader->trust &&
- header->expire < newheader->expire &&
- dns_rdataslab_equal(header, newheader))
+ (oldheader->typepair == DNS_TYPEPAIR(dns_rdatatype_a) ||
+ oldheader->typepair == DNS_TYPEPAIR(dns_rdatatype_aaaa) ||
+ oldheader->typepair == DNS_TYPEPAIR(dns_rdatatype_ds) ||
+ oldheader->typepair ==
+ DNS_SIGTYPEPAIR(dns_rdatatype_ds)) &&
+ EXISTS(oldheader) && EXISTS(newheader) &&
+ oldheader->trust >= newheader->trust &&
+ oldheader->expire < newheader->expire &&
+ dns_rdataslab_equal(oldheader, newheader))
{
- if (header->noqname == NULL &&
+ if (oldheader->noqname == NULL &&
newheader->noqname != NULL)
{
- header->noqname = newheader->noqname;
+ oldheader->noqname = newheader->noqname;
newheader->noqname = NULL;
}
- if (header->closest == NULL &&
+ if (oldheader->closest == NULL &&
newheader->closest != NULL)
{
- header->closest = newheader->closest;
+ oldheader->closest = newheader->closest;
newheader->closest = NULL;
}
- qpcache_hit(qpdb, header);
- bindrdataset(qpdb, qpnode, header, now, nlocktype,
+ qpcache_hit(qpdb, oldheader);
+ bindrdataset(qpdb, qpnode, oldheader, now, nlocktype,
tlocktype,
addedrdataset DNS__DB_FLARG_PASS);
if ((options & DNS_DBADD_EQUALOK) != 0) {
return DNS_R_UNCHANGED;
}
- header->top->header = newheader;
- newheader->top = header->top;
- newheader->down = header;
+ oldheader->top->header = newheader;
+ newheader->top = oldheader->top;
+ newheader->down = oldheader;
ISC_SIEVE_UNLINK(qpdb->buckets[qpnode->locknum].sieve,
- header->top, link);
+ oldheader->top, link);
qpcache_miss(qpdb, newheader, &nlocktype,
&tlocktype DNS__DB_FLARG_PASS);
- mark_ancient(header);
- if (sigheader != NULL) {
- mark_ancient(sigheader);
+ mark_ancient(oldheader);
+ if (oldsigheader != NULL) {
+ mark_ancient(oldsigheader);
}
} else if (!EXISTS(newheader)) {
/*
expiretop = newtop;
}
- mark_ancient(expiretop->header);
+ dns_slabheader_t *expireheader =
+ first_header(expiretop);
+ if (expireheader != NULL) {
+ mark_ancient(expiretop->header);
+ }
/*
* FIXME: In theory, we should mark the RRSIG
* and the header at the same time, but there is
NODE_RDLOCK(nlock, &nlocktype);
DNS_SLABTOP_FOREACH(top, qpnode->data) {
- if (EXISTS(top->header) &&
- (EXPIREDOK(iterator) ||
- iterator_active(qpdb, iterator, top->header)))
+ dns_slabheader_t *header = first_existing_header(top);
+
+ if (EXPIREDOK(iterator) ||
+ (header != NULL && iterator_active(qpdb, iterator, header)))
{
iterator->current = top;
break;
NODE_RDLOCK(nlock, &nlocktype);
DNS_SLABTOP_FOREACH(top, next) {
- if (EXISTS(top->header) &&
- (EXPIREDOK(iterator) ||
- iterator_active(qpdb, iterator, top->header)))
+ dns_slabheader_t *header = first_existing_header(top);
+
+ if (EXPIREDOK(iterator) ||
+ (header != NULL && iterator_active(qpdb, iterator, header)))
{
iterator->current = top;
break;
NODE_RDLOCK(nlock, &nlocktype);
- bindrdataset(qpdb, qpnode, top->header, iterator->common.now, nlocktype,
+ dns_slabheader_t *header = first_existing_header(top);
+ INSIST(header != NULL);
+
+ bindrdataset(qpdb, qpnode, header, iterator->common.now, nlocktype,
isc_rwlocktype_none, rdataset DNS__DB_FLARG_PASS);
NODE_UNLOCK(nlock, &nlocktype);
#include <dns/rdatastruct.h>
#include <dns/stats.h>
#include <dns/time.h>
+#include <dns/types.h>
#include <dns/view.h>
#include <dns/zone.h>
#include "qpzone_p.h"
#include "rdataslab_p.h"
-#define CHECK(op) \
- do { \
- result = (op); \
- if (result != ISC_R_SUCCESS) \
- goto failure; \
- } while (0)
+#define CHECK(op) \
+ { \
+ result = (op); \
+ if (result != ISC_R_SUCCESS) { \
+ goto failure; \
+ } \
+ }
#define HEADERNODE(h) ((qpznode_t *)((h)->node))
qpznode_erefs_increment(node DNS__DB_FLARG_PASS);
}
+static void
+clean_multiple_headers(dns_slabtop_t *top) {
+ dns_slabheader_t *parent = top->header;
+ dns_slabheader_t *header = NULL, *header_down = NULL;
+
+ for (header = parent->down; header != NULL; header = header_down) {
+ header_down = header->down;
+ INSIST(header->serial <= parent->serial);
+ if (header->serial == parent->serial || IGNORE(header)) {
+ parent->down = header->down;
+ dns_slabheader_destroy(&header);
+ } else {
+ parent = header;
+ }
+ }
+}
+
+static void
+check_top_header(dns_slabtop_t *top) {
+ dns_slabheader_t *header = top->header;
+ if (IGNORE(header)) {
+ top->header = header->down;
+ dns_slabheader_destroy(&header);
+ }
+}
+
+static bool
+clean_multiple_versions(dns_slabtop_t *top, uint32_t least_serial) {
+ dns_slabheader_t *parent = top->header;
+ dns_slabheader_t *header = NULL, *header_down = NULL;
+ bool multiple = false;
+
+ for (header = parent->down; header != NULL; header = header_down) {
+ header_down = header->down;
+ if (header->serial < least_serial) {
+ parent->down = header->down;
+ dns_slabheader_destroy(&header);
+ } else {
+ multiple = true;
+ parent = header;
+ }
+ }
+ return multiple;
+}
+
static void
clean_zone_node(qpznode_t *node, uint32_t least_serial) {
dns_slabtop_t *top_prev = NULL;
* with the same serial number, or that have the IGNORE
* attribute.
*/
- dns_slabheader_t *dcurrent = NULL;
- dns_slabheader_t *dcurrent_down = NULL, *dparent = NULL;
-
- dparent = top->header;
- for (dcurrent = dparent->down; dcurrent != NULL;
- dcurrent = dcurrent_down)
- {
- dcurrent_down = dcurrent->down;
- INSIST(dcurrent->serial <= dparent->serial);
- if (dcurrent->serial == dparent->serial ||
- IGNORE(dcurrent))
- {
- dparent->down = dcurrent_down;
- dns_slabheader_destroy(&dcurrent);
- } else {
- dparent = dcurrent;
- }
- }
-
- /*
- * We've now eliminated all IGNORE datasets with the possible
- * exception of current, which we now check.
- */
- dcurrent = top->header;
- if (IGNORE(dcurrent)) {
- top->header = dcurrent->down;
- dns_slabheader_destroy(&dcurrent);
- }
-
- if (top->header == NULL) {
- goto empty;
- }
+ clean_multiple_headers(top);
/*
- * We now try to find the first down node less than the least
- * serial, and if there are such rdatasets, delete it and any
- * older versions.
+ * All IGNORE datasets have been eliminated with the possible
+ * exception of the top header, which we now check.
*/
- dparent = top->header;
- for (dcurrent = dparent->down; dcurrent != NULL;
- dcurrent = dcurrent_down)
- {
- dcurrent_down = dcurrent->down;
- if (dcurrent->serial < least_serial) {
- dparent->down = dcurrent_down;
- dns_slabheader_destroy(&dcurrent);
- } else {
- dparent = dcurrent;
- }
- }
+ check_top_header(top);
if (top->header == NULL) {
- empty:
if (top_prev != NULL) {
top_prev->next = top->next;
} else {
dns_slabtop_destroy(node->mctx, &top);
} else {
/*
- * Note. The serial number of 'current' might be less
- * than least_serial too, but we cannot delete it
+ * Try to find the first down node less than the least
+ * serial, and if there are such rdatasets, delete it
+ * and any older versions.
+ *
+ * Note: The serial number of the top header might be
+ * less than least_serial too, but we cannot delete it
* because it is the most recent version.
*/
- still_dirty = true;
+ still_dirty = clean_multiple_versions(top,
+ least_serial);
+
top_prev = top;
}
}
}
}
+static dns_slabheader_t *
+first_header(dns_slabtop_t *top, uint32_t serial) {
+ for (dns_slabheader_t *header = top->header; header != NULL;
+ header = header->down)
+ {
+ if (header->serial <= serial && !IGNORE(header)) {
+ return header;
+ }
+ }
+
+ return NULL;
+}
+
+static dns_slabheader_t *
+first_existing_header(dns_slabtop_t *top, uint32_t serial) {
+ dns_slabheader_t *header = first_header(top, serial);
+ if (header != NULL && EXISTS(header)) {
+ return header;
+ }
+ return NULL;
+}
+
static void
setnsec3parameters(dns_db_t *db, qpz_version_t *version) {
qpznode_t *node = NULL;
dns_rdata_nsec3param_t nsec3param;
isc_region_t region;
isc_result_t result;
- dns_slabtop_t *top = NULL;
unsigned char *raw; /* RDATASLAB */
unsigned int count, length;
qpzonedb_t *qpdb = (qpzonedb_t *)db;
NODE_RDLOCK(nlock, &nlocktype);
- top = node->data;
- while (top != NULL && top->typepair != dns_rdatatype_nsec3param) {
- top = top->next;
- }
- if (top != NULL) {
- dns_slabheader_t *header = top->header;
- while (header != NULL &&
- (IGNORE(header) || header->serial > version->serial))
- {
- header = header->down;
- }
-
- if (header != NULL && EXISTS(header)) {
- found = header;
+ DNS_SLABTOP_FOREACH(top, node->data) {
+ if (top->typepair != dns_rdatatype_nsec3param) {
+ continue;
}
+ found = first_existing_header(top, version->serial);
}
if (found != NULL) {
}
DNS_SLABTOP_FOREACH(top, node->data) {
- dns_slabheader_t *header = top->header;
- do {
- if (header->serial <= serial && !IGNORE(header)) {
- if (!EXISTS(header)) {
- header = NULL;
- }
- break;
- } else {
- header = header->down;
- }
- } while (header != NULL);
+ dns_slabheader_t *header = first_existing_header(top, serial);
if (header != NULL) {
/*
* We have an active, extant rdataset. If it's a
static bool
cname_and_other(qpznode_t *node, uint32_t serial) {
bool cname = false, other = false;
- dns_rdatatype_t rdtype;
/*
* Look for CNAME and "other data" rdatasets active in our version.
* or RRSIG.
*/
DNS_SLABTOP_FOREACH(top, node->data) {
- dns_slabheader_t *header = top->header;
-
- rdtype = DNS_TYPEPAIR_TYPE(top->typepair);
+ dns_rdatatype_t rdtype = DNS_TYPEPAIR_TYPE(top->typepair);
if (rdtype == dns_rdatatype_cname) {
- do {
- if (header->serial <= serial && !IGNORE(header))
- {
- if (!EXISTS(header)) {
- header = NULL;
- }
- break;
- }
- header = header->down;
- } while (header != NULL);
- if (header != NULL) {
+ if (first_existing_header(top, serial) != NULL) {
cname = true;
}
} else if (rdtype != dns_rdatatype_key &&
rdtype != dns_rdatatype_nsec &&
rdtype != dns_rdatatype_rrsig)
{
- do {
- if (header->serial <= serial && !IGNORE(header))
- {
- if (!EXISTS(header)) {
- header = NULL;
- }
- break;
- }
- header = header->down;
- } while (header != NULL);
- if (header != NULL) {
+ if (first_existing_header(top, serial) != NULL) {
if (!prio_type(rdtype)) {
/*
* CNAME is in the priority list, so if
NODE_RDLOCK(nlock, &nlocktype);
DNS_SLABTOP_FOREACH(top, node->data) {
- dns_slabheader_t *header = top->header;
- while (header != NULL &&
- (IGNORE(header) ||
- header->serial > search->serial))
- {
- header = header->down;
- }
- if (header != NULL && EXISTS(header)) {
- found = header;
- break;
- }
+ found = first_existing_header(top, search->serial);
}
NODE_UNLOCK(nlock, &nlocktype);
if (found != NULL) {
NODE_RDLOCK(nlock, &nlocktype);
empty_node = true;
DNS_SLABTOP_FOREACH(top, node->data) {
- dns_slabheader_t *header = top->header;
/*
* Look for an active, extant NSEC or RRSIG NSEC.
*/
- do {
- if (header->serial <= search->serial &&
- !IGNORE(header))
- {
- if (!EXISTS(header)) {
- header = NULL;
- }
- break;
- } else {
- header = header->down;
- }
- } while (header != NULL);
+ dns_slabheader_t *header =
+ first_existing_header(top, search->serial);
if (header != NULL) {
/*
* We now know that there is at least one
* Look for an NS or DNAME rdataset active in our version.
*/
DNS_SLABTOP_FOREACH(top, node->data) {
- dns_slabheader_t *header = top->header;
if (top->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) ||
top->typepair == DNS_TYPEPAIR(dns_rdatatype_dname) ||
top->typepair == DNS_SIGTYPEPAIR(dns_rdatatype_dname))
{
- do {
- if (header->serial <= search->serial &&
- !IGNORE(header))
- {
- if (!EXISTS(header)) {
- header = NULL;
- }
- break;
- } else {
- header = header->down;
- }
- } while (header != NULL);
+ dns_slabheader_t *header =
+ first_existing_header(top, search->serial);
if (header != NULL) {
if (top->typepair ==
DNS_TYPEPAIR(dns_rdatatype_dname))
sigpair = DNS_SIGTYPEPAIR(type);
empty_node = true;
DNS_SLABTOP_FOREACH(top, node->data) {
- dns_slabheader_t *header = top->header;
/*
* Look for an active, extant rdataset.
*/
- do {
- if (header->serial <= search.serial && !IGNORE(header))
- {
- if (!EXISTS(header)) {
- header = NULL;
- }
- break;
- } else {
- header = header->down;
- }
- } while (header != NULL);
+ dns_slabheader_t *header = first_existing_header(top,
+ search.serial);
if (header != NULL) {
/*
* We now know that there is at least one active
NODE_RDLOCK(nlock, &nlocktype);
DNS_SLABTOP_FOREACH(top, node->data) {
- dns_slabheader_t *header = top->header;
- while (header != NULL &&
- (IGNORE(header) || header->serial > version->serial))
- {
- header = header->down;
- }
+ qrditer->current = first_existing_header(top, version->serial);
- if (header != NULL && EXISTS(header)) {
+ if (qrditer->current != NULL) {
qrditer->currenttop = top;
- qrditer->current = header;
break;
}
}
* Find the start of the header chain for the next type.
*/
DNS_SLABTOP_FOREACH(top, next) {
- dns_slabheader_t *header = top->header;
- while (header != NULL &&
- (IGNORE(header) || header->serial > version->serial))
- {
- header = header->down;
- }
-
- if (header != NULL && EXISTS(header)) {
+ qrditer->current = first_existing_header(top, version->serial);
+ if (qrditer->current != NULL) {
qrditer->currenttop = top;
- qrditer->current = header;
break;
}
}