diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h index f12419bcac..2569e40d23 100644 --- a/lib/dns/include/dns/rdataset.h +++ b/lib/dns/include/dns/rdataset.h @@ -95,7 +95,7 @@ typedef struct dns_rdatasetmethods { * 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; @@ -107,11 +107,7 @@ struct dns_rdataset { 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; diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c index 75cd0d2509..c66eb7cceb 100644 --- a/lib/dns/masterdump.c +++ b/lib/dns/masterdump.c @@ -1114,7 +1114,7 @@ again: 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->ttl, &b); fprintf(f, "; expired since %s " "(awaiting cleanup)\n", diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 98f88e29de..4d37a36ba3 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -3136,6 +3136,7 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rdatasetheader_t *header, rdataset->covers = RBTDB_RDATATYPE_EXT(header->type); rdataset->ttl = header->rdh_ttl - now; rdataset->trust = header->trust; + if (NEGATIVE(header)) { rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE; } @@ -3148,23 +3149,21 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rdatasetheader_t *header, 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->ttl = 0; + rdataset->ttl = header->rdh_ttl; } rdataset->private1 = rbtdb; @@ -5589,7 +5588,8 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { 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 @@ -5860,7 +5860,8 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 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)) { @@ -6957,7 +6958,9 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, } 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); } diff --git a/lib/ns/query.c b/lib/ns/query.c index 97c3be1dd0..749c748704 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -5875,6 +5875,7 @@ query_lookup(query_ctx_t *qctx) { { qctx->rdataset->ttl = qctx->view->staleanswerttl; stale_found = true; + inc_stats(qctx->client, ns_statscounter_usedstale); } else { stale_found = false; }