diff options
Diffstat (limited to 'usr.sbin/bind/lib/dns/rbtdb.c')
-rw-r--r-- | usr.sbin/bind/lib/dns/rbtdb.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/usr.sbin/bind/lib/dns/rbtdb.c b/usr.sbin/bind/lib/dns/rbtdb.c index 32d787e1219..3c08492e17a 100644 --- a/usr.sbin/bind/lib/dns/rbtdb.c +++ b/usr.sbin/bind/lib/dns/rbtdb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $ISC: rbtdb.c,v 1.168.2.11.2.16 2004/05/23 11:07:23 marka Exp $ */ +/* $ISC: rbtdb.c,v 1.168.2.11.2.22 2005/10/14 01:38:48 marka Exp $ */ /* * Principal Author: Bob Halley @@ -97,6 +97,12 @@ typedef isc_uint32_t rbtdb_rdatatype_t; #define RBTDB_RDATATYPE_NCACHEANY \ RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any) +/* + * Allow clients with a virtual time of upto 5 minutes in the past to see + * records that would have otherwise have expired. + */ +#define RBTDB_VIRTUAL 300 + struct noqname { dns_name_t name; void * nsec; @@ -413,7 +419,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) { again: if (rbtdb->tree != NULL) { result = dns_rbt_destroy2(&rbtdb->tree, - (rbtdb->task != NULL) ? 5 : 0); + (rbtdb->task != NULL) ? 1000 : 0); if (result == ISC_R_QUOTA) { INSIST(rbtdb->task != NULL); if (event == NULL) @@ -2752,10 +2758,9 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep, isc_result_t result; dns_fixedname_t fname, forigin; dns_name_t *name, *origin; - rbtdb_rdatatype_t matchtype, sigmatchtype, nsectype; + rbtdb_rdatatype_t matchtype, sigmatchtype; matchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_nsec, 0); - nsectype = RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_nsec); sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec); @@ -2786,7 +2791,9 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep, * node as dirty, so it will get cleaned up * later. */ - if (node->references == 0) { + if (header->ttl > search->now - RBTDB_VIRTUAL) + header_prev = header; + else if (node->references == 0) { INSIST(header->down == NULL); if (header_prev != NULL) header_prev->next = @@ -2943,7 +2950,9 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * mark it as stale, and the node as dirty, so it will * get cleaned up later. */ - if (node->references == 0) { + if (header->ttl > now - RBTDB_VIRTUAL) + header_prev = header; + else if (node->references == 0) { INSIST(header->down == NULL); if (header_prev != NULL) header_prev->next = header->next; @@ -3210,7 +3219,9 @@ cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, * mark it as stale, and the node as dirty, so it will * get cleaned up later. */ - if (node->references == 0) { + if (header->ttl > now - RBTDB_VIRTUAL) + header_prev = header; + else if (node->references == 0) { INSIST(header->down == NULL); if (header_prev != NULL) header_prev->next = header->next; @@ -3398,7 +3409,7 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); for (header = rbtnode->data; header != NULL; header = header->next) - if (header->ttl <= now) { + if (header->ttl <= now - RBTDB_VIRTUAL) { /* * We don't check if rbtnode->references == 0 and try * to free like we do in cache_find(), because @@ -3640,8 +3651,10 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, * rbtnode->references must be non-zero. This is so * because 'node' is an argument to the function. */ - header->attributes |= RDATASET_ATTR_STALE; - rbtnode->dirty = 1; + if (header->ttl <= now - RBTDB_VIRTUAL) { + header->attributes |= RDATASET_ATTR_STALE; + rbtnode->dirty = 1; + } } else if (EXISTS(header)) { if (header->type == matchtype) found = header; @@ -4344,6 +4357,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, changed = add_changed(rbtdb, rbtversion, rbtnode); if (changed == NULL) { free_rdataset(rbtdb->common.mctx, newheader); + UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); return (ISC_R_NOMEMORY); } @@ -4909,6 +4923,11 @@ dns_rbtdb_create isc_mem_attach(mctx, &rbtdb->common.mctx); /* + * Must be initalized before free_rbtdb() is called. + */ + isc_ondestroy_init(&rbtdb->common.ondest); + + /* * Make a copy of the origin name. */ result = dns_name_dupwithoffsets(origin, mctx, &rbtdb->common.origin); @@ -4986,8 +5005,6 @@ dns_rbtdb_create rbtdb->future_version = NULL; ISC_LIST_INIT(rbtdb->open_versions); - isc_ondestroy_init(&rbtdb->common.ondest); - rbtdb->common.magic = DNS_DB_MAGIC; rbtdb->common.impmagic = RBTDB_MAGIC; |