dns_rbtnode_t *rbtnode = rbtiterator->common.node;
rbtdb_version_t *rbtversion = rbtiterator->common.version;
rdatasetheader_t *header, *top_next;
- rbtdb_serial_t serial = 1;
+ rbtdb_serial_t serial;
+ isc_stdtime_t now;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
- if (!IS_CACHE(rbtdb)) {
+ if (IS_CACHE(rbtdb)) {
+ serial = 1;
+ now = rbtiterator->common.now;
+ } else {
serial = rbtversion->serial;
+ now = 0;
}
NODE_RDLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
if (header->serial <= serial && !IGNORE(header)) {
/*
* Is this a "this rdataset doesn't exist"
- * record?
+ * record? Or is it too old in the cache?
+ *
+ * Note: unlike everywhere else, we
+ * check for now > header->rdh_ttl instead
+ * of ">=". This allows ANY and RRSIG
+ * queries for 0 TTL rdatasets to work.
*/
- if (NONEXISTENT(header)) {
+ if (NONEXISTENT(header) ||
+ (now != 0 &&
+ (now - RBTDB_VIRTUAL) >
+ header->rdh_ttl +
+ STALE_TTL(header, rbtdb)))
+ {
header = NULL;
}
break;
dns_rbtnode_t *rbtnode = rbtiterator->common.node;
rbtdb_version_t *rbtversion = rbtiterator->common.version;
rdatasetheader_t *header, *top_next;
+ rbtdb_serial_t serial;
+ isc_stdtime_t now;
rbtdb_rdatatype_t type, negtype;
dns_rdatatype_t rdtype, covers;
- rbtdb_serial_t serial = 1;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
header = rbtiterator->current;
return (ISC_R_NOMORE);
}
- if (!IS_CACHE(rbtdb)) {
+ if (IS_CACHE(rbtdb)) {
+ serial = 1;
+ now = rbtiterator->common.now;
+ } else {
serial = rbtversion->serial;
+ now = 0;
}
NODE_RDLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
/*
* Is this a "this rdataset doesn't
* exist" record?
+ *
+ * Note: unlike everywhere else, we
+ * check for now > header->ttl instead
+ * of ">=". This allows ANY and RRSIG
+ * queries for 0 TTL rdatasets to work.
*/
- if (NONEXISTENT(header)) {
+ if (NONEXISTENT(header) ||
+ (now != 0 &&
+ (now - RBTDB_VIRTUAL) >
+ header->rdh_ttl))
+ {
header = NULL;
}
break;