From 887d4bc542def2306e66dc3dd26a9f51b92a9aa1 Mon Sep 17 00:00:00 2001 From: "Internet Software Consortium, Inc" <@isc.org> Date: Fri, 8 Oct 2010 08:25:08 -0600 Subject: v9.7.2 --- lib/bind9/api | 2 +- lib/bind9/check.c | 6 +- lib/dns/adb.c | 51 +++++---- lib/dns/api | 2 +- lib/dns/include/dns/view.h | 31 +++++- lib/dns/include/dns/zone.h | 31 +++++- lib/dns/rbtdb.c | 80 ++++++++------ lib/dns/sdb.c | 9 +- lib/dns/sdlz.c | 9 +- lib/dns/view.c | 44 +++++++- lib/dns/win32/libdns.def | 3 + lib/dns/zone.c | 200 +++++++++++++++++++++++++++++++--- lib/isc/api | 6 +- lib/isc/entropy.c | 11 +- lib/isc/include/isc/mem.h | 11 +- lib/isc/include/isc/namespace.h | 5 +- lib/isc/mem.c | 39 ++++++- lib/isc/mem_api.c | 9 +- lib/isc/win32/libisc.def | 1 + lib/isc/win32/socket.c | 7 +- lib/isccfg/aclconf.c | 23 +++- lib/isccfg/api | 4 +- lib/isccfg/include/isccfg/aclconf.h | 14 ++- lib/isccfg/include/isccfg/cfg.h | 38 +++++-- lib/isccfg/include/isccfg/grammar.h | 6 +- lib/isccfg/include/isccfg/namedconf.h | 5 +- lib/isccfg/namedconf.c | 57 ++++------ lib/isccfg/parser.c | 66 ++++++++--- lib/isccfg/win32/libisccfg.def | 5 +- lib/lwres/api | 2 +- lib/lwres/print_p.h | 15 ++- 31 files changed, 602 insertions(+), 190 deletions(-) (limited to 'lib') diff --git a/lib/bind9/api b/lib/bind9/api index b0b7496c..d345908b 100644 --- a/lib/bind9/api +++ b/lib/bind9/api @@ -1,3 +1,3 @@ LIBINTERFACE = 60 -LIBREVISION = 3 +LIBREVISION = 4 LIBAGE = 0 diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 593f0b59..5c26f940 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check.c,v 1.114.4.5 2010/06/26 05:31:17 marka Exp $ */ +/* $Id: check.c,v 1.114.4.6 2010/08/11 18:19:57 each Exp $ */ /*! \file */ @@ -2101,7 +2101,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, if (tresult != ISC_R_SUCCESS) result = tresult; - cfg_aclconfctx_destroy(&actx); + cfg_aclconfctx_clear(&actx); return (result); } @@ -2346,7 +2346,7 @@ bind9_check_controls(const cfg_obj_t *config, isc_log_t *logctx, result = tresult; } } - cfg_aclconfctx_destroy(&actx); + cfg_aclconfctx_clear(&actx); return (result); } diff --git a/lib/dns/adb.c b/lib/dns/adb.c index 2e1c607a..a4d8197a 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: adb.c,v 1.247 2009/02/03 22:33:13 jinmei Exp $ */ +/* $Id: adb.c,v 1.247.172.2 2010/08/13 23:46:28 tbox Exp $ */ /*! \file * @@ -118,7 +118,6 @@ struct dns_adb { isc_taskmgr_t *taskmgr; isc_task_t *task; - isc_boolean_t overmem; isc_interval_t tick_interval; int next_cleanbucket; @@ -294,8 +293,8 @@ static inline void inc_adb_irefcnt(dns_adb_t *); static inline void inc_adb_erefcnt(dns_adb_t *); static inline void inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *, isc_boolean_t); -static inline isc_boolean_t dec_entry_refcnt(dns_adb_t *, dns_adbentry_t *, - isc_boolean_t); +static inline isc_boolean_t dec_entry_refcnt(dns_adb_t *, isc_boolean_t, + dns_adbentry_t *, isc_boolean_t); static inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *); static isc_boolean_t clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *); static void clean_target(dns_adb_t *, dns_name_t *); @@ -777,7 +776,7 @@ link_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) { int i; dns_adbentry_t *e; - if (adb->overmem) { + if (isc_mem_isovermem(adb->mctx)) { for (i = 0; i < 2; i++) { e = ISC_LIST_TAIL(adb->entries[bucket]); if (e == NULL) @@ -943,6 +942,7 @@ clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) { dns_adbnamehook_t *namehook; int addr_bucket; isc_boolean_t result = ISC_FALSE; + isc_boolean_t overmem = isc_mem_isovermem(adb->mctx); addr_bucket = DNS_ADB_INVALIDBUCKET; namehook = ISC_LIST_HEAD(*namehooks); @@ -963,7 +963,8 @@ clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) { LOCK(&adb->entrylocks[addr_bucket]); } - result = dec_entry_refcnt(adb, entry, ISC_FALSE); + result = dec_entry_refcnt(adb, overmem, entry, + ISC_FALSE); } /* @@ -1235,7 +1236,9 @@ inc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) { } static inline isc_boolean_t -dec_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) { +dec_entry_refcnt(dns_adb_t *adb, isc_boolean_t overmem, dns_adbentry_t *entry, + isc_boolean_t lock) +{ int bucket; isc_boolean_t destroy_entry; isc_boolean_t result = ISC_FALSE; @@ -1250,7 +1253,7 @@ dec_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) { destroy_entry = ISC_FALSE; if (entry->refcnt == 0 && - (adb->entry_sd[bucket] || entry->expires == 0 || adb->overmem || + (adb->entry_sd[bucket] || entry->expires == 0 || overmem || (entry->flags & ENTRY_IS_DEAD) != 0)) { destroy_entry = ISC_TRUE; result = unlink_entry(adb, entry); @@ -1852,7 +1855,7 @@ check_stale_name(dns_adb_t *adb, int bucket, isc_stdtime_t now) { int victims, max_victims; isc_boolean_t result; dns_adbname_t *victim, *next_victim; - isc_boolean_t overmem = adb->overmem; + isc_boolean_t overmem = isc_mem_isovermem(adb->mctx); int scans = 0; INSIST(bucket != DNS_ADB_INVALIDBUCKET); @@ -2049,7 +2052,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, adb, NULL, NULL); adb->cevent_sent = ISC_FALSE; adb->shutting_down = ISC_FALSE; - adb->overmem = ISC_FALSE; ISC_LIST_INIT(adb->whenshutdown); isc_mem_attach(mem, &adb->mctx); @@ -2616,6 +2618,7 @@ dns_adb_destroyfind(dns_adbfind_t **findp) { dns_adbaddrinfo_t *ai; int bucket; dns_adb_t *adb; + isc_boolean_t overmem; REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp)); find = *findp; @@ -2640,13 +2643,14 @@ dns_adb_destroyfind(dns_adbfind_t **findp) { * Return the find to the memory pool, and decrement the adb's * reference count. */ + overmem = isc_mem_isovermem(adb->mctx); ai = ISC_LIST_HEAD(find->list); while (ai != NULL) { ISC_LIST_UNLINK(find->list, ai, publink); entry = ai->entry; ai->entry = NULL; INSIST(DNS_ADBENTRY_VALID(entry)); - RUNTIME_CHECK(dec_entry_refcnt(adb, entry, ISC_TRUE) == + RUNTIME_CHECK(dec_entry_refcnt(adb, overmem, entry, ISC_TRUE) == ISC_FALSE); free_adbaddrinfo(adb, &ai); ai = ISC_LIST_HEAD(find->list); @@ -3509,6 +3513,7 @@ dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) { int bucket; isc_stdtime_t now; isc_boolean_t want_check_exit = ISC_FALSE; + isc_boolean_t overmem; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(addrp != NULL); @@ -3520,13 +3525,14 @@ dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) { isc_stdtime_get(&now); *addrp = NULL; + overmem = isc_mem_isovermem(adb->mctx); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); entry->expires = now + ADB_ENTRY_WINDOW; - want_check_exit = dec_entry_refcnt(adb, entry, ISC_FALSE); + want_check_exit = dec_entry_refcnt(adb, overmem, entry, ISC_FALSE); UNLOCK(&adb->entrylocks[bucket]); @@ -3591,6 +3597,14 @@ dns_adb_flushname(dns_adb_t *adb, dns_name_t *name) { static void water(void *arg, int mark) { + /* + * We're going to change the way to handle overmem condition: use + * isc_mem_isovermem() instead of storing the state via this callback, + * since the latter way tends to cause race conditions. + * To minimize the change, and in case we re-enable the callback + * approach, however, keep this function at the moment. + */ + dns_adb_t *adb = arg; isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER); @@ -3598,17 +3612,6 @@ water(void *arg, int mark) { DP(ISC_LOG_DEBUG(1), "adb reached %s water mark", overmem ? "high" : "low"); - - /* - * We can't use adb->lock as there is potential for water - * to be called when adb->lock is held. - */ - LOCK(&adb->overmemlock); - if (adb->overmem != overmem) { - adb->overmem = overmem; - isc_mem_waterack(adb->mctx, mark); - } - UNLOCK(&adb->overmemlock); } void diff --git a/lib/dns/api b/lib/dns/api index b88cdba1..d8aa0d4f 100644 --- a/lib/dns/api +++ b/lib/dns/api @@ -1,3 +1,3 @@ -LIBINTERFACE = 67 +LIBINTERFACE = 68 LIBREVISION = 0 LIBAGE = 0 diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 6e4ca624..8f8dde5d 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.h,v 1.120.8.5 2010/07/11 00:12:19 each Exp $ */ +/* $Id: view.h,v 1.120.8.6 2010/08/11 18:19:58 each Exp $ */ #ifndef DNS_VIEW_H #define DNS_VIEW_H 1 @@ -176,6 +176,14 @@ struct dns_view { dns_viewlist_t * viewlist; dns_zone_t * managed_keys; + +#ifdef BIND9 + /* File in which to store configuration for newly added zones */ + char * new_zone_file; + + void * new_zone_config; + void (*cfg_destroy)(void **); +#endif }; #define DNS_VIEW_MAGIC ISC_MAGIC('V','i','e','w') @@ -994,4 +1002,25 @@ dns_view_untrust(dns_view_t *view, dns_name_t *keyname, * \li 'dnskey' is valid. */ +void +dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx, + void (*cfg_destroy)(void **)); +/*%< + * Set whether or not to allow zones to be created or deleted at runtime. + * + * If 'allow' is ISC_TRUE, determines the filename into which new zone + * configuration will be written. Preserves the configuration context + * (a pointer to which is passed in 'cfgctx') for use when parsing new + * zone configuration. 'cfg_destroy' points to a callback routine to + * destroy the configuration context when the view is destroyed. (This + * roundabout method is used in order to avoid libdns having a dependency + * on libisccfg and libbind9.) + * + * If 'allow' is ISC_FALSE, removes any existing references to + * configuration context and frees any memory. + * + * Requires: + * \li 'view' is valid. + */ + #endif /* DNS_VIEW_H */ diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 9d6a8534..a5d82350 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.h,v 1.174.4.1 2009/12/29 22:23:00 marka Exp $ */ +/* $Id: zone.h,v 1.174.4.4 2010/08/16 22:27:18 marka Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -89,6 +89,7 @@ typedef enum { #define DNS_ZONEKEY_ALLOW 0x00000001U /*%< fetch keys on command */ #define DNS_ZONEKEY_MAINTAIN 0x00000002U /*%< publish/sign on schedule */ #define DNS_ZONEKEY_CREATE 0x00000004U /*%< make keys when needed */ +#define DNS_ZONEKEY_FULLSIGN 0x00000008U /*%< roll to new keys immediately */ #ifndef DNS_ZONE_MINREFRESH #define DNS_ZONE_MINREFRESH 300 /*%< 5 minutes */ @@ -1779,9 +1780,14 @@ dns_zone_getprivatetype(dns_zone_t *zone); */ void -dns_zone_rekey(dns_zone_t *zone); +dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign); /*%< * Update the zone's DNSKEY set from the key repository. + * + * If 'fullsign' is true, trigger an immediate full signing of + * the zone with the new key. Otherwise, if there are no keys or + * if the new keys are for algorithms that have already signed the + * zone, then the zone can be re-signed incrementally. */ isc_result_t @@ -1802,6 +1808,25 @@ dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, * ISC_R_SUCCESS if there were no errors examining the zone contents. */ +void +dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added); +/*% + * Sets the value of zone->added, which should be ISC_TRUE for + * zones that were originally added by "rndc addzone". + * + * Requires: + * \li 'zone' to be valid. + */ + +isc_boolean_t +dns_zone_getadded(dns_zone_t *zone); +/*% + * Returns ISC_TRUE if the zone was originally added at runtime + * using "rndc addzone". + * + * Requires: + * \li 'zone' to be valid. + */ ISC_LANG_ENDDECLS diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 22299383..c282bb05 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.292.8.9 2010/05/10 01:41:11 marka Exp $ */ +/* $Id: rbtdb.c,v 1.292.8.12 2010/08/13 23:46:28 tbox Exp $ */ /*! \file */ @@ -411,7 +411,6 @@ typedef struct { rbtdb_version_t * current_version; rbtdb_version_t * future_version; rbtdb_versionlist_t open_versions; - isc_boolean_t overmem; isc_task_t * task; dns_dbnode_t *soanode; dns_dbnode_t *nsnode; @@ -3276,6 +3275,9 @@ matchparams(rdatasetheader_t *header, rbtdb_search_t *search) return (ISC_FALSE); } +/* + * Find node of the NSEC/NSEC3 record that is 'name'. + */ static inline isc_result_t previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search, dns_name_t *name, dns_name_t *origin, @@ -3287,15 +3289,15 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search, dns_rbtnode_t *nsecnode; isc_result_t result; + REQUIRE(nodep != NULL && *nodep == NULL); + if (type == dns_rdatatype_nsec3) { result = dns_rbtnodechain_prev(&search->chain, NULL, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) return (result); result = dns_rbtnodechain_current(&search->chain, name, origin, nodep); - if (result != ISC_R_SUCCESS) - return (result); - return (ISC_R_SUCCESS); + return (result); } dns_fixedname_init(&ftarget); @@ -3328,11 +3330,11 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search, * Try the previous node in the NSEC tree. */ result = dns_rbtnodechain_prev(nsecchain, - name, origin); + name, origin); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; - } else if (result == ISC_R_NOTFOUND - || result == DNS_R_PARTIALMATCH) { + } else if (result == ISC_R_NOTFOUND || + result == DNS_R_PARTIALMATCH) { result = dns_rbtnodechain_current(nsecchain, name, origin, NULL); if (result == ISC_R_NOTFOUND) @@ -3349,8 +3351,6 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search, result = dns_rbtnodechain_prev(nsecchain, name, origin); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; - if (result != ISC_R_SUCCESS) - return (result); } if (result != ISC_R_SUCCESS) return (result); @@ -3374,10 +3374,7 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search, * same name as the node in the auxiliary NSEC tree, except for * nodes in the auxiliary tree that are awaiting deletion. */ - if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - - if (result != ISC_R_NOTFOUND) { + if (result != DNS_R_PARTIALMATCH && result != ISC_R_NOTFOUND) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_ERROR, "previous_closest_nsec(): %s", @@ -3387,6 +3384,11 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search, } } +/* + * Find the NSEC/NSEC3 which is or before the current point on the + * search chain. For NSEC3 records only NSEC3 records that match the + * current NSEC3PARAM record are considered. + */ static inline isc_result_t find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, @@ -3420,15 +3422,16 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep, * Use the auxiliary tree only starting with the second node in the * hope that the original node will be right much of the time. */ - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - dns_fixedname_init(&forigin); - origin = dns_fixedname_name(&forigin); + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + dns_fixedname_init(&forigin); + origin = dns_fixedname_name(&forigin); again: node = NULL; + prevnode = NULL; result = dns_rbtnodechain_current(&search->chain, name, origin, &node); - if (result != ISC_R_SUCCESS) - return (result); + if (result != ISC_R_SUCCESS) + return (result); do { NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); @@ -3479,8 +3482,10 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep, empty_node = ISC_TRUE; found = NULL; foundsig = NULL; - result = dns_rbtnodechain_prev(&search->chain, - NULL, NULL); + result = previous_closest_nsec(type, search, + name, origin, + &prevnode, NULL, + NULL); } else if (found != NULL && (foundsig != NULL || !need_sig)) { /* @@ -3520,8 +3525,10 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep, */ empty_node = ISC_TRUE; result = previous_closest_nsec(type, search, - name, origin, &prevnode, - &nsecchain, &first); + name, origin, + &prevnode, + &nsecchain, + &first); } else { /* * We found an active node, but either the @@ -3542,6 +3549,7 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep, NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); node = prevnode; + prevnode = NULL; } while (empty_node && result == ISC_R_SUCCESS); if (!first) @@ -5117,7 +5125,7 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { if (now == 0) isc_stdtime_get(&now); - if (rbtdb->overmem) { + if (isc_mem_isovermem(rbtdb->common.mctx)) { isc_uint32_t val; isc_random_get(&val); @@ -5127,8 +5135,8 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { force_expire = ISC_TF(rbtnode->down == NULL && val % 4 == 0); /* - * Note that 'log' can be true IFF rbtdb->overmem is also true. - * rbtdb->overmem can currently only be true for cache + * Note that 'log' can be true IFF overmem is also true. + * overmem can currently only be true for cache * databases -- hence all of the "overmem cache" log strings. */ log = ISC_TF(isc_log_wouldlog(dns_lctx, level)); @@ -5173,7 +5181,7 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { "reprieve by RETAIN() %s", printname); } - } else if (rbtdb->overmem && log) + } else if (isc_mem_isovermem(rbtdb->common.mctx) && log) isc_log_write(dns_lctx, category, module, level, "overmem cache: saved %s", printname); @@ -5185,10 +5193,12 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { static void overmem(dns_db_t *db, isc_boolean_t overmem) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; + /* This is an empty callback. See adb.c:water() */ - if (IS_CACHE(rbtdb)) - rbtdb->overmem = overmem; + UNUSED(db); + UNUSED(overmem); + + return; } static void @@ -6134,6 +6144,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_boolean_t delegating; isc_boolean_t newnsec; isc_boolean_t tree_locked = ISC_FALSE; + isc_boolean_t cache_is_overmem = ISC_FALSE; REQUIRE(VALID_RBTDB(rbtdb)); @@ -6230,12 +6241,14 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, * the tree. In the latter case the lock does not necessarily have to * be acquired but it will help purge stale entries more effectively. */ - if (delegating || newnsec || (IS_CACHE(rbtdb) && rbtdb->overmem)) { + if (IS_CACHE(rbtdb) && isc_mem_isovermem(rbtdb->common.mctx)) + cache_is_overmem = ISC_TRUE; + if (delegating || newnsec || cache_is_overmem) { tree_locked = ISC_TRUE; RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); } - if (IS_CACHE(rbtdb) && rbtdb->overmem) + if (cache_is_overmem) overmem_purge(rbtdb, rbtnode->locknum, now, tree_locked); NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, @@ -7399,7 +7412,6 @@ dns_rbtdb_create return (result); } rbtdb->attributes = 0; - rbtdb->overmem = ISC_FALSE; rbtdb->task = NULL; /* diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c index 2e15b78b..7f4b97b1 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.c,v 1.71.54.2 2010/02/25 05:25:53 tbox Exp $ */ +/* $Id: sdb.c,v 1.71.54.3 2010/08/16 05:14:15 marka Exp $ */ /*! \file */ @@ -836,13 +836,6 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, result = DNS_R_NXDOMAIN; for (i = olabels; i <= nlabels; i++) { - /* - * Unless this is an explicit lookup at the origin, don't - * look at the origin. - */ - if (i == olabels && i != nlabels) - continue; - /* * Look up the next label. */ diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c index 6bedd4cc..7f67fae0 100644 --- a/lib/dns/sdlz.c +++ b/lib/dns/sdlz.c @@ -50,7 +50,7 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdlz.c,v 1.22.104.2 2010/02/25 05:25:53 tbox Exp $ */ +/* $Id: sdlz.c,v 1.22.104.3 2010/08/16 05:14:15 marka Exp $ */ /*! \file */ @@ -800,13 +800,6 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, result = DNS_R_NXDOMAIN; for (i = olabels; i <= nlabels; i++) { - /* - * Unless this is an explicit lookup at the origin, don't - * look at the origin. - */ - if (i == olabels && i != nlabels) - continue; - /* * Look up the next label. */ diff --git a/lib/dns/view.c b/lib/dns/view.c index 8f4452ca..83525653 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -15,13 +15,14 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.c,v 1.159.8.7 2010/07/11 00:12:19 each Exp $ */ +/* $Id: view.c,v 1.159.8.9 2010/08/12 04:04:34 each Exp $ */ /*! \file */ #include #include +#include #include #include /* Required for HP/UX (and others?) */ #include @@ -183,8 +184,11 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->v4_aaaa_acl = NULL; dns_fixedname_init(&view->dlv_fixed); view->managed_keys = NULL; - #ifdef BIND9 + view->new_zone_file = NULL; + view->new_zone_config = NULL; + view->cfg_destroy = NULL; + result = dns_order_create(view->mctx, &view->order); if (result != ISC_R_SUCCESS) goto cleanup_dynkeys; @@ -366,6 +370,7 @@ destroy(dns_view_t *view) { #ifdef BIND9 if (view->managed_keys != NULL) dns_zone_detach(&view->managed_keys); + dns_view_setnewzones(view, ISC_FALSE, NULL, NULL); #endif dns_fwdtable_destroy(&view->fwdtable); dns_aclenv_destroy(&view->aclenv); @@ -1620,3 +1625,38 @@ dns_view_untrust(dns_view_t *view, dns_name_t *keyname, dst_key_free(&key); } +#define NZF ".nzf" + +void +dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx, + void (*cfg_destroy)(void **)) +{ + REQUIRE(DNS_VIEW_VALID(view)); + REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow); + +#ifdef BIND9 + if (allow) { + char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(NZF)]; + isc_sha256_data((void *)view->name, strlen(view->name), buffer); + /* Truncate the hash at 16 chars; full length is overkill */ + isc_string_printf(buffer + 16, sizeof(NZF), "%s", NZF); + view->new_zone_file = isc_mem_strdup(view->mctx, buffer); + view->new_zone_config = cfgctx; + view->cfg_destroy = cfg_destroy; + } else { + if (view->new_zone_file != NULL) { + isc_mem_free(view->mctx, view->new_zone_file); + view->new_zone_file = NULL; + } + + if (view->new_zone_config != NULL) { + view->cfg_destroy(&view->new_zone_config); + view->cfg_destroy = NULL; + } + } +#else + UNUSED(allow); + UNUSED(cfgctx); + UNUSED(cfg_destroy); +#endif +} diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def index 87ead548..71a4933a 100644 --- a/lib/dns/win32/libdns.def +++ b/lib/dns/win32/libdns.def @@ -705,6 +705,7 @@ dns_view_setcache2 dns_view_setdstport dns_view_sethints dns_view_setkeyring +dns_view_setnewzones dns_view_setresquerystats dns_view_setresstats dns_view_setrootdelonly @@ -738,6 +739,7 @@ dns_zone_flush dns_zone_forcereload dns_zone_forwardupdate dns_zone_fulldumptostream +dns_zone_getadded dns_zone_getchecknames dns_zone_getclass dns_zone_getdb @@ -795,6 +797,7 @@ dns_zone_refresh dns_zone_rekey dns_zone_replacedb dns_zone_setacache +dns_zone_setadded dns_zone_setalsonotify dns_zone_setaltxfrsource4 dns_zone_setaltxfrsource6 diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 155f44bf..5a6f02cd 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.540.2.26 2010/06/02 01:00:28 marka Exp $ */ +/* $Id: zone.c,v 1.540.2.29 2010/08/16 23:46:30 tbox Exp $ */ /*! \file */ @@ -317,6 +317,11 @@ struct dns_zone { * Autosigning/key-maintenance options */ isc_uint32_t keyopts; + + /*% + * True if added by "rndc addzone" + */ + isc_boolean_t added; }; #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0)) @@ -827,6 +832,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->signatures = 10; zone->nodes = 100; zone->privatetype = (dns_rdatatype_t)0xffffU; + zone->added = ISC_FALSE; zone->magic = ZONE_MAGIC; @@ -13724,6 +13730,36 @@ clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, return (result); } +/* + * Given an RRSIG rdataset and an algorithm, determine whether there + * are any signatures using that algorithm. + */ +static isc_boolean_t +signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) { + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_rrsig_t rrsig; + isc_result_t result; + + REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig); + if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) { + return (ISC_FALSE); + } + + for (result = dns_rdataset_first(rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(rdataset)) + { + dns_rdataset_current(rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &rrsig, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_rdata_reset(&rdata); + if (rrsig.algorithm == alg) + return (ISC_TRUE); + } + + return (ISC_FALSE); +} + static void zone_rekey(dns_zone_t *zone) { isc_result_t result; @@ -13735,12 +13771,14 @@ zone_rekey(dns_zone_t *zone) { dns_dnsseckey_t *key; dns_diff_t diff; isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE; + isc_boolean_t fullsign; dns_ttl_t ttl = 3600; const char *dir; isc_mem_t *mctx; isc_stdtime_t now; isc_time_t timenow; isc_interval_t ival; + char timebuf[80]; REQUIRE(DNS_ZONE_VALID(zone)); @@ -13783,6 +13821,12 @@ zone_rekey(dns_zone_t *zone) { } else if (result != ISC_R_NOTFOUND) goto failure; + /* + * True when called from "rndc sign". Indicates the zone should be + * fully signed now. + */ + fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0); + result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys); if (result == ISC_R_SUCCESS) { isc_boolean_t check_ksk; @@ -13812,7 +13856,7 @@ zone_rekey(dns_zone_t *zone) { } } - if ((newactive || !ISC_LIST_EMPTY(diff.tuples)) && + if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) && dnskey_sane(zone, db, ver, &diff)) { CHECK(dns_diff_apply(&diff, db, ver)); CHECK(clean_nsec3param(zone, db, ver, &diff)); @@ -13833,6 +13877,8 @@ zone_rekey(dns_zone_t *zone) { if (commit) { isc_time_t timenow; dns_difftuple_t *tuple; + isc_boolean_t newkey = ISC_FALSE; + isc_boolean_t newalg = ISC_FALSE; LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); @@ -13842,33 +13888,126 @@ zone_rekey(dns_zone_t *zone) { TIME_NOW(&timenow); zone_settimer(zone, &timenow); + /* + * Has a new key become active? If so, is it for + * a new algorithm? + */ for (tuple = ISC_LIST_HEAD(diff.tuples); tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) { dns_rdata_dnskey_t dnskey; - dns_secalg_t algorithm; - isc_region_t r; - isc_uint16_t keyid; if (tuple->rdata.type != dns_rdatatype_dnskey) continue; - result = dns_rdata_tostruct(&tuple->rdata, &dnskey, - NULL); + newkey = ISC_TRUE; + if (!dns_rdataset_isassociated(&keysigs)) { + newalg = ISC_TRUE; + break; + } + + result = dns_rdata_tostruct(&tuple->rdata, + &dnskey, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdata_toregion(&tuple->rdata, &r); - algorithm = dnskey.algorithm; - keyid = dst_region_computeid(&r, algorithm); + if (!signed_with_alg(&keysigs, + dnskey.algorithm)) { + newalg = ISC_TRUE; + break; + } + } - result = zone_signwithkey(zone, algorithm, keyid, - ISC_TF(tuple->op == DNS_DIFFOP_DEL)); - if (result != ISC_R_SUCCESS) { - dns_zone_log(zone, ISC_LOG_ERROR, + /* + * If we found a new algorithm, we need to sign the + * zone fully. If there's a new key, but it's for an + * already-existing algorithm, then the zone signing + * can be handled incrementally. + */ + if (newkey && !newalg) + set_resigntime(zone); + + /* Remove any signatures from removed keys. */ + if (!ISC_LIST_EMPTY(rmkeys)) { + for (key = ISC_LIST_HEAD(rmkeys); + key != NULL; + key = ISC_LIST_NEXT(key, link)) { + result = zone_signwithkey(zone, + dst_key_alg(key->key), + dst_key_id(key->key), + ISC_TRUE); + if (result != ISC_R_SUCCESS) { + dns_zone_log(zone, ISC_LOG_ERROR, "zone_signwithkey failed: %s", - dns_result_totext(result)); + dns_result_totext(result)); + } } } + + if (fullsign) { + /* + * "rndc sign" was called, so we now sign the zone + * with all active keys, whether they're new or not. + */ + for (key = ISC_LIST_HEAD(dnskeys); + key != NULL; + key = ISC_LIST_NEXT(key, link)) { + if (!key->force_sign && !key->hint_sign) + continue; + + result = zone_signwithkey(zone, + dst_key_alg(key->key), + dst_key_id(key->key), + ISC_FALSE); + if (result != ISC_R_SUCCESS) { + dns_zone_log(zone, ISC_LOG_ERROR, + "zone_signwithkey failed: %s", + dns_result_totext(result)); + } + } + } else if (newalg) { + /* + * We haven't been told to sign fully, but a new + * algorithm was added to the DNSKEY. We sign + * the full zone, but only with the newly-added + * keys. + */ + for (tuple = ISC_LIST_HEAD(diff.tuples); + tuple != NULL; + tuple = ISC_LIST_NEXT(tuple, link)) { + dns_rdata_dnskey_t dnskey; + dns_secalg_t algorithm; + isc_region_t r; + isc_uint16_t keyid; + + if (tuple->rdata.type != dns_rdatatype_dnskey || + tuple->op == DNS_DIFFOP_DEL) + continue; + + result = dns_rdata_tostruct(&tuple->rdata, + &dnskey, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_rdata_toregion(&tuple->rdata, &r); + algorithm = dnskey.algorithm; + keyid = dst_region_computeid(&r, algorithm); + + result = zone_signwithkey(zone, algorithm, + keyid, + ISC_TF(tuple->op == + DNS_DIFFOP_DEL)); + if (result != ISC_R_SUCCESS) { + dns_zone_log(zone, ISC_LOG_ERROR, + "zone_signwithkey failed: %s", + dns_result_totext(result)); + } + } + } + + /* + * Clear fullsign flag, if it was set, so we don't do + * another full signing next time + */ + zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN; + /* * Cause the zone to add/delete NSEC3 chains for the * deferred NSEC3PARAM changes. @@ -13933,6 +14072,17 @@ zone_rekey(dns_zone_t *zone) { UNLOCK_ZONE(zone); } + /* + * If no key event is scheduled, we should still check the key + * repository for updates every so often. (Currently this is + * hard-coded to 12 hours, but it could be configurable.) + */ + if (isc_time_isepoch(&zone->refreshkeytime)) + DNS_ZONE_TIME_ADD(&timenow, (3600 * 12), &zone->refreshkeytime); + + isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); + dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); + failure: dns_diff_clear(&diff); @@ -13961,15 +14111,19 @@ zone_rekey(dns_zone_t *zone) { } void -dns_zone_rekey(dns_zone_t *zone) { +dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) { isc_time_t now; if (zone->type == dns_zone_master && zone->task != NULL) { LOCK_ZONE(zone); + if (fullsign) + zone->keyopts |= DNS_ZONEKEY_FULLSIGN; + TIME_NOW(&now); zone->refreshkeytime = now; zone_settimer(zone, &now); + UNLOCK_ZONE(zone); } } @@ -13992,3 +14146,17 @@ dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_db_detachnode(db, &node); return (result); } + +void +dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) { + REQUIRE(DNS_ZONE_VALID(zone)); + LOCK_ZONE(zone); + zone->added = added; + UNLOCK_ZONE(zone); +} + +isc_boolean_t +dns_zone_getadded(dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + return (zone->added); +} diff --git a/lib/isc/api b/lib/isc/api index 692a5f9c..ddd8d2fd 100644 --- a/lib/isc/api +++ b/lib/isc/api @@ -1,3 +1,3 @@ -LIBINTERFACE = 61 -LIBREVISION = 6 -LIBAGE = 1 +LIBINTERFACE = 62 +LIBREVISION = 0 +LIBAGE = 0 diff --git a/lib/isc/entropy.c b/lib/isc/entropy.c index 2d817c6a..8b24c7b1 100644 --- a/lib/isc/entropy.c +++ b/lib/isc/entropy.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: entropy.c,v 1.20 2009/01/18 23:48:14 tbox Exp $ */ +/* $Id: entropy.c,v 1.20.186.2 2010/08/10 23:47:45 tbox Exp $ */ /*! \file * \brief @@ -283,8 +283,11 @@ entropypool_add_word(isc_entropypool_t *rp, isc_uint32_t val) { val ^= rp->pool[(rp->cursor + TAP3) & (RND_POOLWORDS - 1)]; val ^= rp->pool[(rp->cursor + TAP4) & (RND_POOLWORDS - 1)]; val ^= rp->pool[(rp->cursor + TAP5) & (RND_POOLWORDS - 1)]; - rp->pool[rp->cursor++] ^= - ((val << rp->rotate) | (val >> (32 - rp->rotate))); + if (rp->rotate == 0) + rp->pool[rp->cursor++] ^= val; + else + rp->pool[rp->cursor++] ^= + ((val << rp->rotate) | (val >> (32 - rp->rotate))); /* * If we have looped around the pool, increment the rotate diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h index f2aa11e0..b51b03a8 100644 --- a/lib/isc/include/isc/mem.h +++ b/lib/isc/include/isc/mem.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: mem.h,v 1.86.102.2 2010/03/04 23:49:20 tbox Exp $ */ +/* $Id: mem.h,v 1.86.102.3 2010/08/11 22:56:59 jinmei Exp $ */ #ifndef ISC_MEM_H #define ISC_MEM_H 1 @@ -224,6 +224,7 @@ typedef struct isc_memmethods { void *water_arg, size_t hiwater, size_t lowater); void (*waterack)(isc_mem_t *ctx, int flag); size_t (*inuse)(isc_mem_t *mctx); + isc_boolean_t (*isovermem)(isc_mem_t *mctx); isc_result_t (*mpcreate)(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp); } isc_memmethods_t; @@ -420,6 +421,14 @@ isc_mem_inuse(isc_mem_t *mctx); * allocated from the system but not yet used. */ +isc_boolean_t +isc_mem_isovermem(isc_mem_t *mctx); +/*%< + * Return true iff the memory context is in "over memory" state, i.e., + * a hiwater mark has been set and the used amount of memory has exceeds + * the mark. + */ + void isc_mem_setwater(isc_mem_t *mctx, isc_mem_water_t water, void *water_arg, size_t hiwater, size_t lowater); diff --git a/lib/isc/include/isc/namespace.h b/lib/isc/include/isc/namespace.h index 4fa05ac4..1e9e1229 100644 --- a/lib/isc/include/isc/namespace.h +++ b/lib/isc/include/isc/namespace.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namespace.h,v 1.5 2009/10/01 01:30:01 sar Exp $ */ +/* $Id: namespace.h,v 1.5.62.2 2010/08/13 23:46:28 tbox Exp $ */ #ifndef ISCAPI_NAMESPACE_H #define ISCAPI_NAMESPACE_H 1 @@ -67,6 +67,7 @@ #define isc_mem_getquota isc__mem_getquota #define isc_mem_gettag isc__mem_gettag #define isc_mem_inuse isc__mem_inuse +#define isc_mem_isovermem isc__mem_isovermem #define isc_mem_setname isc__mem_setname #define isc_mem_setwater isc__mem_setwater #define isc_mem_printallactive isc__mem_printallactive diff --git a/lib/isc/mem.c b/lib/isc/mem.c index 5e867f0d..4e20f8f2 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: mem.c,v 1.153.104.3 2010/05/12 00:49:31 marka Exp $ */ +/* $Id: mem.c,v 1.153.104.6 2010/08/11 23:46:20 tbox Exp $ */ /*! \file */ @@ -144,6 +144,7 @@ struct isc__mem { size_t hi_water; size_t lo_water; isc_boolean_t hi_called; + isc_boolean_t is_overmem; isc_mem_water_t water; void * water_arg; ISC_LIST(isc__mempool_t) pools; @@ -269,6 +270,8 @@ ISC_MEMFUNC_SCOPE size_t isc__mem_getquota(isc_mem_t *ctx); ISC_MEMFUNC_SCOPE size_t isc__mem_inuse(isc_mem_t *ctx); +ISC_MEMFUNC_SCOPE isc_boolean_t +isc__mem_isovermem(isc_mem_t *ctx); ISC_MEMFUNC_SCOPE void isc__mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg, size_t hiwater, size_t lowater); @@ -345,6 +348,7 @@ static struct isc__memmethods { isc__mem_setwater, isc__mem_waterack, isc__mem_inuse, + isc__mem_isovermem, isc__mempool_create } #ifndef BIND9 @@ -939,6 +943,7 @@ isc__mem_createx2(size_t init_max_size, size_t target_size, ctx->hi_water = 0; ctx->lo_water = 0; ctx->hi_called = ISC_FALSE; + ctx->is_overmem = ISC_FALSE; ctx->water = NULL; ctx->water_arg = NULL; ctx->common.impmagic = MEM_MAGIC; @@ -1281,6 +1286,10 @@ isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) { } ADD_TRACE(ctx, ptr, size, file, line); + if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water && + !ctx->is_overmem) { + ctx->is_overmem = ISC_TRUE; + } if (ctx->hi_water != 0U && !ctx->hi_called && ctx->inuse > ctx->hi_water) { call_water = ISC_TRUE; @@ -1338,6 +1347,10 @@ isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) { * when the context was pushed over hi_water but then had * isc_mem_setwater() called with 0 for hi_water and lo_water. */ + if (ctx->is_overmem && + (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) { + ctx->is_overmem = ISC_FALSE; + } if (ctx->hi_called && (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) { if (ctx->water != NULL) @@ -1529,6 +1542,11 @@ isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) { #if ISC_MEM_TRACKLINES ADD_TRACE(ctx, si, si[-1].u.size, file, line); #endif + if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water && + !ctx->is_overmem) { + ctx->is_overmem = ISC_TRUE; + } + if (ctx->hi_water != 0U && !ctx->hi_called && ctx->inuse > ctx->hi_water) { ctx->hi_called = ISC_TRUE; @@ -1619,6 +1637,11 @@ isc___mem_free(isc_mem_t *ctx0, void *ptr FLARG) { * when the context was pushed over hi_water but then had * isc_mem_setwater() called with 0 for hi_water and lo_water. */ + if (ctx->is_overmem && + (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) { + ctx->is_overmem = ISC_FALSE; + } + if (ctx->hi_called && (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) { ctx->hi_called = ISC_FALSE; @@ -1753,6 +1776,20 @@ isc__mem_setwater(isc_mem_t *ctx0, isc_mem_water_t water, void *water_arg, (oldwater)(oldwater_arg, ISC_MEM_LOWATER); } +ISC_MEMFUNC_SCOPE isc_boolean_t +isc__mem_isovermem(isc_mem_t *ctx0) { + isc__mem_t *ctx = (isc__mem_t *)ctx0; + + REQUIRE(VALID_CONTEXT(ctx)); + + /* + * We don't bother to lock the context because 100% accuracy isn't + * necessary (and even if we locked the context the returned value + * could be different from the actual state when it's used anyway) + */ + return (ctx->is_overmem); +} + ISC_MEMFUNC_SCOPE void isc__mem_setname(isc_mem_t *ctx0, const char *name, void *tag) { isc__mem_t *ctx = (isc__mem_t *)ctx0; diff --git a/lib/isc/mem_api.c b/lib/isc/mem_api.c index fdff49a8..74e52f79 100644 --- a/lib/isc/mem_api.c +++ b/lib/isc/mem_api.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: mem_api.c,v 1.5.104.2 2010/04/09 23:49:48 tbox Exp $ */ +/* $Id: mem_api.c,v 1.5.104.3 2010/08/12 21:31:33 jinmei Exp $ */ #include @@ -199,6 +199,13 @@ isc_mem_inuse(isc_mem_t *mctx) { return (mctx->methods->inuse(mctx)); } +isc_boolean_t +isc_mem_isovermem(isc_mem_t *mctx) { + REQUIRE(ISCAPI_MCTX_VALID(mctx)); + + return (mctx->methods->isovermem(mctx)); +} + void isc_mem_setname(isc_mem_t *mctx, const char *name, void *tag) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); diff --git a/lib/isc/win32/libisc.def b/lib/isc/win32/libisc.def index 509eef5e..1316ffe1 100644 --- a/lib/isc/win32/libisc.def +++ b/lib/isc/win32/libisc.def @@ -58,6 +58,7 @@ isc__mem_getname isc__mem_getquota isc__mem_gettag isc__mem_inuse +isc__mem_isovermem isc__mem_ondestroy isc__mem_references isc__mem_setdestroycheck diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index 14e2e6ff..08c1d8d3 100644 --- a/lib/isc/win32/socket.c +++ b/lib/isc/win32/socket.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.c,v 1.81 2009/11/10 18:31:47 each Exp $ */ +/* $Id: socket.c,v 1.81.22.1 2010/08/16 22:55:17 marka Exp $ */ /* This code uses functions which are only available on Server 2003 and * higher, and Windows XP and higher. @@ -2439,7 +2439,8 @@ SocketIoThread(LPVOID ThreadContext) { send_recvdone_abort(sock, isc_result); if ((isc_result == ISC_R_UNEXPECTED) || ((isc_result == ISC_R_CONNECTIONRESET) && - (errstatus != ERROR_OPERATION_ABORTED)) || + (errstatus != ERROR_OPERATION_ABORTED) && + (errstatus != ERROR_CONNECTION_ABORTED)) || (isc_result == ISC_R_HOSTUNREACH)) { UNEXPECTED_ERROR(__FILE__, __LINE__, "SOCKET_RECV: Windows error code: %d, returning ISC error %d", diff --git a/lib/isccfg/aclconf.c b/lib/isccfg/aclconf.c index 0a240e98..9def19ff 100644 --- a/lib/isccfg/aclconf.c +++ b/lib/isccfg/aclconf.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: aclconf.c,v 1.27 2009/10/01 23:48:08 tbox Exp $ */ +/* $Id: aclconf.c,v 1.27.62.2 2010/08/13 23:46:28 tbox Exp $ */ #include @@ -39,7 +39,7 @@ cfg_aclconfctx_init(cfg_aclconfctx_t *ctx) { } void -cfg_aclconfctx_destroy(cfg_aclconfctx_t *ctx) { +cfg_aclconfctx_clear(cfg_aclconfctx_t *ctx) { dns_acl_t *dacl, *next; for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache); @@ -51,6 +51,23 @@ cfg_aclconfctx_destroy(cfg_aclconfctx_t *ctx) { } } +void +cfg_aclconfctx_clone(cfg_aclconfctx_t *src, cfg_aclconfctx_t *dest) { + dns_acl_t *dacl, *next; + REQUIRE(src != NULL && dest != NULL); + + cfg_aclconfctx_init(dest); + for (dacl = ISC_LIST_HEAD(src->named_acl_cache); + dacl != NULL; + dacl = next) + { + dns_acl_t *copy; + next = ISC_LIST_NEXT(dacl, nextincache); + dns_acl_attach(dacl, ©); + ISC_LIST_APPEND(dest->named_acl_cache, copy, nextincache); + } +} + /* * Find the definition of the named acl whose name is "name". */ diff --git a/lib/isccfg/api b/lib/isccfg/api index 5146f4d5..ddd8d2fd 100644 --- a/lib/isccfg/api +++ b/lib/isccfg/api @@ -1,3 +1,3 @@ -LIBINTERFACE = 61 +LIBINTERFACE = 62 LIBREVISION = 0 -LIBAGE = 1 +LIBAGE = 0 diff --git a/lib/isccfg/include/isccfg/aclconf.h b/lib/isccfg/include/isccfg/aclconf.h index 7ad4351f..829342ed 100644 --- a/lib/isccfg/include/isccfg/aclconf.h +++ b/lib/isccfg/include/isccfg/aclconf.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: aclconf.h,v 1.10 2007/10/12 04:17:18 each Exp $ */ +/* $Id: aclconf.h,v 1.10.470.2 2010/08/13 23:46:28 tbox Exp $ */ #ifndef ISCCFG_ACLCONF_H #define ISCCFG_ACLCONF_H 1 @@ -44,9 +44,15 @@ cfg_aclconfctx_init(cfg_aclconfctx_t *ctx); */ void -cfg_aclconfctx_destroy(cfg_aclconfctx_t *ctx); +cfg_aclconfctx_clone(cfg_aclconfctx_t *src, cfg_aclconfctx_t *dest); /* - * Destroy an ACL configuration context. + * Copy the contents of one ACL configuration context into another. + */ + +void +cfg_aclconfctx_clear(cfg_aclconfctx_t *ctx); +/* + * Clear the contents of an ACL configuration context. */ isc_result_t diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h index d0ed94b8..4a9bab77 100644 --- a/lib/isccfg/include/isccfg/cfg.h +++ b/lib/isccfg/include/isccfg/cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cfg.h,v 1.44 2007/10/12 04:17:18 each Exp $ */ +/* $Id: cfg.h,v 1.44.470.2 2010/08/13 23:46:29 tbox Exp $ */ #ifndef ISCCFG_CFG_H #define ISCCFG_CFG_H 1 @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -70,7 +71,7 @@ typedef struct cfg_obj cfg_obj_t; typedef struct cfg_listelt cfg_listelt_t; /*% - * A callback function to be called when parsing an option + * A callback function to be called when parsing an option * that needs to be interpreted at parsing time, like * "directory". */ @@ -83,6 +84,12 @@ typedef isc_result_t ISC_LANG_BEGINDECLS +void +cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest); +/*%< + * Reference a parser object. + */ + isc_result_t cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret); /*%< @@ -123,7 +130,7 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, * (isc_parse_buffer()). * * Returns an error if the file does not parse correctly. - * + * * Requires: *\li "filename" is valid. *\li "mem" is valid. @@ -140,13 +147,14 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, void cfg_parser_destroy(cfg_parser_t **pctxp); /*%< - * Destroy a configuration parser. + * Remove a reference to a configuration parser; destroy it if there are no + * more references. */ isc_boolean_t cfg_obj_isvoid(const cfg_obj_t *obj); /*%< - * Return true iff 'obj' is of void type (e.g., an optional + * Return true iff 'obj' is of void type (e.g., an optional * value not specified). */ @@ -355,7 +363,7 @@ cfg_list_length(const cfg_obj_t *obj, isc_boolean_t recurse); * all contained lists. */ -const cfg_obj_t * +cfg_obj_t * cfg_listelt_value(const cfg_listelt_t *elt); /*%< * Returns the configuration object associated with cfg_listelt_t. @@ -389,17 +397,25 @@ cfg_print_grammar(const cfg_type_t *type, isc_boolean_t cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type); /*%< - * Return true iff 'obj' is of type 'type'. + * Return true iff 'obj' is of type 'type'. */ -void cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj); +void +cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest); +/*%< + * Reference a configuration object. + */ + +void +cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj); /*%< - * Destroy a configuration object. + * Delete a reference to a configuration object; destroy the object if + * there are no more references. */ void cfg_obj_log(const cfg_obj_t *obj, isc_log_t *lctx, int level, - const char *fmt, ...) + const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); /*%< * Log a message concerning configuration object 'obj' to the logging diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h index dc3cffb9..021343a2 100644 --- a/lib/isccfg/include/isccfg/grammar.h +++ b/lib/isccfg/include/isccfg/grammar.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: grammar.h,v 1.19.136.2 2010/06/23 23:46:36 tbox Exp $ */ +/* $Id: grammar.h,v 1.19.136.3 2010/08/11 18:19:58 each Exp $ */ #ifndef ISCCFG_GRAMMAR_H #define ISCCFG_GRAMMAR_H 1 @@ -159,6 +159,7 @@ struct cfg_obj { isc_sockaddr_t sockaddr; cfg_netprefix_t netprefix; } value; + isc_refcount_t references; /*%< reference counter */ const char * file; unsigned int line; }; @@ -218,6 +219,9 @@ struct cfg_parser { */ unsigned int flags; + /*%< Reference counter */ + isc_refcount_t references; + cfg_parsecallback_t callback; void *callbackarg; }; diff --git a/lib/isccfg/include/isccfg/namedconf.h b/lib/isccfg/include/isccfg/namedconf.h index ea68bf62..37a8c9ed 100644 --- a/lib/isccfg/include/isccfg/namedconf.h +++ b/lib/isccfg/include/isccfg/namedconf.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.h,v 1.15.120.2 2010/07/11 23:46:36 tbox Exp $ */ +/* $Id: namedconf.h,v 1.15.120.3 2010/08/11 18:19:59 each Exp $ */ #ifndef ISCCFG_NAMEDCONF_H #define ISCCFG_NAMEDCONF_H 1 @@ -36,6 +36,9 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_namedconf; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_bindkeys; /*%< A bind.keys file. */ +LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_newzones; +/*%< A new-zones file (for zones added by 'rndc addzone'). */ + LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_addzoneconf; /*%< A single zone passed via the addzone rndc command. */ diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 926f2b4e..69ccd28f 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.113.4.9 2010/07/11 23:46:36 tbox Exp $ */ +/* $Id: namedconf.c,v 1.113.4.10 2010/08/11 18:19:58 each Exp $ */ /*! \file */ @@ -101,7 +101,6 @@ static cfg_type_t cfg_type_negated; static cfg_type_t cfg_type_notifytype; static cfg_type_t cfg_type_optional_allow; static cfg_type_t cfg_type_optional_class; -static cfg_type_t cfg_type_optional_qstring; static cfg_type_t cfg_type_optional_facility; static cfg_type_t cfg_type_optional_keyref; static cfg_type_t cfg_type_optional_port; @@ -832,8 +831,6 @@ bindkeys_clauses[] = { */ static cfg_clausedef_t options_clauses[] = { - { "use-v4-udp-ports", &cfg_type_bracketed_portlist, 0 }, - { "use-v6-udp-ports", &cfg_type_bracketed_portlist, 0 }, { "avoid-v4-udp-ports", &cfg_type_bracketed_portlist, 0 }, { "avoid-v6-udp-ports", &cfg_type_bracketed_portlist, 0 }, { "bindkeys-file", &cfg_type_qstring, 0 }, @@ -848,6 +845,7 @@ options_clauses[] = { { "dump-file", &cfg_type_qstring, 0 }, { "fake-iquery", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "files", &cfg_type_size, 0 }, + { "flush-zones-on-shutdown", &cfg_type_boolean, 0 }, { "has-old-clients", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "heartbeat-interval", &cfg_type_uint32, 0 }, { "host-statistics", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTIMP }, @@ -887,8 +885,9 @@ options_clauses[] = { { "treat-cr-as-space", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "use-id-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "use-ixfr", &cfg_type_boolean, 0 }, + { "use-v4-udp-ports", &cfg_type_bracketed_portlist, 0 }, + { "use-v6-udp-ports", &cfg_type_bracketed_portlist, 0 }, { "version", &cfg_type_qstringornone, 0 }, - { "flush-zones-on-shutdown", &cfg_type_boolean, 0 }, { NULL, NULL, 0 } }; @@ -996,6 +995,7 @@ view_clauses[] = { { "acache-enable", &cfg_type_boolean, 0 }, { "additional-from-auth", &cfg_type_boolean, 0 }, { "additional-from-cache", &cfg_type_boolean, 0 }, + { "allow-new-zones", &cfg_type_boolean, 0 }, { "allow-query-cache", &cfg_type_bracketed_aml, 0 }, { "allow-query-cache-on", &cfg_type_bracketed_aml, 0 }, { "allow-recursion", &cfg_type_bracketed_aml, 0 }, @@ -1058,7 +1058,6 @@ view_clauses[] = { { "transfer-format", &cfg_type_transferformat, 0 }, { "use-queryport-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "zero-no-soa-ttl-cache", &cfg_type_boolean, 0 }, - { "new-zone-file", &cfg_type_qstringornone, 0 }, #ifdef ALLOW_FILTER_AAAA_ON_V4 { "filter-aaaa", &cfg_type_bracketed_aml, 0 }, { "filter-aaaa-on-v4", &cfg_type_v4_aaaa, 0 }, @@ -1236,6 +1235,24 @@ LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_bindkeys = { &cfg_rep_map, bindkeys_clausesets }; +/*% The new-zone-file syntax (for zones added by 'rndc addzone') */ +static cfg_clausedef_t +newzones_clauses[] = { + { "zone", &cfg_type_zone, CFG_CLAUSEFLAG_MULTI }, + { NULL, NULL, 0 } +}; + +static cfg_clausedef_t * +newzones_clausesets[] = { + newzones_clauses, + NULL +}; + +LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_newzones = { + "newzones", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, + &cfg_rep_map, newzones_clausesets +}; + /*% The "options" statement syntax. */ static cfg_clausedef_t * @@ -1402,11 +1419,7 @@ static cfg_type_t cfg_type_logging = { * For parsing an 'addzone' statement */ -/*% - * A zone statement. - */ static cfg_tuplefielddef_t addzone_fields[] = { - { "filepart", &cfg_type_optional_qstring, 0 }, { "name", &cfg_type_astring, 0 }, { "class", &cfg_type_optional_class, 0 }, { "view", &cfg_type_optional_class, 0 }, @@ -1836,30 +1849,6 @@ static cfg_type_t cfg_type_optional_class = { NULL, NULL }; -/*% - * An optional string, distinguished by being in quotes - */ -static isc_result_t -parse_optional_qstr(cfg_parser_t *pctx, const cfg_type_t *type, - cfg_obj_t **ret) -{ - isc_result_t result; - UNUSED(type); - CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); - if (pctx->token.type == isc_tokentype_qstring) - CHECK(cfg_parse_obj(pctx, &cfg_type_qstring, ret)); - else - CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret)); - cleanup: - return (result); -} - - -static cfg_type_t cfg_type_optional_qstring = { - "optional_quoted_string", parse_optional_qstr, NULL, cfg_doc_terminal, - NULL, NULL -}; - static isc_result_t parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index a0f4c94d..8072cd82 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: parser.c,v 1.132.104.2 2010/06/23 23:46:36 tbox Exp $ */ +/* $Id: parser.c,v 1.132.104.3 2010/08/11 18:19:58 each Exp $ */ /*! \file */ @@ -387,6 +387,12 @@ cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) { if (pctx == NULL) return (ISC_R_NOMEMORY); + result = isc_refcount_init(&pctx->references, 1); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, pctx, sizeof(*pctx)); + return (result); + } + pctx->mctx = mctx; pctx->lctx = lctx; pctx->lexer = NULL; @@ -526,18 +532,31 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, return (result); } +void +cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest) { + REQUIRE(src != NULL); + REQUIRE(dest != NULL && *dest == NULL); + isc_refcount_increment(&src->references, NULL); + *dest = src; +} + void cfg_parser_destroy(cfg_parser_t **pctxp) { cfg_parser_t *pctx = *pctxp; - isc_lex_destroy(&pctx->lexer); - /* - * Cleaning up open_files does not - * close the files; that was already done - * by closing the lexer. - */ - CLEANUP_OBJ(pctx->open_files); - CLEANUP_OBJ(pctx->closed_files); - isc_mem_put(pctx->mctx, pctx, sizeof(*pctx)); + unsigned int refs; + + isc_refcount_decrement(&pctx->references, &refs); + if (refs == 0) { + isc_lex_destroy(&pctx->lexer); + /* + * Cleaning up open_files does not + * close the files; that was already done + * by closing the lexer. + */ + CLEANUP_OBJ(pctx->open_files); + CLEANUP_OBJ(pctx->closed_files); + isc_mem_put(pctx->mctx, pctx, sizeof(*pctx)); + } *pctxp = NULL; } @@ -1133,7 +1152,7 @@ cfg_list_length(const cfg_obj_t *obj, isc_boolean_t recurse) { return (count); } -const cfg_obj_t * +cfg_obj_t * cfg_listelt_value(const cfg_listelt_t *elt) { REQUIRE(elt != NULL); return (elt->obj); @@ -2315,6 +2334,7 @@ cfg_obj_line(const cfg_obj_t *obj) { isc_result_t cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { + isc_result_t result; cfg_obj_t *obj; obj = isc_mem_get(pctx->mctx, sizeof(cfg_obj_t)); @@ -2323,10 +2343,16 @@ cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { obj->type = type; obj->file = current_file(pctx); obj->line = pctx->line; + result = isc_refcount_init(&obj->references, 1); + if (result != ISC_R_SUCCESS) { + isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t)); + return (result); + } *ret = obj; return (ISC_R_SUCCESS); } + static void map_symtabitem_destroy(char *key, unsigned int type, isc_symvalue_t symval, void *userarg) @@ -2380,11 +2406,25 @@ cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type) { void cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) { cfg_obj_t *obj = *objp; - obj->type->rep->free(pctx, obj); - isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t)); + unsigned int refs; + + isc_refcount_decrement(&obj->references, &refs); + if (refs == 0) { + obj->type->rep->free(pctx, obj); + isc_refcount_destroy(&obj->references); + isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t)); + } *objp = NULL; } +void +cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest) { + REQUIRE(src != NULL); + REQUIRE(dest != NULL && *dest == NULL); + isc_refcount_increment(&src->references, NULL); + *dest = src; +} + static void free_noop(cfg_parser_t *pctx, cfg_obj_t *obj) { UNUSED(pctx); diff --git a/lib/isccfg/win32/libisccfg.def b/lib/isccfg/win32/libisccfg.def index a06232b8..0e7260e0 100644 --- a/lib/isccfg/win32/libisccfg.def +++ b/lib/isccfg/win32/libisccfg.def @@ -4,7 +4,8 @@ LIBRARY libisccfg EXPORTS cfg_acl_fromconfig -cfg_aclconfctx_destroy +cfg_aclconfctx_clear +cfg_aclconfctx_clone cfg_aclconfctx_init cfg_list_first cfg_list_next @@ -18,6 +19,7 @@ cfg_obj_assockaddr cfg_obj_asstring cfg_obj_asuint32 cfg_obj_asuint64 +cfg_obj_attach cfg_obj_destroy cfg_obj_file cfg_obj_isboolean @@ -35,6 +37,7 @@ cfg_obj_line cfg_obj_log cfg_parse_buffer cfg_parse_file +cfg_parser_attach cfg_parser_create cfg_parser_destroy cfg_parser_setcallback diff --git a/lib/lwres/api b/lib/lwres/api index 3252b3bf..25708f02 100644 --- a/lib/lwres/api +++ b/lib/lwres/api @@ -1,3 +1,3 @@ LIBINTERFACE = 60 -LIBREVISION = 0 +LIBREVISION = 1 LIBAGE = 0 diff --git a/lib/lwres/print_p.h b/lib/lwres/print_p.h index c22b44a1..42ed36c7 100644 --- a/lib/lwres/print_p.h +++ b/lib/lwres/print_p.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2007, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: print_p.h,v 1.4 2007/06/19 23:47:22 tbox Exp $ */ +/* $Id: print_p.h,v 1.4.558.2 2010/08/16 23:46:31 tbox Exp $ */ #ifndef LWRES_PRINT_P_H #define LWRES_PRINT_P_H 1 @@ -47,7 +47,7 @@ #ifdef __GNUC__ #define LWRES_FORMAT_PRINTF(fmt, args) \ - __attribute__((__format__(__printf__, fmt, args))) + __attribute__((__format__(__printf__, fmt, args))) #else #define LWRES_FORMAT_PRINTF(fmt, args) #endif @@ -67,17 +67,26 @@ LWRES_LANG_BEGINDECLS int lwres__print_vsnprintf(char *str, size_t size, const char *format, va_list ap) LWRES_FORMAT_PRINTF(3, 0); +#ifdef vsnprintf +#undef vsnprintf +#endif #define vsnprintf lwres__print_vsnprintf int lwres__print_snprintf(char *str, size_t size, const char *format, ...) LWRES_FORMAT_PRINTF(3, 4); +#ifdef snprintf +#undef snprintf +#endif #define snprintf lwres__print_snprintf #endif /* LWRES_PLATFORM_NEEDVSNPRINTF */ #ifdef LWRES_PLATFORM_NEEDSPRINTF int lwres__print_sprintf(char *str, const char *format, ...) LWRES_FORMAT_PRINTF(2, 3); +#ifdef sprintf +#undef sprintf +#endif #define sprintf lwres__print_sprintf #endif -- cgit v1.2.3