summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorInternet Software Consortium, Inc <@isc.org>2010-10-08 08:25:08 -0600
committerInternet Software Consortium, Inc <@isc.org>2010-10-08 08:25:08 -0600
commit887d4bc542def2306e66dc3dd26a9f51b92a9aa1 (patch)
treeb2e1fd5cf45db770490a28c6587cc291fb452fb1 /lib
parent274f3a9719ec6152a42ab768cbec525395b61a93 (diff)
downloadbind9-887d4bc542def2306e66dc3dd26a9f51b92a9aa1.tar.gz
v9.7.2
Diffstat (limited to 'lib')
-rw-r--r--lib/bind9/api2
-rw-r--r--lib/bind9/check.c6
-rw-r--r--lib/dns/adb.c51
-rw-r--r--lib/dns/api2
-rw-r--r--lib/dns/include/dns/view.h31
-rw-r--r--lib/dns/include/dns/zone.h31
-rw-r--r--lib/dns/rbtdb.c80
-rw-r--r--lib/dns/sdb.c9
-rw-r--r--lib/dns/sdlz.c9
-rw-r--r--lib/dns/view.c44
-rw-r--r--lib/dns/win32/libdns.def3
-rw-r--r--lib/dns/zone.c200
-rw-r--r--lib/isc/api6
-rw-r--r--lib/isc/entropy.c11
-rw-r--r--lib/isc/include/isc/mem.h11
-rw-r--r--lib/isc/include/isc/namespace.h5
-rw-r--r--lib/isc/mem.c39
-rw-r--r--lib/isc/mem_api.c9
-rw-r--r--lib/isc/win32/libisc.def1
-rw-r--r--lib/isc/win32/socket.c7
-rw-r--r--lib/isccfg/aclconf.c23
-rw-r--r--lib/isccfg/api4
-rw-r--r--lib/isccfg/include/isccfg/aclconf.h14
-rw-r--r--lib/isccfg/include/isccfg/cfg.h38
-rw-r--r--lib/isccfg/include/isccfg/grammar.h6
-rw-r--r--lib/isccfg/include/isccfg/namedconf.h5
-rw-r--r--lib/isccfg/namedconf.c57
-rw-r--r--lib/isccfg/parser.c66
-rw-r--r--lib/isccfg/win32/libisccfg.def5
-rw-r--r--lib/lwres/api2
-rw-r--r--lib/lwres/print_p.h15
31 files changed, 602 insertions, 190 deletions
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 */
@@ -837,13 +837,6 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
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.
*/
dns_name_getlabelsequence(name, nlabels - i, i, xname);
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 */
@@ -801,13 +801,6 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
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.
*/
dns_name_getlabelsequence(name, nlabels - i, i, xname);
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 <config.h>
#include <isc/hash.h>
+#include <isc/sha2.h>
#include <isc/stats.h>
#include <isc/string.h> /* Required for HP/UX (and others?) */
#include <isc/task.h>
@@ -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 <config.h>
@@ -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 <config.h>
@@ -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, &copy);
+ 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 <isc/formatcheck.h>
#include <isc/lang.h>
+#include <isc/refcount.h>
#include <isc/types.h>
#include <isc/list.h>
@@ -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;
@@ -527,17 +533,30 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer,
}
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