* rdataset implementations may change any of the fields.
*/
struct dns_rdataset {
- unsigned int magic; /* XXX ? */
+ unsigned int magic;
dns_rdatasetmethods_t *methods;
ISC_LINK(dns_rdataset_t) link;
dns_rdataclass_t rdclass;
dns_rdatatype_t type;
dns_ttl_t ttl;
- /*
- * Stale ttl is used to see how long this RRset can still be used
- * to serve to clients, after the TTL has expired.
- */
- dns_ttl_t stale_ttl;
+
dns_trust_t trust;
dns_rdatatype_t covers;
*/
isc_stdtime_t resign;
+ /*
+ * When a cache rdataset's TTL has expired but it hasn't been
+ * cleaned up yet, it will have this value set so that the time
+ * it expired can be printed by dns_master_dump*().
+ */
+ isc_stdtime_t expired;
+
/*@{*/
/*%
* These are for use by the rdataset implementation, and MUST NOT
isc_result_t result;
if (STALE(rds)) {
fprintf(f, "; stale\n");
- } else if (ANCIENT(rds)) {
+ } else if (ANCIENT(rds) && rds->expired != 0) {
isc_buffer_t b;
char buf[sizeof("YYYYMMDDHHMMSS")];
memset(buf, 0, sizeof(buf));
isc_buffer_init(&b, buf, sizeof(buf) - 1);
- dns_time64_totext((uint64_t)rds->stale_ttl, &b);
+ dns_time64_totext((uint64_t)rds->expired, &b);
fprintf(f,
"; expired since %s "
"(awaiting cleanup)\n",
rdataset->type = RBTDB_RDATATYPE_BASE(header->type);
rdataset->covers = RBTDB_RDATATYPE_EXT(header->type);
rdataset->ttl = header->rdh_ttl - now;
+ rdataset->expired = 0;
rdataset->trust = header->trust;
+
if (NEGATIVE(header)) {
rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE;
}
if (PREFETCH(header)) {
rdataset->attributes |= DNS_RDATASETATTR_PREFETCH;
}
+
if (stale && !ancient) {
dns_ttl_t stale_ttl = header->rdh_ttl + rbtdb->serve_stale_ttl;
if (stale_ttl > now) {
- stale_ttl = stale_ttl - now;
+ rdataset->ttl = stale_ttl - now;
} else {
- stale_ttl = 0;
+ rdataset->ttl = 0;
}
if (STALE_WINDOW(header)) {
rdataset->attributes |= DNS_RDATASETATTR_STALE_WINDOW;
}
rdataset->attributes |= DNS_RDATASETATTR_STALE;
- rdataset->stale_ttl = stale_ttl;
- rdataset->ttl = stale_ttl;
} else if (IS_CACHE(rbtdb) && !ACTIVE(header, now)) {
rdataset->attributes |= DNS_RDATASETATTR_ANCIENT;
- rdataset->stale_ttl = header->rdh_ttl;
+ rdataset->expired = header->rdh_ttl;
rdataset->ttl = 0;
}
isc_rwlocktype_write);
for (header = rbtnode->data; header != NULL; header = header->next) {
- if (header->rdh_ttl <= now - RBTDB_VIRTUAL) {
+ if (header->rdh_ttl + rbtdb->serve_stale_ttl <=
+ now - RBTDB_VIRTUAL) {
/*
* We don't check if refcurrent(rbtnode) == 0 and try
* to free like we do in cache_find(), because
for (header = rbtnode->data; header != NULL; header = header_next) {
header_next = header->next;
if (!ACTIVE(header, now)) {
- if ((header->rdh_ttl < now - RBTDB_VIRTUAL) &&
+ if ((header->rdh_ttl + rbtdb->serve_stale_ttl <
+ now - RBTDB_VIRTUAL) &&
(locktype == isc_rwlocktype_write ||
NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS))
{
}
header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
- if (header && header->rdh_ttl < now - RBTDB_VIRTUAL) {
+ if (header != NULL && header->rdh_ttl + rbtdb->serve_stale_ttl <
+ now - RBTDB_VIRTUAL)
+ {
expire_header(rbtdb, header, tree_locked, expire_ttl);
}