BIND 10 trac832, updated. f82fbc6020cbdab281310bc7e51c79d7a96da8c4 [trac832] trivial changes to compile/run over Windows.

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Apr 6 14:41:05 UTC 2011


The branch, trac832 has been updated
       via  f82fbc6020cbdab281310bc7e51c79d7a96da8c4 (commit)
       via  e7d0dbd6ba745bab334aef6e747056c33f5edaa8 (commit)
       via  7c1e4d5e1e28e556b1d10a8df8d9486971a3f052 (commit)
       via  4929dc565823e49c94b1efea1543ba23d9745c9f (commit)
       via  c7bb38c99c9afa049c7336ea3f827aa41a1b2ea0 (commit)
       via  1c269cbdc76f5dc2baeb43387c4d7ccc6dc863d2 (commit)
       via  98e93921ae905aefef6646fc8839e3f4a30a37e1 (commit)
       via  1ec7e1ccd24b25501902e0fc29fddf400f2ebdb1 (commit)
       via  47b51ddc032a458b42454c3ed774bf26ef4254c1 (commit)
       via  c139d4bf6b30d7ad9325c7a621911c9455826f6b (commit)
       via  d8c55247d888cd9f5e2e474e49f8bd97b96623cf (commit)
       via  ba876505740d4782b58169848605af49325b11ed (commit)
       via  4d505b0cef54209575173d52e4f9a3e6e244dab3 (commit)
       via  6ff2a83cb7a6c04a258e84818257fe6eda9634a6 (commit)
       via  682ea37cfb7e20366521fd48fc98826a21344942 (commit)
       via  8d3f576ca98cdd6e821cf76464cd342d42d941a3 (commit)
       via  ddfc6892916bc041e53b79a690abbed10ff99056 (commit)
       via  af0d35e501aab417b9b032069ae1cb8841debab4 (commit)
       via  cf5b24f110a927685226e8ef41378a847b002357 (commit)
       via  5a7c1928eb5b70c2a9739650961bd4e32b6b26ed (commit)
       via  f9a697ab99914d58e7e135ca069b3d5a06c00511 (commit)
       via  320bafb306878cd9f13ba9703a0d4573fb645341 (commit)
       via  0b53561c3b937c5d2585a3c62876b600800815bb (commit)
       via  e111d142cba584e410c5e385c10b714715f55dc4 (commit)
       via  de3c708f962db8fe15287c9a5704d3aa8b257b03 (commit)
       via  9b90408108142c710c2adb403e61af374fe1b24c (commit)
       via  00cb2ff77044b185fe80dcf3f577a9b4793638b0 (commit)
       via  00b37501ae500c81657b1727dfff0105c2202f07 (commit)
       via  7b794844b6afc77cf05bb93828477fe5cc48408d (commit)
       via  75b29aaa4aabf843b0d80400eb2cf8c39c4dd8f0 (commit)
       via  d27da40718b797aca37ad5bab7215592a089627a (commit)
       via  7362cbdfc230a2f8deee2933b78e23bdb4892e98 (commit)
       via  48846bf7b70cc48e317aabc554a4dacef89b2d46 (commit)
      from  6c611b5c04a5484df7269a603be4f00c4f7fa7f2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f82fbc6020cbdab281310bc7e51c79d7a96da8c4
Author: Francis Dupont <fdupont at isc.org>
Date:   Wed Apr 6 16:40:18 2011 +0200

    [trac832] trivial changes to compile/run over Windows.

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                          |   16 +++
 src/bin/auth/Makefile.am                           |    2 +-
 src/bin/auth/{config.cc => auth_config.cc}         |    2 +-
 src/bin/auth/{config.h => auth_config.h}           |    0 
 src/bin/auth/auth_srv.cc                           |    2 +-
 src/bin/auth/auth_srv.h                            |    9 ++
 src/bin/auth/benchmarks/Makefile.am                |    2 +-
 src/bin/auth/benchmarks/query_bench.cc             |    4 +-
 src/bin/auth/main.cc                               |    4 +-
 src/bin/auth/tests/Makefile.am                     |    2 +-
 src/bin/auth/tests/command_unittest.cc             |    4 +-
 src/bin/auth/tests/config_unittest.cc              |    2 +-
 src/bin/bind10/bind10.py.in                        |   22 ++--
 src/bin/bind10/bob.spec                            |    5 +
 src/bin/bind10/tests/bind10_test.py.in             |   40 ++++++-
 src/bin/resolver/main.cc                           |    2 +
 src/bin/resolver/resolver.h                        |   12 ++-
 src/bin/resolver/tests/resolver_config_unittest.cc |    2 +
 src/bin/stats/b10-stats.8                          |   19 +++-
 src/bin/stats/b10-stats.xml                        |    6 +-
 src/bin/stats/stats.py.in                          |   12 ++-
 src/bin/stats/tests/b10-stats_test.py              |   11 ++-
 src/bin/zonemgr/tests/zonemgr_test.py              |  132 +++++++++++++-------
 src/bin/zonemgr/zonemgr.py.in                      |   72 +++++++----
 src/bin/zonemgr/zonemgr.spec.pre.in                |   26 ++++
 src/lib/dns/dnssectime.cc                          |   20 +++
 src/lib/dns/masterload.cc                          |    3 +
 src/lib/dns/messagerenderer.cc                     |    5 +-
 src/lib/dns/rcode.h                                |    2 +
 src/lib/dns/rdata/in_1/a_1.cc                      |   13 ++-
 src/lib/dns/rdata/in_1/aaaa_28.cc                  |   13 ++-
 src/lib/dns/rrclass-placeholder.h                  |    2 +
 src/lib/dns/rrparamregistry-placeholder.cc         |    6 +-
 src/lib/dns/tests/rdata_tsig_unittest.cc           |    2 +-
 src/lib/dns/util/base_n.cc                         |    2 +-
 src/lib/nsas/locks.h                               |    5 -
 src/lib/python/isc/config/config_data.py           |    4 +-
 .../python/isc/config/tests/config_data_test.py    |    4 +-
 src/lib/resolve/resolver_callback.h                |    4 +-
 .../resolve/tests/resolver_callback_unittest.cc    |    2 +-
 src/lib/testutils/srv_test.cc                      |    2 +
 41 files changed, 373 insertions(+), 126 deletions(-)
 rename src/bin/auth/{config.cc => auth_config.cc} (99%)
 rename src/bin/auth/{config.h => auth_config.h} (100%)

-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index b426fb2..447df56 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+  214.  [func]*     vorner
+    Zone manager no longer thinks it is secondary master for all zones in the
+	database They are listed in Zonemgr/secondary_zones configuration variable
+	(in the form [{"name": "example.com", "class": "IN"}]).
+	(Trac #670, 7c1e4d5e1e28e556b1d10a8df8d9486971a3f052)
+
+  213.  [bug]       naokikambe
+	Solved incorrect datetime of "bind10.boot_time" and also added a new
+	command "sendstats" for Bob. This command is to send statistics data to
+	the stats daemon immediately. The solved problem is that statistics
+	data doesn't surely reach to the daemon because Bob sent statistics
+	data to the daemon while it is starting. So the daemon invokes the
+	command for Bob after it starts up. This command is also useful for
+	resending statistics data via bindctl manually.
+	(Trac #521, git 1c269cbdc76f5dc2baeb43387c4d7ccc6dc863d2)
+
   212.  [bug]		naokikambe
 	Fixed that the ModuleCCSession object may group_unsubscribe in the
 	closed CC session in being deleted.
diff --git a/src/bin/auth/Makefile.am b/src/bin/auth/Makefile.am
index cdfc55e..54dc03c 100644
--- a/src/bin/auth/Makefile.am
+++ b/src/bin/auth/Makefile.am
@@ -39,7 +39,7 @@ pkglibexec_PROGRAMS = b10-auth
 b10_auth_SOURCES = query.cc query.h
 b10_auth_SOURCES += auth_srv.cc auth_srv.h
 b10_auth_SOURCES += change_user.cc change_user.h
-b10_auth_SOURCES += config.cc config.h
+b10_auth_SOURCES += auth_config.cc auth_config.h
 b10_auth_SOURCES += command.cc command.h
 b10_auth_SOURCES += common.h
 b10_auth_SOURCES += statistics.cc statistics.h
diff --git a/src/bin/auth/auth_config.cc b/src/bin/auth/auth_config.cc
new file mode 100644
index 0000000..7929d80
--- /dev/null
+++ b/src/bin/auth/auth_config.cc
@@ -0,0 +1,347 @@
+// Copyright (C) 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
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <boost/foreach.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <dns/name.h>
+#include <dns/rrclass.h>
+
+#include <cc/data.h>
+
+#include <datasrc/memory_datasrc.h>
+#include <datasrc/zonetable.h>
+
+#include <auth/auth_srv.h>
+#include <auth/auth_config.h>
+#include <auth/common.h>
+
+#include <server_common/portconfig.h>
+
+using namespace std;
+using boost::shared_ptr;
+using namespace isc::dns;
+using namespace isc::data;
+using namespace isc::datasrc;
+using namespace isc::server_common::portconfig;
+
+namespace {
+// Forward declaration
+AuthConfigParser*
+createAuthConfigParser(AuthSrv& server, const std::string& config_id,
+                       bool internal);
+
+/// A derived \c AuthConfigParser class for the "datasources" configuration
+/// identifier.
+class DatasourcesConfig : public AuthConfigParser {
+public:
+    DatasourcesConfig(AuthSrv& server) : server_(server) {}
+    virtual void build(ConstElementPtr config_value);
+    virtual void commit();
+private:
+    AuthSrv& server_;
+    vector<shared_ptr<AuthConfigParser> > datasources_;
+    set<string> configured_sources_;
+};
+
+void
+DatasourcesConfig::build(ConstElementPtr config_value) {
+    BOOST_FOREACH(ConstElementPtr datasrc_elem, config_value->listValue()) {
+        // The caller is supposed to perform syntax-level checks, but we'll
+        // do minimum level of validation ourselves so that we won't crash due
+        // to a buggy application.
+        ConstElementPtr datasrc_type = datasrc_elem->get("type");
+        if (!datasrc_type) {
+            isc_throw(AuthConfigError, "Missing data source type");
+        }
+
+        if (configured_sources_.find(datasrc_type->stringValue()) !=
+            configured_sources_.end()) {
+            isc_throw(AuthConfigError, "Data source type '" <<
+                      datasrc_type->stringValue() << "' already configured");
+        }
+        
+        shared_ptr<AuthConfigParser> datasrc_config =
+            shared_ptr<AuthConfigParser>(
+                createAuthConfigParser(server_, string("datasources/") +
+                                       datasrc_type->stringValue(),
+                                       true));
+        datasrc_config->build(datasrc_elem);
+        datasources_.push_back(datasrc_config);
+
+        configured_sources_.insert(datasrc_type->stringValue());
+    }
+}
+
+void
+DatasourcesConfig::commit() {
+    // XXX a short term workaround: clear all data sources and then reset
+    // to new ones so that we can remove data sources that don't exist in
+    // the new configuration and have been used in the server.
+    // This could be inefficient and requires knowledge about
+    // server implementation details, and isn't scalable wrt the number of
+    // data source types, and should eventually be improved.
+    // Currently memory data source for class IN is the only possibility.
+    server_.setMemoryDataSrc(RRClass::IN(), AuthSrv::MemoryDataSrcPtr());
+
+    BOOST_FOREACH(shared_ptr<AuthConfigParser> datasrc_config, datasources_) {
+        datasrc_config->commit();
+    }
+}
+
+/// A derived \c AuthConfigParser class for the memory type datasource
+/// configuration.  It does not correspond to the configuration syntax;
+/// it's instantiated for internal use.
+class MemoryDatasourceConfig : public AuthConfigParser {
+public:
+    MemoryDatasourceConfig(AuthSrv& server) :
+        server_(server),
+        rrclass_(0)              // XXX: dummy initial value
+    {}
+    virtual void build(ConstElementPtr config_value);
+    virtual void commit() {
+        server_.setMemoryDataSrc(rrclass_, memory_datasrc_);
+    }
+private:
+    AuthSrv& server_;
+    RRClass rrclass_;
+    AuthSrv::MemoryDataSrcPtr memory_datasrc_;
+};
+
+void
+MemoryDatasourceConfig::build(ConstElementPtr config_value) {
+    // XXX: apparently we cannot retrieve the default RR class from the
+    // module spec.  As a temporary workaround we hardcode the default value.
+    ConstElementPtr rrclass_elem = config_value->get("class");
+    rrclass_ = RRClass(rrclass_elem ? rrclass_elem->stringValue() : "IN");
+
+    // We'd eventually optimize building zones (in case of reloading) by
+    // selectively loading fresh zones.  Right now we simply check the
+    // RR class is supported by the server implementation.
+    server_.getMemoryDataSrc(rrclass_);
+    memory_datasrc_ = AuthSrv::MemoryDataSrcPtr(new MemoryDataSrc());
+
+    ConstElementPtr zones_config = config_value->get("zones");
+    if (!zones_config) {
+        // XXX: Like the RR class, we cannot retrieve the default value here,
+        // so we assume an empty zone list in this case.
+        return;
+    }
+
+    BOOST_FOREACH(ConstElementPtr zone_config, zones_config->listValue()) {
+        ConstElementPtr origin = zone_config->get("origin");
+        if (!origin) {
+            isc_throw(AuthConfigError, "Missing zone origin");
+        }
+        ConstElementPtr file = zone_config->get("file");
+        if (!file) {
+            isc_throw(AuthConfigError, "Missing zone file for zone: "
+                      << origin->str());
+        }
+        shared_ptr<MemoryZone> new_zone(new MemoryZone(rrclass_,
+            Name(origin->stringValue())));
+        const result::Result result = memory_datasrc_->addZone(new_zone);
+        if (result == result::EXIST) {
+            isc_throw(AuthConfigError, "zone "<< origin->str()
+                      << " already exists");
+        }
+
+        /*
+         * TODO: Once we have better reloading of configuration (something
+         * else than throwing everything away and loading it again), we will
+         * need the load method to be split into some kind of build and
+         * commit/abort parts.
+         */
+        new_zone->load(file->stringValue());
+    }
+}
+
+/// A derived \c AuthConfigParser class for the "statistics-internal"
+/// configuration identifier.
+class StatisticsIntervalConfig : public AuthConfigParser {
+public:
+    StatisticsIntervalConfig(AuthSrv& server) :
+        server_(server), interval_(0)
+    {}
+    virtual void build(ConstElementPtr config_value) {
+        const int32_t config_interval = config_value->intValue();
+        if (config_interval < 0) {
+            isc_throw(AuthConfigError, "Negative statistics interval value: "
+                      << config_interval);
+        }
+        if (config_interval > 86400) {
+            isc_throw(AuthConfigError, "Statistics interval value "
+                      << config_interval
+                      << " must be equal to or shorter than 86400");
+        }
+        interval_ = config_interval;
+    }
+    virtual void commit() {
+        // setStatisticsTimerInterval() is not 100% exception free.  But
+        // exceptions should happen only in a very rare situation, so we
+        // let them be thrown and subsequently regard them as a fatal error.
+        server_.setStatisticsTimerInterval(interval_);
+    }
+private:
+    AuthSrv& server_;
+    uint32_t interval_;
+};
+
+/// A special parser for testing: it throws from commit() despite the
+/// suggested convention of the class interface.
+class ThrowerCommitConfig : public AuthConfigParser {
+public:
+    virtual void build(ConstElementPtr) {} // ignore param, do nothing
+    virtual void commit() {
+        throw 10;
+    }
+};
+
+/**
+ * \brief Configuration parser for listen_on.
+ *
+ * It parses and sets the listening addresses of the server.
+ *
+ * It acts in unusual way. Since actually binding (changing) the sockets
+ * is an operation that is expected to throw often, it shouldn't happen
+ * in commit. Thefere we do it in build. But if the config is not committed
+ * then, we would have it wrong. So we store the old addresses and if
+ * commit is not called before destruction of the object, we return the
+ * old addresses (which is the same kind of dangerous operation, but it is
+ * expected that if we just managed to bind some and had the old ones binded
+ * before, it should work).
+ *
+ * We might do something better in future (like open only the ports that are
+ * extra, put them in in commit and close the old ones), but that's left out
+ * for now.
+ */
+class ListenAddressConfig : public AuthConfigParser {
+public:
+    ListenAddressConfig(AuthSrv& server) :
+        server_(server)
+    { }
+    ~ ListenAddressConfig() {
+        if (rollbackAddresses_.get() != NULL) {
+            server_.setListenAddresses(*rollbackAddresses_);
+        }
+    }
+private:
+    typedef auto_ptr<AddressList> AddrListPtr;
+public:
+    virtual void build(ConstElementPtr config) {
+        AddressList newAddresses = parseAddresses(config, "listen_on");
+        AddrListPtr old(new AddressList(server_.getListenAddresses()));
+        server_.setListenAddresses(newAddresses);
+        /*
+         * Set the rollback addresses only after successful setting of the
+         * new addresses, so we don't try to rollback if the setup is
+         * unsuccessful (the above can easily throw).
+         */
+        rollbackAddresses_ = old;
+    }
+    virtual void commit() {
+        rollbackAddresses_.release();
+    }
+private:
+    AuthSrv& server_;
+    /**
+     * This is the old address list, if we expect to roll back. When we commit,
+     * this is set to NULL.
+     */
+    AddrListPtr rollbackAddresses_;
+};
+
+// This is a generalized version of create function that can create
+// an AuthConfigParser object for "internal" use.
+AuthConfigParser*
+createAuthConfigParser(AuthSrv& server, const std::string& config_id,
+                       bool internal)
+{
+    // For the initial implementation we use a naive if-else blocks for
+    // simplicity.  In future we'll probably generalize it using map-like
+    // data structure, and may even provide external register interface so
+    // that it can be dynamically customized.
+    if (config_id == "datasources") {
+        return (new DatasourcesConfig(server));
+    } else if (config_id == "statistics-interval") {
+        return (new StatisticsIntervalConfig(server));
+    } else if (internal && config_id == "datasources/memory") {
+        return (new MemoryDatasourceConfig(server));
+    } else if (config_id == "listen_on") {
+        return (new ListenAddressConfig(server));
+    } else if (config_id == "_commit_throw") {
+        // This is for testing purpose only and should not appear in the
+        // actual configuration syntax.  While this could crash the caller
+        // as a result, the server implementation is expected to perform
+        // syntax level validation and should be safe in practice.  In future,
+        // we may introduce dynamic registration of configuration parsers,
+        // and then this test can be done in a cleaner and safer way.
+        return (new ThrowerCommitConfig());
+    } else {
+        isc_throw(AuthConfigError, "Unknown configuration identifier: " <<
+                  config_id);
+    }
+}
+} // end of unnamed namespace
+
+AuthConfigParser*
+createAuthConfigParser(AuthSrv& server, const std::string& config_id) {
+    return (createAuthConfigParser(server, config_id, false));
+}
+
+void
+configureAuthServer(AuthSrv& server, ConstElementPtr config_set) {
+    if (!config_set) {
+        isc_throw(AuthConfigError,
+                  "Null pointer is passed to configuration parser");
+    }
+
+    typedef shared_ptr<AuthConfigParser> ParserPtr;
+    vector<ParserPtr> parsers;
+    typedef pair<string, ConstElementPtr> ConfigPair;
+    try {
+        BOOST_FOREACH(ConfigPair config_pair, config_set->mapValue()) {
+            // We should eventually integrate the sqlite3 DB configuration to
+            // this framework, but to minimize diff we begin with skipping that
+            // part.
+            if (config_pair.first == "database_file") {
+                continue;
+            }
+
+            ParserPtr parser(createAuthConfigParser(server,
+                                                    config_pair.first));
+            parser->build(config_pair.second);
+            parsers.push_back(parser);
+        }
+    } catch (const AuthConfigError& ex) {
+        throw;                  // simply rethrowing it
+    } catch (const isc::Exception& ex) {
+        isc_throw(AuthConfigError, "Server configuration failed: " <<
+                  ex.what());
+    }
+
+    try {
+        BOOST_FOREACH(ParserPtr parser, parsers) {
+            parser->commit();
+        }
+    } catch (...) {
+        throw FatalError("Unrecoverable error: "
+                         "a configuration parser threw in commit");
+    }
+}
diff --git a/src/bin/auth/auth_config.h b/src/bin/auth/auth_config.h
new file mode 100644
index 0000000..6f18810
--- /dev/null
+++ b/src/bin/auth/auth_config.h
@@ -0,0 +1,202 @@
+// Copyright (C) 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
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <string>
+
+#include <exceptions/exceptions.h>
+
+#include <cc/data.h>
+
+#ifndef __CONFIG_H
+#define __CONFIG_H 1
+
+class AuthSrv;
+
+/// An exception that is thrown if an error occurs while configuring an
+/// \c AuthSrv object.
+class AuthConfigError : public isc::Exception {
+public:
+    AuthConfigError(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
+/// The abstract base class that represents a single configuration identifier
+/// for an \c AuthSrv object.
+///
+/// In general, each top level configuration identifier for \c AuthSrv is
+/// expected to have its own derived class of this base class.
+/// For example, for the following configuration:
+/// \code { "param1": 10, "param2": { "subparam1": "foo", "subparam2": [] } }
+/// \endcode
+/// "param1" and "param2" are top level identifiers, and would correspond to
+/// derived \c AuthConfigParser classes.
+/// "subparam1" and/or "subparam2" may also have dedicated derived classes.
+///
+/// These derived classes are hidden inside the implementation; applications
+/// are not expected to (and in fact cannot) instantiate them directly.
+///
+/// Each derived class is generally expected to be constructed with an
+/// \c AuthSrv object to be configured and hold a reference to the server
+/// throughout the configuration process.
+/// For each derived class, the \c build() method parses the configuration
+/// value for the corresponding identifier and prepares new configuration
+/// value(s) to be applied to the server.  This method may throw an exception
+/// when it encounters an error.
+/// The \c commit() method actually applies the new configuration value
+/// to the server.  It's basically not expected to throw an exception;
+/// any configuration operations that can fail (such as ones involving
+/// resource allocation) should be done in \c build().
+///
+/// When the destructor is called before \c commit(), the destructor is
+/// supposed to make sure the state of the \c AuthSrv object is the same
+/// as that before it starts building the configuration value.
+/// If \c build() doesn't change the server state (which is recommended)
+/// the destructor doesn't have to do anything special in this regard.
+/// This is a key to ensure the strong exception guarantee (see also
+/// the description of \c configureAuthServer()).
+class AuthConfigParser {
+    ///
+    /// \name Constructors and Destructor
+    ///
+    /// Note: The copy constructor and the assignment operator are
+    /// intentionally defined as private to make it explicit that this is a
+    /// pure base class.
+    //@{
+private:
+    AuthConfigParser(const AuthConfigParser& source);
+    AuthConfigParser& operator=(const AuthConfigParser& source);
+protected:
+    /// \brief The default constructor.
+    ///
+    /// This is intentionally defined as \c protected as this base class should
+    /// never be instantiated (except as part of a derived class).
+    AuthConfigParser() {}
+public:
+    /// The destructor.
+    virtual ~AuthConfigParser() {}
+    //@}
+
+    /// Prepare configuration value.
+    ///
+    /// This method parses the "value part" of the configuration identifier
+    /// that corresponds to this derived class and prepares a new value to
+    /// apply to the server.
+    /// In the above example, the derived class for the identifier "param1"
+    /// would be passed an data \c Element storing an integer whose value
+    /// is 10, and would record that value internally;
+    /// the derived class for the identifier "param2" would be passed a
+    /// map element and (after parsing) convert it into some internal
+    /// data structure.
+    ///
+    /// This method must validate the given value both in terms of syntax
+    /// and semantics of the configuration, so that the server will be
+    /// validly configured at the time of \c commit().  Note: the given
+    /// configuration value is normally syntactically validated, but the
+    /// \c build() implementation must also expect invalid input.  If it
+    /// detects an error it may throw an exception of a derived class
+    /// of \c isc::Exception.
+    ///
+    /// Preparing a configuration value will often require resource
+    /// allocation.  If it fails, it may throw a corresponding standard
+    /// exception.
+    ///
+    /// This method is not expected to be called more than once.  Although
+    /// multiple calls are not prohibited by the interface, the behavior
+    /// is undefined.
+    ///
+    /// \param config_value The configuration value for the identifier
+    /// corresponding to the derived class.
+    virtual void build(isc::data::ConstElementPtr config_value) = 0;
+
+    /// Apply the prepared configuration value to the server.
+    ///
+    /// This method is expected to be exception free, and, as a consequence,
+    /// it should normally not involve resource allocation.
+    /// Typically it would simply perform exception free assignment or swap
+    /// operation on the value prepared in \c build().
+    /// In some cases, however, it may be very difficult to meet this
+    /// condition in a realistic way, while the failure case should really
+    /// be very rare.  In such a case it may throw, and, if the parser is
+    /// called via \c configureAuthServer(), the caller will convert the
+    /// exception as a fatal error.
+    ///
+    /// This method is expected to be called after \c build(), and only once.
+    /// The result is undefined otherwise.
+    virtual void commit() = 0;
+};
+
+/// Configure an \c AuthSrv object with a set of configuration values.
+///
+/// This function parses configuration information stored in \c config_set
+/// and configures the \c server by applying the configuration to it.
+/// It provides the strong exception guarantee as long as the underlying
+/// derived class implementations of \c AuthConfigParser meet the assumption,
+/// that is, it ensures that either configuration is fully applied or the
+/// state of the server is intact.
+///
+/// If a syntax or semantics level error happens during the configuration
+/// (such as malformed configuration or invalid configuration parameter),
+/// this function throws an exception of class \c AuthConfigError.
+/// If the given configuration requires resource allocation and it fails,
+/// a corresponding standard exception will be thrown.
+/// Other exceptions may also be thrown, depending on the implementation of
+/// the underlying derived class of \c AuthConfigError.
+/// In any case the strong guarantee is provided as described above except
+/// in the very rare cases where the \c commit() method of a parser throws
+/// an exception.  If that happens this function converts the exception
+/// into a \c FatalError exception and rethrows it.  This exception is
+/// expected to be caught at the highest level of the application to terminate
+/// the program gracefully.
+///
+/// \param server The \c AuthSrv object to be configured.
+/// \param config_set A JSON style configuration to apply to \c server.
+void configureAuthServer(AuthSrv& server,
+                         isc::data::ConstElementPtr config_set);
+
+/// Create a new \c AuthConfigParser object for a given configuration
+/// identifier.
+///
+/// It internally identifies an appropriate derived class for the given
+/// identifier and creates a new instance of that class.  The caller can
+/// then configure the \c server regarding the identifier by calling
+/// the \c build() and \c commit() methods of the returned object.
+///
+/// In practice, this function is only expected to be used as a backend of
+/// \c configureAuthServer() and is not supposed to be called directly
+/// by applications.  It is publicly available mainly for testing purposes.
+/// When called directly, the created object must be deleted by the caller.
+/// Note: this means if this module and the caller use incompatible sets of
+/// new/delete, it may cause unexpected strange failure.  We could avoid that
+/// by providing a separate deallocation function or by using a smart pointer,
+/// but since the expected usage of this function is very limited (i.e. for
+/// our own testing purposes) it would be an overkilling.  We therefore prefer
+/// simplicity and keeping the interface intuitive.
+///
+/// If the resource allocation for the new object fails, a corresponding
+/// standard exception will be thrown.  Otherwise this function is not
+/// expected to throw an exception, unless the constructor of the underlying
+/// derived class implementation (unexpectedly) throws.
+///
+/// \param server The \c AuthSrv object to be configured.
+/// \param config_id The configuration identifier for which a parser object
+/// is to be created.
+/// \return A pointer to an \c AuthConfigParser object.
+AuthConfigParser* createAuthConfigParser(AuthSrv& server,
+                                         const std::string& config_id);
+
+#endif // __CONFIG_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index f46752a..9a49cc7 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -52,7 +52,7 @@
 #include <xfr/xfrout_client.h>
 
 #include <auth/common.h>
-#include <auth/config.h>
+#include <auth/auth_config.h>
 #include <auth/auth_srv.h>
 #include <auth/query.h>
 #include <auth/statistics.h>
diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h
index 8253c85..8a6d522 100644
--- a/src/bin/auth/auth_srv.h
+++ b/src/bin/auth/auth_srv.h
@@ -23,6 +23,15 @@
 
 #include <cc/data.h>
 #include <config/ccsession.h>
+#include <dns/message.h>
+#include <dns/buffer.h>
+
+#include <asiolink/io_message.h>
+#include <asiolink/io_service.h>
+#include <asiolink/dns_server.h>
+#include <asiolink/dns_lookup.h>
+#include <asiolink/dns_answer.h>
+#include <asiolink/simple_callback.h>
 
 #include <asiolink/asiolink.h>
 #include <server_common/portconfig.h>
diff --git a/src/bin/auth/benchmarks/Makefile.am b/src/bin/auth/benchmarks/Makefile.am
index 3078dd5..c7de8d4 100644
--- a/src/bin/auth/benchmarks/Makefile.am
+++ b/src/bin/auth/benchmarks/Makefile.am
@@ -10,7 +10,7 @@ noinst_PROGRAMS = query_bench
 query_bench_SOURCES = query_bench.cc
 query_bench_SOURCES += ../query.h  ../query.cc
 query_bench_SOURCES += ../auth_srv.h ../auth_srv.cc
-query_bench_SOURCES += ../config.h ../config.cc
+query_bench_SOURCES += ../auth_config.h ../auth_config.cc
 query_bench_SOURCES += ../statistics.h ../statistics.cc
 
 query_bench_LDADD = $(top_builddir)/src/lib/dns/libdns++.la
diff --git a/src/bin/auth/benchmarks/query_bench.cc b/src/bin/auth/benchmarks/query_bench.cc
index 5e69134..86d9813 100644
--- a/src/bin/auth/benchmarks/query_bench.cc
+++ b/src/bin/auth/benchmarks/query_bench.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <config.h>
+
 #include <stdlib.h>
 
 #include <iostream>
@@ -31,7 +33,7 @@
 #include <xfr/xfrout_client.h>
 
 #include <auth/auth_srv.h>
-#include <auth/config.h>
+#include <auth/auth_config.h>
 #include <auth/query.h>
 
 #include <asiolink/asiolink.h>
diff --git a/src/bin/auth/config.cc b/src/bin/auth/config.cc
deleted file mode 100644
index f289ca0..0000000
--- a/src/bin/auth/config.cc
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright (C) 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
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <boost/foreach.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <dns/name.h>
-#include <dns/rrclass.h>
-
-#include <cc/data.h>
-
-#include <datasrc/memory_datasrc.h>
-#include <datasrc/zonetable.h>
-
-#include <auth/auth_srv.h>
-#include <auth/config.h>
-#include <auth/common.h>
-
-#include <server_common/portconfig.h>
-
-using namespace std;
-using boost::shared_ptr;
-using namespace isc::dns;
-using namespace isc::data;
-using namespace isc::datasrc;
-using namespace isc::server_common::portconfig;
-
-namespace {
-// Forward declaration
-AuthConfigParser*
-createAuthConfigParser(AuthSrv& server, const std::string& config_id,
-                       bool internal);
-
-/// A derived \c AuthConfigParser class for the "datasources" configuration
-/// identifier.
-class DatasourcesConfig : public AuthConfigParser {
-public:
-    DatasourcesConfig(AuthSrv& server) : server_(server) {}
-    virtual void build(ConstElementPtr config_value);
-    virtual void commit();
-private:
-    AuthSrv& server_;
-    vector<shared_ptr<AuthConfigParser> > datasources_;
-    set<string> configured_sources_;
-};
-
-void
-DatasourcesConfig::build(ConstElementPtr config_value) {
-    BOOST_FOREACH(ConstElementPtr datasrc_elem, config_value->listValue()) {
-        // The caller is supposed to perform syntax-level checks, but we'll
-        // do minimum level of validation ourselves so that we won't crash due
-        // to a buggy application.
-        ConstElementPtr datasrc_type = datasrc_elem->get("type");
-        if (!datasrc_type) {
-            isc_throw(AuthConfigError, "Missing data source type");
-        }
-
-        if (configured_sources_.find(datasrc_type->stringValue()) !=
-            configured_sources_.end()) {
-            isc_throw(AuthConfigError, "Data source type '" <<
-                      datasrc_type->stringValue() << "' already configured");
-        }
-        
-        shared_ptr<AuthConfigParser> datasrc_config =
-            shared_ptr<AuthConfigParser>(
-                createAuthConfigParser(server_, string("datasources/") +
-                                       datasrc_type->stringValue(),
-                                       true));
-        datasrc_config->build(datasrc_elem);
-        datasources_.push_back(datasrc_config);
-
-        configured_sources_.insert(datasrc_type->stringValue());
-    }
-}
-
-void
-DatasourcesConfig::commit() {
-    // XXX a short term workaround: clear all data sources and then reset
-    // to new ones so that we can remove data sources that don't exist in
-    // the new configuration and have been used in the server.
-    // This could be inefficient and requires knowledge about
-    // server implementation details, and isn't scalable wrt the number of
-    // data source types, and should eventually be improved.
-    // Currently memory data source for class IN is the only possibility.
-    server_.setMemoryDataSrc(RRClass::IN(), AuthSrv::MemoryDataSrcPtr());
-
-    BOOST_FOREACH(shared_ptr<AuthConfigParser> datasrc_config, datasources_) {
-        datasrc_config->commit();
-    }
-}
-
-/// A derived \c AuthConfigParser class for the memory type datasource
-/// configuration.  It does not correspond to the configuration syntax;
-/// it's instantiated for internal use.
-class MemoryDatasourceConfig : public AuthConfigParser {
-public:
-    MemoryDatasourceConfig(AuthSrv& server) :
-        server_(server),
-        rrclass_(0)              // XXX: dummy initial value
-    {}
-    virtual void build(ConstElementPtr config_value);
-    virtual void commit() {
-        server_.setMemoryDataSrc(rrclass_, memory_datasrc_);
-    }
-private:
-    AuthSrv& server_;
-    RRClass rrclass_;
-    AuthSrv::MemoryDataSrcPtr memory_datasrc_;
-};
-
-void
-MemoryDatasourceConfig::build(ConstElementPtr config_value) {
-    // XXX: apparently we cannot retrieve the default RR class from the
-    // module spec.  As a temporary workaround we hardcode the default value.
-    ConstElementPtr rrclass_elem = config_value->get("class");
-    rrclass_ = RRClass(rrclass_elem ? rrclass_elem->stringValue() : "IN");
-
-    // We'd eventually optimize building zones (in case of reloading) by
-    // selectively loading fresh zones.  Right now we simply check the
-    // RR class is supported by the server implementation.
-    server_.getMemoryDataSrc(rrclass_);
-    memory_datasrc_ = AuthSrv::MemoryDataSrcPtr(new MemoryDataSrc());
-
-    ConstElementPtr zones_config = config_value->get("zones");
-    if (!zones_config) {
-        // XXX: Like the RR class, we cannot retrieve the default value here,
-        // so we assume an empty zone list in this case.
-        return;
-    }
-
-    BOOST_FOREACH(ConstElementPtr zone_config, zones_config->listValue()) {
-        ConstElementPtr origin = zone_config->get("origin");
-        if (!origin) {
-            isc_throw(AuthConfigError, "Missing zone origin");
-        }
-        ConstElementPtr file = zone_config->get("file");
-        if (!file) {
-            isc_throw(AuthConfigError, "Missing zone file for zone: "
-                      << origin->str());
-        }
-        shared_ptr<MemoryZone> new_zone(new MemoryZone(rrclass_,
-            Name(origin->stringValue())));
-        const result::Result result = memory_datasrc_->addZone(new_zone);
-        if (result == result::EXIST) {
-            isc_throw(AuthConfigError, "zone "<< origin->str()
-                      << " already exists");
-        }
-
-        /*
-         * TODO: Once we have better reloading of configuration (something
-         * else than throwing everything away and loading it again), we will
-         * need the load method to be split into some kind of build and
-         * commit/abort parts.
-         */
-        new_zone->load(file->stringValue());
-    }
-}
-
-/// A derived \c AuthConfigParser class for the "statistics-internal"
-/// configuration identifier.
-class StatisticsIntervalConfig : public AuthConfigParser {
-public:
-    StatisticsIntervalConfig(AuthSrv& server) :
-        server_(server), interval_(0)
-    {}
-    virtual void build(ConstElementPtr config_value) {
-        const int32_t config_interval = config_value->intValue();
-        if (config_interval < 0) {
-            isc_throw(AuthConfigError, "Negative statistics interval value: "
-                      << config_interval);
-        }
-        if (config_interval > 86400) {
-            isc_throw(AuthConfigError, "Statistics interval value "
-                      << config_interval
-                      << " must be equal to or shorter than 86400");
-        }
-        interval_ = config_interval;
-    }
-    virtual void commit() {
-        // setStatisticsTimerInterval() is not 100% exception free.  But
-        // exceptions should happen only in a very rare situation, so we
-        // let them be thrown and subsequently regard them as a fatal error.
-        server_.setStatisticsTimerInterval(interval_);
-    }
-private:
-    AuthSrv& server_;
-    uint32_t interval_;
-};
-
-/// A special parser for testing: it throws from commit() despite the
-/// suggested convention of the class interface.
-class ThrowerCommitConfig : public AuthConfigParser {
-public:
-    virtual void build(ConstElementPtr) {} // ignore param, do nothing
-    virtual void commit() {
-        throw 10;
-    }
-};
-
-/**
- * \brief Configuration parser for listen_on.
- *
- * It parses and sets the listening addresses of the server.
- *
- * It acts in unusual way. Since actually binding (changing) the sockets
- * is an operation that is expected to throw often, it shouldn't happen
- * in commit. Thefere we do it in build. But if the config is not committed
- * then, we would have it wrong. So we store the old addresses and if
- * commit is not called before destruction of the object, we return the
- * old addresses (which is the same kind of dangerous operation, but it is
- * expected that if we just managed to bind some and had the old ones binded
- * before, it should work).
- *
- * We might do something better in future (like open only the ports that are
- * extra, put them in in commit and close the old ones), but that's left out
- * for now.
- */
-class ListenAddressConfig : public AuthConfigParser {
-public:
-    ListenAddressConfig(AuthSrv& server) :
-        server_(server)
-    { }
-    ~ ListenAddressConfig() {
-        if (rollbackAddresses_.get() != NULL) {
-            server_.setListenAddresses(*rollbackAddresses_);
-        }
-    }
-private:
-    typedef auto_ptr<AddressList> AddrListPtr;
-public:
-    virtual void build(ConstElementPtr config) {
-        AddressList newAddresses = parseAddresses(config, "listen_on");
-        AddrListPtr old(new AddressList(server_.getListenAddresses()));
-        server_.setListenAddresses(newAddresses);
-        /*
-         * Set the rollback addresses only after successful setting of the
-         * new addresses, so we don't try to rollback if the setup is
-         * unsuccessful (the above can easily throw).
-         */
-        rollbackAddresses_ = old;
-    }
-    virtual void commit() {
-        rollbackAddresses_.release();
-    }
-private:
-    AuthSrv& server_;
-    /**
-     * This is the old address list, if we expect to roll back. When we commit,
-     * this is set to NULL.
-     */
-    AddrListPtr rollbackAddresses_;
-};
-
-// This is a generalized version of create function that can create
-// an AuthConfigParser object for "internal" use.
-AuthConfigParser*
-createAuthConfigParser(AuthSrv& server, const std::string& config_id,
-                       bool internal)
-{
-    // For the initial implementation we use a naive if-else blocks for
-    // simplicity.  In future we'll probably generalize it using map-like
-    // data structure, and may even provide external register interface so
-    // that it can be dynamically customized.
-    if (config_id == "datasources") {
-        return (new DatasourcesConfig(server));
-    } else if (config_id == "statistics-interval") {
-        return (new StatisticsIntervalConfig(server));
-    } else if (internal && config_id == "datasources/memory") {
-        return (new MemoryDatasourceConfig(server));
-    } else if (config_id == "listen_on") {
-        return (new ListenAddressConfig(server));
-    } else if (config_id == "_commit_throw") {
-        // This is for testing purpose only and should not appear in the
-        // actual configuration syntax.  While this could crash the caller
-        // as a result, the server implementation is expected to perform
-        // syntax level validation and should be safe in practice.  In future,
-        // we may introduce dynamic registration of configuration parsers,
-        // and then this test can be done in a cleaner and safer way.
-        return (new ThrowerCommitConfig());
-    } else {
-        isc_throw(AuthConfigError, "Unknown configuration identifier: " <<
-                  config_id);
-    }
-}
-} // end of unnamed namespace
-
-AuthConfigParser*
-createAuthConfigParser(AuthSrv& server, const std::string& config_id) {
-    return (createAuthConfigParser(server, config_id, false));
-}
-
-void
-configureAuthServer(AuthSrv& server, ConstElementPtr config_set) {
-    if (!config_set) {
-        isc_throw(AuthConfigError,
-                  "Null pointer is passed to configuration parser");
-    }
-
-    typedef shared_ptr<AuthConfigParser> ParserPtr;
-    vector<ParserPtr> parsers;
-    typedef pair<string, ConstElementPtr> ConfigPair;
-    try {
-        BOOST_FOREACH(ConfigPair config_pair, config_set->mapValue()) {
-            // We should eventually integrate the sqlite3 DB configuration to
-            // this framework, but to minimize diff we begin with skipping that
-            // part.
-            if (config_pair.first == "database_file") {
-                continue;
-            }
-
-            ParserPtr parser(createAuthConfigParser(server,
-                                                    config_pair.first));
-            parser->build(config_pair.second);
-            parsers.push_back(parser);
-        }
-    } catch (const AuthConfigError& ex) {
-        throw;                  // simply rethrowing it
-    } catch (const isc::Exception& ex) {
-        isc_throw(AuthConfigError, "Server configuration failed: " <<
-                  ex.what());
-    }
-
-    try {
-        BOOST_FOREACH(ParserPtr parser, parsers) {
-            parser->commit();
-        }
-    } catch (...) {
-        throw FatalError("Unrecoverable error: "
-                         "a configuration parser threw in commit");
-    }
-}
diff --git a/src/bin/auth/config.h b/src/bin/auth/config.h
deleted file mode 100644
index 6f18810..0000000
--- a/src/bin/auth/config.h
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright (C) 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
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <string>
-
-#include <exceptions/exceptions.h>
-
-#include <cc/data.h>
-
-#ifndef __CONFIG_H
-#define __CONFIG_H 1
-
-class AuthSrv;
-
-/// An exception that is thrown if an error occurs while configuring an
-/// \c AuthSrv object.
-class AuthConfigError : public isc::Exception {
-public:
-    AuthConfigError(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
-};
-
-/// The abstract base class that represents a single configuration identifier
-/// for an \c AuthSrv object.
-///
-/// In general, each top level configuration identifier for \c AuthSrv is
-/// expected to have its own derived class of this base class.
-/// For example, for the following configuration:
-/// \code { "param1": 10, "param2": { "subparam1": "foo", "subparam2": [] } }
-/// \endcode
-/// "param1" and "param2" are top level identifiers, and would correspond to
-/// derived \c AuthConfigParser classes.
-/// "subparam1" and/or "subparam2" may also have dedicated derived classes.
-///
-/// These derived classes are hidden inside the implementation; applications
-/// are not expected to (and in fact cannot) instantiate them directly.
-///
-/// Each derived class is generally expected to be constructed with an
-/// \c AuthSrv object to be configured and hold a reference to the server
-/// throughout the configuration process.
-/// For each derived class, the \c build() method parses the configuration
-/// value for the corresponding identifier and prepares new configuration
-/// value(s) to be applied to the server.  This method may throw an exception
-/// when it encounters an error.
-/// The \c commit() method actually applies the new configuration value
-/// to the server.  It's basically not expected to throw an exception;
-/// any configuration operations that can fail (such as ones involving
-/// resource allocation) should be done in \c build().
-///
-/// When the destructor is called before \c commit(), the destructor is
-/// supposed to make sure the state of the \c AuthSrv object is the same
-/// as that before it starts building the configuration value.
-/// If \c build() doesn't change the server state (which is recommended)
-/// the destructor doesn't have to do anything special in this regard.
-/// This is a key to ensure the strong exception guarantee (see also
-/// the description of \c configureAuthServer()).
-class AuthConfigParser {
-    ///
-    /// \name Constructors and Destructor
-    ///
-    /// Note: The copy constructor and the assignment operator are
-    /// intentionally defined as private to make it explicit that this is a
-    /// pure base class.
-    //@{
-private:
-    AuthConfigParser(const AuthConfigParser& source);
-    AuthConfigParser& operator=(const AuthConfigParser& source);
-protected:
-    /// \brief The default constructor.
-    ///
-    /// This is intentionally defined as \c protected as this base class should
-    /// never be instantiated (except as part of a derived class).
-    AuthConfigParser() {}
-public:
-    /// The destructor.
-    virtual ~AuthConfigParser() {}
-    //@}
-
-    /// Prepare configuration value.
-    ///
-    /// This method parses the "value part" of the configuration identifier
-    /// that corresponds to this derived class and prepares a new value to
-    /// apply to the server.
-    /// In the above example, the derived class for the identifier "param1"
-    /// would be passed an data \c Element storing an integer whose value
-    /// is 10, and would record that value internally;
-    /// the derived class for the identifier "param2" would be passed a
-    /// map element and (after parsing) convert it into some internal
-    /// data structure.
-    ///
-    /// This method must validate the given value both in terms of syntax
-    /// and semantics of the configuration, so that the server will be
-    /// validly configured at the time of \c commit().  Note: the given
-    /// configuration value is normally syntactically validated, but the
-    /// \c build() implementation must also expect invalid input.  If it
-    /// detects an error it may throw an exception of a derived class
-    /// of \c isc::Exception.
-    ///
-    /// Preparing a configuration value will often require resource
-    /// allocation.  If it fails, it may throw a corresponding standard
-    /// exception.
-    ///
-    /// This method is not expected to be called more than once.  Although
-    /// multiple calls are not prohibited by the interface, the behavior
-    /// is undefined.
-    ///
-    /// \param config_value The configuration value for the identifier
-    /// corresponding to the derived class.
-    virtual void build(isc::data::ConstElementPtr config_value) = 0;
-
-    /// Apply the prepared configuration value to the server.
-    ///
-    /// This method is expected to be exception free, and, as a consequence,
-    /// it should normally not involve resource allocation.
-    /// Typically it would simply perform exception free assignment or swap
-    /// operation on the value prepared in \c build().
-    /// In some cases, however, it may be very difficult to meet this
-    /// condition in a realistic way, while the failure case should really
-    /// be very rare.  In such a case it may throw, and, if the parser is
-    /// called via \c configureAuthServer(), the caller will convert the
-    /// exception as a fatal error.
-    ///
-    /// This method is expected to be called after \c build(), and only once.
-    /// The result is undefined otherwise.
-    virtual void commit() = 0;
-};
-
-/// Configure an \c AuthSrv object with a set of configuration values.
-///
-/// This function parses configuration information stored in \c config_set
-/// and configures the \c server by applying the configuration to it.
-/// It provides the strong exception guarantee as long as the underlying
-/// derived class implementations of \c AuthConfigParser meet the assumption,
-/// that is, it ensures that either configuration is fully applied or the
-/// state of the server is intact.
-///
-/// If a syntax or semantics level error happens during the configuration
-/// (such as malformed configuration or invalid configuration parameter),
-/// this function throws an exception of class \c AuthConfigError.
-/// If the given configuration requires resource allocation and it fails,
-/// a corresponding standard exception will be thrown.
-/// Other exceptions may also be thrown, depending on the implementation of
-/// the underlying derived class of \c AuthConfigError.
-/// In any case the strong guarantee is provided as described above except
-/// in the very rare cases where the \c commit() method of a parser throws
-/// an exception.  If that happens this function converts the exception
-/// into a \c FatalError exception and rethrows it.  This exception is
-/// expected to be caught at the highest level of the application to terminate
-/// the program gracefully.
-///
-/// \param server The \c AuthSrv object to be configured.
-/// \param config_set A JSON style configuration to apply to \c server.
-void configureAuthServer(AuthSrv& server,
-                         isc::data::ConstElementPtr config_set);
-
-/// Create a new \c AuthConfigParser object for a given configuration
-/// identifier.
-///
-/// It internally identifies an appropriate derived class for the given
-/// identifier and creates a new instance of that class.  The caller can
-/// then configure the \c server regarding the identifier by calling
-/// the \c build() and \c commit() methods of the returned object.
-///
-/// In practice, this function is only expected to be used as a backend of
-/// \c configureAuthServer() and is not supposed to be called directly
-/// by applications.  It is publicly available mainly for testing purposes.
-/// When called directly, the created object must be deleted by the caller.
-/// Note: this means if this module and the caller use incompatible sets of
-/// new/delete, it may cause unexpected strange failure.  We could avoid that
-/// by providing a separate deallocation function or by using a smart pointer,
-/// but since the expected usage of this function is very limited (i.e. for
-/// our own testing purposes) it would be an overkilling.  We therefore prefer
-/// simplicity and keeping the interface intuitive.
-///
-/// If the resource allocation for the new object fails, a corresponding
-/// standard exception will be thrown.  Otherwise this function is not
-/// expected to throw an exception, unless the constructor of the underlying
-/// derived class implementation (unexpectedly) throws.
-///
-/// \param server The \c AuthSrv object to be configured.
-/// \param config_id The configuration identifier for which a parser object
-/// is to be created.
-/// \return A pointer to an \c AuthConfigParser object.
-AuthConfigParser* createAuthConfigParser(AuthSrv& server,
-                                         const std::string& config_id);
-
-#endif // __CONFIG_H
-
-// Local Variables:
-// mode: c++
-// End:
diff --git a/src/bin/auth/main.cc b/src/bin/auth/main.cc
index fad4a72..9743eef 100644
--- a/src/bin/auth/main.cc
+++ b/src/bin/auth/main.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <config.h>
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/select.h>
@@ -37,7 +39,7 @@
 
 #include <auth/spec_config.h>
 #include <auth/common.h>
-#include <auth/config.h>
+#include <auth/auth_config.h>
 #include <auth/command.h>
 #include <auth/change_user.h>
 #include <auth/auth_srv.h>
diff --git a/src/bin/auth/tests/Makefile.am b/src/bin/auth/tests/Makefile.am
index 7d489a1..8845755 100644
--- a/src/bin/auth/tests/Makefile.am
+++ b/src/bin/auth/tests/Makefile.am
@@ -22,7 +22,7 @@ run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
 run_unittests_SOURCES += ../auth_srv.h ../auth_srv.cc
 run_unittests_SOURCES += ../query.h ../query.cc
 run_unittests_SOURCES += ../change_user.h ../change_user.cc
-run_unittests_SOURCES += ../config.h ../config.cc
+run_unittests_SOURCES += ../auth_config.h ../auth_config.cc
 run_unittests_SOURCES += ../command.h ../command.cc
 run_unittests_SOURCES += ../statistics.h ../statistics.cc
 run_unittests_SOURCES += auth_srv_unittest.cc
diff --git a/src/bin/auth/tests/command_unittest.cc b/src/bin/auth/tests/command_unittest.cc
index f788d9e..dd1f6eb 100644
--- a/src/bin/auth/tests/command_unittest.cc
+++ b/src/bin/auth/tests/command_unittest.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <config.h>
+
 #include <cassert>
 #include <cstdlib>
 #include <string>
@@ -32,7 +34,7 @@
 #include <datasrc/memory_datasrc.h>
 
 #include <auth/auth_srv.h>
-#include <auth/config.h>
+#include <auth/auth_config.h>
 #include <auth/command.h>
 
 #include <asiolink/asiolink.h>
diff --git a/src/bin/auth/tests/config_unittest.cc b/src/bin/auth/tests/config_unittest.cc
index 8cce0af..9c94e25 100644
--- a/src/bin/auth/tests/config_unittest.cc
+++ b/src/bin/auth/tests/config_unittest.cc
@@ -26,7 +26,7 @@
 #include <xfr/xfrout_client.h>
 
 #include <auth/auth_srv.h>
-#include <auth/config.h>
+#include <auth/auth_config.h>
 #include <auth/common.h>
 
 #include <testutils/mockups.h>
diff --git a/src/bin/bind10/bind10.py.in b/src/bin/bind10/bind10.py.in
index 9224ffa..e6504e1 100755
--- a/src/bin/bind10/bind10.py.in
+++ b/src/bin/bind10/bind10.py.in
@@ -297,7 +297,7 @@ class BoB:
 
     def command_handler(self, command, args):
         if self.verbose:
-            sys.stdout.write("[bind10] Boss got command: " + command + "\n")
+            sys.stdout.write("[bind10] Boss got command: " + str(command) + "\n")
         answer = isc.config.ccsession.create_answer(1, "command not implemented")
         if type(command) != str:
             answer = isc.config.ccsession.create_answer(1, "bad command")
@@ -305,6 +305,15 @@ class BoB:
             if command == "shutdown":
                 self.runnable = False
                 answer = isc.config.ccsession.create_answer(0)
+            elif command == "sendstats":
+                # send statistics data to the stats daemon immediately
+                cmd = isc.config.ccsession.create_command(
+                    'set', { "stats_data": {
+                            'bind10.boot_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', _BASETIME)
+                            }})
+                seq = self.cc_session.group_sendmsg(cmd, 'Stats')
+                self.cc_session.group_recvmsg(True, seq)
+                answer = isc.config.ccsession.create_answer(0)
             elif command == "ping":
                 answer = isc.config.ccsession.create_answer(0, "pong")
             elif command == "show_processes":
@@ -977,17 +986,6 @@ def main():
     sys.stdout.write("[bind10] BIND 10 started\n")
     dump_pid(options.pid_file)
 
-    # send "bind10.boot_time" to b10-stats
-    time.sleep(1) # wait a second
-    if options.verbose:
-        sys.stdout.write("[bind10] send \"bind10.boot_time\" to b10-stats\n")
-    cmd = isc.config.ccsession.create_command('set', 
-            { "stats_data": {
-              'bind10.boot_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', _BASETIME)
-              }
-            })
-    boss_of_bind.cc_session.group_sendmsg(cmd, 'Stats')
-
     # In our main loop, we check for dead processes or messages 
     # on the c-channel.
     wakeup_fd = wakeup_pipe[0]
diff --git a/src/bin/bind10/bob.spec b/src/bin/bind10/bob.spec
index c206b34..1184fd1 100644
--- a/src/bin/bind10/bob.spec
+++ b/src/bin/bind10/bob.spec
@@ -23,6 +23,11 @@
         "command_args": []
       },
       {
+        "command_name": "sendstats",
+        "command_description": "Send data to a statistics module at once",
+        "command_args": []
+      },
+      {
         "command_name": "ping",
         "command_description": "Ping the boss process",
         "command_args": []
diff --git a/src/bin/bind10/tests/bind10_test.py.in b/src/bin/bind10/tests/bind10_test.py.in
index 2d58b61..8432c89 100644
--- a/src/bin/bind10/tests/bind10_test.py.in
+++ b/src/bin/bind10/tests/bind10_test.py.in
@@ -13,7 +13,7 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from bind10 import ProcessInfo, BoB, parse_args, dump_pid, unlink_pid_file
+from bind10 import ProcessInfo, BoB, parse_args, dump_pid, unlink_pid_file, _BASETIME
 
 # XXX: environment tests are currently disabled, due to the preprocessor
 #      setup that we have now complicating the environment
@@ -24,6 +24,9 @@ import os
 import signal
 import socket
 from isc.net.addr import IPAddr
+import time
+import isc
+
 from isc.testutils.parse_args import TestOptParser, OptsError
 
 class TestProcessInfo(unittest.TestCase):
@@ -123,6 +126,41 @@ class TestBoB(unittest.TestCase):
         self.assertEqual(bob.cfg_start_auth, True)
         self.assertEqual(bob.cfg_start_resolver, False)
 
+    def test_command_handler(self):
+        class DummySession():
+            def group_sendmsg(self, msg, group):
+                (self.msg, self.group) = (msg, group)
+            def group_recvmsg(self, nonblock, seq): pass
+        bob = BoB()
+        bob.verbose = True
+        bob.cc_session = DummySession()
+        # a bad command
+        self.assertEqual(bob.command_handler(-1, None),
+                         isc.config.ccsession.create_answer(1, "bad command"))
+        # "shutdown" command
+        self.assertEqual(bob.command_handler("shutdown", None),
+                         isc.config.ccsession.create_answer(0))
+        self.assertFalse(bob.runnable)
+        # "sendstats" command
+        self.assertEqual(bob.command_handler("sendstats", None),
+                         isc.config.ccsession.create_answer(0))
+        self.assertEqual(bob.cc_session.group, "Stats")
+        self.assertEqual(bob.cc_session.msg,
+                         isc.config.ccsession.create_command(
+                'set', { "stats_data": {
+                        'bind10.boot_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', _BASETIME)
+                        }}))
+        # "ping" command
+        self.assertEqual(bob.command_handler("ping", None),
+                         isc.config.ccsession.create_answer(0, "pong"))
+        # "show_processes" command
+        self.assertEqual(bob.command_handler("show_processes", None),
+                         isc.config.ccsession.create_answer(0,
+                                                            bob.get_processes()))
+        # an unknown command
+        self.assertEqual(bob.command_handler("__UNKNOWN__", None),
+                         isc.config.ccsession.create_answer(1, "Unknown command"))
+
 # Class for testing the BoB without actually starting processes.
 # This is used for testing the start/stop components routines and
 # the BoB commands.
diff --git a/src/bin/resolver/main.cc b/src/bin/resolver/main.cc
index 1d76e0b..092ec54 100644
--- a/src/bin/resolver/main.cc
+++ b/src/bin/resolver/main.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <config.h>
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/select.h>
diff --git a/src/bin/resolver/resolver.h b/src/bin/resolver/resolver.h
index 002e58b..8f07ff7 100644
--- a/src/bin/resolver/resolver.h
+++ b/src/bin/resolver/resolver.h
@@ -21,8 +21,16 @@
 
 #include <cc/data.h>
 #include <config/ccsession.h>
-
-#include <asiolink/asiolink.h>
+#include <dns/message.h>
+#include <dns/buffer.h>
+
+#include <asiolink/io_message.h>
+#include <asiolink/io_service.h>
+#include <asiolink/dns_server.h>
+#include <asiolink/dns_service.h>
+#include <asiolink/dns_lookup.h>
+#include <asiolink/dns_answer.h>
+#include <asiolink/simple_callback.h>
 
 #include <nsas/nameserver_address_store.h>
 #include <cache/resolver_cache.h>
diff --git a/src/bin/resolver/tests/resolver_config_unittest.cc b/src/bin/resolver/tests/resolver_config_unittest.cc
index 2fa62e5..c1ff853 100644
--- a/src/bin/resolver/tests/resolver_config_unittest.cc
+++ b/src/bin/resolver/tests/resolver_config_unittest.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <config.h>
+
 #include <string>
 
 #include <gtest/gtest.h>
diff --git a/src/bin/stats/b10-stats.8 b/src/bin/stats/b10-stats.8
index 062ff35..5714234 100644
--- a/src/bin/stats/b10-stats.8
+++ b/src/bin/stats/b10-stats.8
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: b10-stats
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
 .\"      Date: Oct 15, 2010
 .\"    Manual: BIND10
 .\"    Source: BIND10
@@ -9,6 +9,15 @@
 .\"
 .TH "B10\-STATS" "8" "Oct 15, 2010" "BIND10" "BIND10"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
@@ -35,6 +44,11 @@ with other modules like
 \fBbind10\fR,
 \fBb10\-auth\fR
 and so on\&. It waits for coming data from other modules, then other modules send data to stats module periodically\&. Other modules send stats data to stats module independently from implementation of stats module, so the frequency of sending data may not be constant\&. Stats module collects data and aggregates it\&.
+\fBb10\-stats\fR
+invokes "sendstats" command for
+\fBbind10\fR
+after its initial starting because it\*(Aqs sure to collect statistics data from
+\fBbind10\fR\&.
 .SH "OPTIONS"
 .PP
 The arguments are as follows:
@@ -49,7 +63,8 @@ switches to verbose mode\&. It sends verbose messages to STDOUT\&.
 .PP
 /usr/local/share/bind10\-devel/stats\&.spec
 \(em This is a spec file for
-\fBb10\-stats\fR\&. It contains definitions of statistics items of BIND 10 and commands received vi bindctl\&.
+\fBb10\-stats\fR\&. It contains definitions of statistics items of BIND 10 and commands received via
+bindctl(1)\&.
 .SH "SEE ALSO"
 .PP
 
diff --git a/src/bin/stats/b10-stats.xml b/src/bin/stats/b10-stats.xml
index f622439..7ec58dd 100644
--- a/src/bin/stats/b10-stats.xml
+++ b/src/bin/stats/b10-stats.xml
@@ -2,7 +2,7 @@
                "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
 	       [<!ENTITY mdash "—">]>
 <!--
- - Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2010,2011  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
@@ -64,7 +64,9 @@
       send stats data to stats module independently from
       implementation of stats module, so the frequency of sending data
       may not be constant. Stats module collects data and aggregates
-      it.
+      it. <command>b10-stats</command> invokes "sendstats" command
+      for <command>bind10</command> after its initial starting because it's
+      sure to collect statistics data from <command>bind10</command>.
     </para>
   </refsect1>
 
diff --git a/src/bin/stats/stats.py.in b/src/bin/stats/stats.py.in
index 15e2980..eeddd92 100755
--- a/src/bin/stats/stats.py.in
+++ b/src/bin/stats/stats.py.in
@@ -1,6 +1,6 @@
 #!@PYTHON@
 
-# Copyright (C) 2010  Internet Systems Consortium.
+# Copyright (C) 2010, 2011  Internet Systems Consortium.
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -15,8 +15,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-__version__ = "$Revision$"
-
 import sys; sys.path.append ('@@PYTHONPATH@@')
 import os
 import signal
@@ -220,7 +218,13 @@ class CCSessionListener(Listener):
         self.stats_data['stats.start_time'] = get_datetime()
         self.stats_data['stats.last_update_time'] = get_datetime()
         self.stats_data['stats.lname'] = self.session.lname
-        return self.cc_session.start()
+        self.cc_session.start()
+        # request Bob to send statistics data
+        if self.verbose:
+            sys.stdout.write("[b10-stats] request Bob to send statistics data\n")
+        cmd = isc.config.ccsession.create_command("sendstats", None)
+        seq = self.session.group_sendmsg(cmd, 'Boss')
+        self.session.group_recvmsg(True, seq)
 
     def stop(self):
         """
diff --git a/src/bin/stats/tests/b10-stats_test.py b/src/bin/stats/tests/b10-stats_test.py
index e4e1a1e..3566bc4 100644
--- a/src/bin/stats/tests/b10-stats_test.py
+++ b/src/bin/stats/tests/b10-stats_test.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2010  Internet Systems Consortium.
+# Copyright (C) 2010,2011  Internet Systems Consortium.
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -13,8 +13,6 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-__version__ = "$Revision$"
-
 #
 # Tests for the stats module
 #
@@ -504,6 +502,13 @@ class TestStats(unittest.TestCase):
         self.assertEqual(result_ok(),
                          self.session.get_message("Stats", None))
 
+    def test_for_boss(self):
+        last_queue = self.session.old_message_queue.pop()
+        self.assertEqual(
+            last_queue.msg, {'command': ['sendstats']})
+        self.assertEqual(
+            last_queue.env['group'], 'Boss')
+
 class TestStats2(unittest.TestCase):
 
     def setUp(self):
diff --git a/src/bin/zonemgr/tests/zonemgr_test.py b/src/bin/zonemgr/tests/zonemgr_test.py
index 70dc1b0..2e9f685 100644
--- a/src/bin/zonemgr/tests/zonemgr_test.py
+++ b/src/bin/zonemgr/tests/zonemgr_test.py
@@ -22,10 +22,10 @@ import tempfile
 from zonemgr import *
 
 ZONE_NAME_CLASS1_IN = ("sd.cn.", "IN")
-ZONE_NAME_CLASS2_CH = ("tw.cn", "CH")
+ZONE_NAME_CLASS2_CH = ("tw.cn.", "CH")
 ZONE_NAME_CLASS3_IN = ("example.com", "IN")
 ZONE_NAME_CLASS1_CH = ("sd.cn.", "CH")
-ZONE_NAME_CLASS2_IN = ("tw.cn", "IN")
+ZONE_NAME_CLASS2_IN = ("tw.cn.", "IN")
 
 MAX_TRANSFER_TIMEOUT = 14400
 LOWERBOUND_REFRESH = 10
@@ -46,21 +46,43 @@ class MySession():
     def group_recvmsg(self, nonblock, seq):
         return None, None
 
+class FakeConfig:
+    def __init__(self):
+        self.zone_list = []
+        self.set_zone_list_from_name_classes([ZONE_NAME_CLASS1_IN,
+                                              ZONE_NAME_CLASS2_CH])
+    def set_zone_list_from_name_classes(self, zones):
+        self.zone_list = map(lambda nc: {"name": nc[0], "class": nc[1]}, zones)
+    def get(self, name):
+        if name == 'lowerbound_refresh':
+            return LOWERBOUND_REFRESH
+        elif name == 'lowerbound_retry':
+            return LOWERBOUND_RETRY
+        elif name == 'max_transfer_timeout':
+            return MAX_TRANSFER_TIMEOUT
+        elif name == 'jitter_scope':
+            return JITTER_SCOPE
+        elif name == 'secondary_zones':
+            return self.zone_list
+        else:
+            raise ValueError('Uknown config option')
+
 class MyZonemgrRefresh(ZonemgrRefresh):
     def __init__(self):
-        class FakeConfig:
-            def get(self, name):
-                if name == 'lowerbound_refresh':
-                    return LOWERBOUND_REFRESH
-                elif name == 'lowerbound_retry':
-                    return LOWERBOUND_RETRY
-                elif name == 'max_transfer_timeout':
-                    return MAX_TRANSFER_TIMEOUT
-                elif name == 'jitter_scope':
-                    return JITTER_SCOPE
-                else:
-                    raise ValueError('Uknown config option')
         self._master_socket, self._slave_socket = socket.socketpair()
+        self._zonemgr_refresh_info = {}
+
+        def get_zone_soa(zone_name, db_file):
+            if zone_name == 'sd.cn.':
+                return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
+                        'a.dns.cn. root.cnnic.cn. 2009073106 7200 3600 2419200 21600')
+            elif zone_name == 'tw.cn.':
+                return (1, 2, 'tw.cn.', 'cn.sd.', 21600, 'SOA', None,
+                        'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600')
+            else:
+                return None
+        sqlite3_ds.get_zone_soa = get_zone_soa
+
         ZonemgrRefresh.__init__(self, MySession(), "initdb.file",
             self._slave_socket, FakeConfig())
         current_time = time.time()
@@ -70,7 +92,7 @@ class MyZonemgrRefresh(ZonemgrRefresh):
          'next_refresh_time': current_time + 6500, 
          'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600', 
          'zone_state': 0},
-         ('tw.cn', 'CH'): {
+         ('tw.cn.', 'CH'): {
          'last_refresh_time': current_time, 
          'next_refresh_time': current_time + 6900, 
          'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600', 
@@ -272,28 +294,6 @@ class TestZonemgrRefresh(unittest.TestCase):
                                          ZONE_NAME_CLASS1_IN)
         sqlite3_ds.get_zone_soa = old_get_zone_soa
 
-    def test_build_zonemgr_refresh_info(self):
-        soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
-
-        def get_zones_info(db_file):
-            return [("sd.cn.", "IN")] 
-
-        def get_zone_soa(zone_name, db_file):
-            return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None, 
-                    'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
-
-        sqlite3_ds.get_zones_info = get_zones_info
-        sqlite3_ds.get_zone_soa = get_zone_soa
-
-        self.zone_refresh._zonemgr_refresh_info = {}
-        self.zone_refresh._build_zonemgr_refresh_info()
-        self.assertEqual(1, len(self.zone_refresh._zonemgr_refresh_info))
-        zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
-        self.assertEqual(soa_rdata, zone_soa_rdata) 
-        self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
-        self.assertTrue("last_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
-        self.assertTrue("next_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
-
     def test_zone_handle_notify(self):
         self.zone_refresh.zone_handle_notify(ZONE_NAME_CLASS1_IN,"127.0.0.1")
         notify_master = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"]
@@ -356,7 +356,7 @@ class TestZonemgrRefresh(unittest.TestCase):
                     'next_refresh_time': time1 + 7200, 
                     'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600', 
                     'zone_state': ZONE_OK},
-                ("tw.cn","CH"):{
+                ("tw.cn.","CH"):{
                     'last_refresh_time': time1 - 7200, 
                     'next_refresh_time': time1, 
                     'refresh_timeout': time1 + MAX_TRANSFER_TIMEOUT, 
@@ -424,7 +424,8 @@ class TestZonemgrRefresh(unittest.TestCase):
                     "lowerbound_refresh" : 60,
                     "lowerbound_retry" : 30,
                     "max_transfer_timeout" : 19800,
-                    "jitter_scope" : 0.25
+                    "jitter_scope" : 0.25,
+                    "secondary_zones": []
                 }
         self.zone_refresh.update_config_data(config_data)
         self.assertEqual(60, self.zone_refresh._lowerbound_refresh)
@@ -440,6 +441,31 @@ class TestZonemgrRefresh(unittest.TestCase):
         self.zone_refresh.shutdown()
         self.assertFalse(listener.is_alive())
 
+    def test_secondary_zones(self):
+        """Test that we can modify the list of secondary zones"""
+        config = FakeConfig()
+        config.zone_list = []
+        # First, remove everything
+        self.zone_refresh.update_config_data(config)
+        self.assertEqual(self.zone_refresh._zonemgr_refresh_info, {})
+        # Put something in
+        config.set_zone_list_from_name_classes([ZONE_NAME_CLASS1_IN])
+        self.zone_refresh.update_config_data(config)
+        self.assertTrue(("sd.cn.", "IN") in
+                        self.zone_refresh._zonemgr_refresh_info)
+        # This one does not exist
+        config.set_zone_list_from_name_classes(["example.net", "CH"])
+        self.assertRaises(ZonemgrException,
+                          self.zone_refresh.update_config_data, config)
+        # So it should not affect the old ones
+        self.assertTrue(("sd.cn.", "IN") in
+                        self.zone_refresh._zonemgr_refresh_info)
+        # Make sure it works even when we "accidentally" forget the final dot
+        config.set_zone_list_from_name_classes([("sd.cn", "IN")])
+        self.zone_refresh.update_config_data(config)
+        self.assertTrue(("sd.cn.", "IN") in
+                        self.zone_refresh._zonemgr_refresh_info)
+
     def tearDown(self):
         sys.stderr= self.stderr_backup
 
@@ -464,10 +490,11 @@ class MyZonemgr(Zonemgr):
         self._cc = MySession()
         self._module_cc = MyCCSession()
         self._config_data = {
-                    "lowerbound_refresh" : 10, 
-                    "lowerbound_retry" : 5, 
+                    "lowerbound_refresh" : 10,
+                    "lowerbound_retry" : 5,
                     "max_transfer_timeout" : 14400,
-                    "jitter_scope" : 0.1
+                    "jitter_scope" : 0.1,
+                    "secondary_zones": []
                     }
 
     def _start_zone_refresh_timer(self):
@@ -480,12 +507,14 @@ class TestZonemgr(unittest.TestCase):
 
     def test_config_handler(self):
         config_data1 = {
-                    "lowerbound_refresh" : 60, 
-                    "lowerbound_retry" : 30, 
+                    "lowerbound_refresh" : 60,
+                    "lowerbound_retry" : 30,
                     "max_transfer_timeout" : 14400,
-                    "jitter_scope" : 0.1
+                    "jitter_scope" : 0.1,
+                    "secondary_zones": []
                     }
-        self.zonemgr.config_handler(config_data1)
+        self.assertEqual(self.zonemgr.config_handler(config_data1),
+                         {"result": [0]})
         self.assertEqual(config_data1, self.zonemgr._config_data)
         config_data2 = {"zone_name" : "sd.cn.", "port" : "53", "master" : "192.168.1.1"}
         self.zonemgr.config_handler(config_data2)
@@ -494,10 +523,19 @@ class TestZonemgr(unittest.TestCase):
         config_data3 = {"jitter_scope" : 0.7}
         self.zonemgr.config_handler(config_data3)
         self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
+        # The zone doesn't exist in database, it should be rejected
+        self.zonemgr._zone_refresh = ZonemgrRefresh(None, "initdb.file", None,
+                                                    config_data1)
+        config_data1["secondary_zones"] = [{"name": "nonexistent.example",
+                                            "class": "IN"}]
+        self.assertNotEqual(self.zonemgr.config_handler(config_data1),
+                            {"result": [0]})
+        # As it is rejected, the old value should be kept
+        self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
 
     def test_get_db_file(self):
         self.assertEqual("initdb.file", self.zonemgr.get_db_file())
-    
+
     def test_parse_cmd_params(self):
         params1 = {"zone_name" : "org.cn", "zone_class" : "CH", "master" : "127.0.0.1"}
         answer1 = (("org.cn", "CH"), "127.0.0.1")
diff --git a/src/bin/zonemgr/zonemgr.py.in b/src/bin/zonemgr/zonemgr.py.in
index 2cededf..129c673 100755
--- a/src/bin/zonemgr/zonemgr.py.in
+++ b/src/bin/zonemgr/zonemgr.py.in
@@ -100,9 +100,8 @@ class ZonemgrRefresh:
         self._cc = cc
         self._check_sock = slave_socket
         self._db_file = db_file
-        self.update_config_data(config_data)
         self._zonemgr_refresh_info = {}
-        self._build_zonemgr_refresh_info()
+        self.update_config_data(config_data)
         self._running = False
 
     def _random_jitter(self, max, jitter):
@@ -148,16 +147,13 @@ class ZonemgrRefresh:
 
     def _zone_not_exist(self, zone_name_class):
         """ Zone doesn't belong to zonemgr"""
-        if zone_name_class in self._zonemgr_refresh_info.keys():
-            return False
-        return True
+        return not zone_name_class in self._zonemgr_refresh_info
 
     def zone_refresh_success(self, zone_name_class):
         """Update zone info after zone refresh success"""
         if (self._zone_not_exist(zone_name_class)):
             raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't "
                                    "belong to zonemgr" % zone_name_class)
-            return
         self.zonemgr_reload_zone(zone_name_class)
         self._set_zone_refresh_timer(zone_name_class)
         self._set_zone_state(zone_name_class, ZONE_OK)
@@ -168,7 +164,6 @@ class ZonemgrRefresh:
         if (self._zone_not_exist(zone_name_class)):
             raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't "
                                    "belong to zonemgr" % zone_name_class)
-            return
         # Is zone expired?
         if (self._zone_is_expired(zone_name_class)):
             self._set_zone_state(zone_name_class, ZONE_EXPIRED)
@@ -181,7 +176,6 @@ class ZonemgrRefresh:
         if (self._zone_not_exist(zone_name_class)):
             raise ZonemgrException("[b10-zonemgr] Notified zone (%s, %s) "
                                    "doesn't belong to zonemgr" % zone_name_class)
-            return
         self._set_zone_notifier_master(zone_name_class, master)
         self._set_zone_notify_timer(zone_name_class)
 
@@ -192,6 +186,7 @@ class ZonemgrRefresh:
 
     def zonemgr_add_zone(self, zone_name_class):
         """ Add a zone into zone manager."""
+        log_msg("Loading zone (%s, %s)" % zone_name_class)
         zone_info = {}
         zone_soa = sqlite3_ds.get_zone_soa(str(zone_name_class[0]), self._db_file)
         if not zone_soa:
@@ -203,14 +198,6 @@ class ZonemgrRefresh:
                                          float(zone_soa[7].split(" ")[REFRESH_OFFSET])
         self._zonemgr_refresh_info[zone_name_class] = zone_info
 
-    def _build_zonemgr_refresh_info(self):
-        """ Build zonemgr refresh info map."""
-        log_msg("Start loading zone into zonemgr.")
-        for zone_name, zone_class in sqlite3_ds.get_zones_info(self._db_file):
-            zone_name_class = (zone_name, zone_class)
-            self.zonemgr_add_zone(zone_name_class)
-        log_msg("Finish loading zone into zonemgr.")
-
     def _zone_is_expired(self, zone_name_class):
         """Judge whether a zone is expired or not."""
         zone_expired_time = float(self._get_zone_soa_rdata(zone_name_class).split(" ")[EXPIRED_OFFSET])
@@ -415,6 +402,32 @@ class ZonemgrRefresh:
 
     def update_config_data(self, new_config):
         """ update ZonemgrRefresh config """
+        backup = self._zonemgr_refresh_info.copy()
+        try:
+            required = {}
+            # Add new zones
+            for secondary_zone in new_config.get('secondary_zones'):
+                name = secondary_zone['name']
+                # Be tolerant to sclerotic users who forget the final dot
+                if name[-1] != '.':
+                    name = name + '.'
+                name_class = (name, secondary_zone['class'])
+                required[name_class] = True
+                # Add it only if it isn't there already
+                if not name_class in self._zonemgr_refresh_info:
+                    self.zonemgr_add_zone(name_class)
+            # Drop the zones that are no longer there
+            # Do it in two phases, python doesn't like deleting while iterating
+            to_drop = []
+            for old_zone in self._zonemgr_refresh_info:
+                if not old_zone in required:
+                    to_drop.append(old_zone)
+            for drop in to_drop:
+                del self._zonemgr_refresh_info[drop]
+        # If we are not able to find it in database, restore the original
+        except:
+            self._zonemgr_refresh_info = backup
+            raise
         self._lowerbound_refresh = new_config.get('lowerbound_refresh')
         self._lowerbound_retry = new_config.get('lowerbound_retry')
         self._max_transfer_timeout = new_config.get('max_transfer_timeout')
@@ -471,26 +484,37 @@ class Zonemgr:
     def config_handler(self, new_config):
         """ Update config data. """
         answer = create_answer(0)
+        ok = True
+        complete = self._config_data.copy()
         for key in new_config:
-            if key not in self._config_data:
+            if key not in complete:
                 answer = create_answer(1, "Unknown config data: " + str(key))
+                ok = False
                 continue
-            self._config_data[key] = new_config[key]
+            complete[key] = new_config[key]
 
-        self._config_data_check(self._config_data)
-        if (self._zone_refresh):
-            self._zone_refresh.update_config_data(self._config_data)
+        self._config_data_check(complete)
+        if self._zone_refresh is not None:
+            try:
+                self._zone_refresh.update_config_data(complete)
+            except Exception as e:
+                answer = create_answer(1, str(e))
+                ok = False
+        if ok:
+            self._config_data = complete
 
         return answer
 
     def _config_data_check(self, config_data):
-        """Check whether the new config data is valid or 
-        not. """ 
+        """Check whether the new config data is valid or
+        not. It contains only basic logic, not full check against
+        database."""
         # jitter should not be bigger than half of the original value
         if config_data.get('jitter_scope') > 0.5:
             config_data['jitter_scope'] = 0.5
             log_msg("[b10-zonemgr] jitter_scope is too big, its value will "
-                      "be set to 0.5") 
+                      "be set to 0.5")
+
 
     def _parse_cmd_params(self, args, command):
         zone_name = args.get("zone_name")
diff --git a/src/bin/zonemgr/zonemgr.spec.pre.in b/src/bin/zonemgr/zonemgr.spec.pre.in
index 0539ef3..9df01f2 100644
--- a/src/bin/zonemgr/zonemgr.spec.pre.in
+++ b/src/bin/zonemgr/zonemgr.spec.pre.in
@@ -25,6 +25,32 @@
          "item_type": "real",
          "item_optional": false,
          "item_default": 0.25
+       },
+       {
+         "item_name": "secondary_zones",
+         "item_type": "list",
+         "item_optional": false,
+         "item_default": [],
+         "list_item_spec": {
+           "item_name": "secondary_zone",
+           "item_type": "map",
+           "item_optional": false,
+           "item_default": {},
+           "map_item_spec": [
+             {
+               "item_name": "class",
+               "item_type": "string",
+               "item_optional": false,
+               "item_default": "IN"
+             },
+             {
+               "item_name": "name",
+               "item_type": "string",
+               "item_optional": false,
+               "item_default": ""
+             }
+           ]
+         }
        }
       ],
       "commands": [
diff --git a/src/lib/dns/dnssectime.cc b/src/lib/dns/dnssectime.cc
index c889178..89d25f5 100644
--- a/src/lib/dns/dnssectime.cc
+++ b/src/lib/dns/dnssectime.cc
@@ -14,7 +14,12 @@
 
 #include <stdint.h>
 
+#ifdef _WIN32
+#include <time.h>
+#include <windows.h>
+#else
 #include <sys/time.h>
+#endif
 
 #include <string>
 #include <iomanip>
@@ -122,10 +127,25 @@ gettimeofdayWrapper() {
         return (gettimeFunction());
     }
 
+#ifdef _WIN32
+    SYSTEMTIME epoch = { 1970, 1, 4, 1, 0, 0, 0, 0 };
+    FILETIME temp;
+    SystemTimeToFileTime(&epoch, &temp);
+    ULARGE_INTEGER t;
+    t.LowPart = temp.dwLowDateTime;
+    t.HighPart = temp.dwHighDateTime;
+    FILETIME now;
+    GetSystemTimeAsFileTime(&now);
+    ULARGE_INTEGER n;
+    n.LowPart = now.dwLowDateTime;
+    n.HighPart = now.dwHighDateTime;
+    return (static_cast<int64_t>((n.QuadPart - t.QuadPart) / 10000000));
+#else
     struct timeval now;
     gettimeofday(&now, NULL);
 
     return (static_cast<int64_t>(now.tv_sec));
+#endif
 }
 }
 
diff --git a/src/lib/dns/masterload.cc b/src/lib/dns/masterload.cc
index 5f7d5a0..d5eb3ca 100644
--- a/src/lib/dns/masterload.cc
+++ b/src/lib/dns/masterload.cc
@@ -42,6 +42,9 @@ masterLoad(const char* const filename, const Name& origin,
 {
     ifstream ifs;
 
+    if (filename == NULL) {
+        isc_throw(MasterLoadError, "Invalid NULL master file");
+    }
     ifs.open(filename, ios_base::in);
     if (ifs.fail()) {
         isc_throw(MasterLoadError, "Failed to open master file: " << filename);
diff --git a/src/lib/dns/messagerenderer.cc b/src/lib/dns/messagerenderer.cc
index 212411a..0dae08d 100644
--- a/src/lib/dns/messagerenderer.cc
+++ b/src/lib/dns/messagerenderer.cc
@@ -272,8 +272,9 @@ MessageRenderer::writeName(const Name& name, const bool compress) {
     name.toWire(impl_->nbuffer_);
 
     unsigned int i;
-    std::set<NameCompressNode>::const_iterator notfound = impl_->nodeset_.end();
-    std::set<NameCompressNode>::const_iterator n = notfound;
+    std::set<NameCompressNode, NameCompare>::const_iterator notfound =
+        impl_->nodeset_.end();
+    std::set<NameCompressNode, NameCompare>::const_iterator n = notfound;
 
     // Find the longest ancestor name in the rendered set that matches the
     // given name.
diff --git a/src/lib/dns/rcode.h b/src/lib/dns/rcode.h
index 0c63285..e58ee6b 100644
--- a/src/lib/dns/rcode.h
+++ b/src/lib/dns/rcode.h
@@ -21,6 +21,8 @@
 #ifndef __RCODE_H
 #define __RCODE_H 1
 
+#undef NOERROR
+
 namespace isc {
 namespace dns {
 
diff --git a/src/lib/dns/rdata/in_1/a_1.cc b/src/lib/dns/rdata/in_1/a_1.cc
index ddd03f8..dd72c55 100644
--- a/src/lib/dns/rdata/in_1/a_1.cc
+++ b/src/lib/dns/rdata/in_1/a_1.cc
@@ -17,8 +17,12 @@
 
 #include <string>
 
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#else
 #include <arpa/inet.h> // XXX: for inet_pton/ntop(), not exist in C++ standards
 #include <sys/socket.h> // for AF_INET/AF_INET6
+#endif
 
 #include <exceptions/exceptions.h>
 
@@ -77,7 +81,14 @@ string
 A::toText() const {
     char addr_string[sizeof("255.255.255.255")];
 
-    if (inet_ntop(AF_INET, &addr_, addr_string, sizeof(addr_string)) == NULL) {
+#ifdef _WIN32
+#define DECONST (void *)
+#else
+#define DECONST
+#endif
+
+    if (inet_ntop(AF_INET, DECONST &addr_,
+                  addr_string, sizeof(addr_string)) == NULL) {
         isc_throw(Unexpected,
                   "Failed to convert IN/A RDATA to textual IPv4 address");
     }
diff --git a/src/lib/dns/rdata/in_1/aaaa_28.cc b/src/lib/dns/rdata/in_1/aaaa_28.cc
index 45c4682..179b363 100644
--- a/src/lib/dns/rdata/in_1/aaaa_28.cc
+++ b/src/lib/dns/rdata/in_1/aaaa_28.cc
@@ -17,8 +17,12 @@
 
 #include <string>
 
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#else
 #include <arpa/inet.h> // XXX: for inet_pton/ntop(), not exist in C++ standards
 #include <sys/socket.h> // for AF_INET/AF_INET6
+#endif
 
 #include <exceptions/exceptions.h>
 
@@ -74,7 +78,14 @@ string
 AAAA::toText() const {
     char addr_string[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
 
-    if (inet_ntop(AF_INET6, &addr_, addr_string, sizeof(addr_string)) == NULL) {
+#ifdef _WIN32
+#define DECONST (void *)
+#else
+#define DECONST
+#endif
+
+    if (inet_ntop(AF_INET6, DECONST &addr_,
+                  addr_string, sizeof(addr_string)) == NULL) {
         isc_throw(Unexpected,
                   "Failed to convert IN/AAAA RDATA to textual IPv6 address");
     }
diff --git a/src/lib/dns/rrclass-placeholder.h b/src/lib/dns/rrclass-placeholder.h
index ce9a141..fe673ad 100644
--- a/src/lib/dns/rrclass-placeholder.h
+++ b/src/lib/dns/rrclass-placeholder.h
@@ -22,6 +22,8 @@
 
 #include <exceptions/exceptions.h>
 
+#undef IN
+
 namespace isc {
 namespace dns {
 
diff --git a/src/lib/dns/rrparamregistry-placeholder.cc b/src/lib/dns/rrparamregistry-placeholder.cc
index 19363a3..f876c1e 100644
--- a/src/lib/dns/rrparamregistry-placeholder.cc
+++ b/src/lib/dns/rrparamregistry-placeholder.cc
@@ -76,7 +76,7 @@ struct RRTypeParam {
     static size_t UNKNOWN_MAXLEN();
 };
 
-typedef shared_ptr<RRTypeParam> RRTypeParamPtr;
+typedef boost::shared_ptr<RRTypeParam> RRTypeParamPtr;
 typedef map<string, RRTypeParamPtr, CIStringLess> StrRRTypeMap;
 typedef map<uint16_t, RRTypeParamPtr> CodeRRTypeMap;
 
@@ -118,7 +118,7 @@ struct RRClassParam {
     static size_t UNKNOWN_MAXLEN();
 };
 
-typedef shared_ptr<RRClassParam> RRClassParamPtr;
+typedef boost::shared_ptr<RRClassParam> RRClassParamPtr;
 typedef map<string, RRClassParamPtr, CIStringLess> StrRRClassMap;
 typedef map<uint16_t, RRClassParamPtr> CodeRRClassMap;
 
@@ -341,7 +341,7 @@ addParam(const string& code_string, uint16_t code, MC& codemap, MS& stringmap)
         return (false);
     }
 
-    typedef shared_ptr<PT> ParamPtr;
+    typedef boost::shared_ptr<PT> ParamPtr;
     typedef pair<string, ParamPtr> StrParamPair;
     typedef pair<uint16_t, ParamPtr> CodeParamPair;
     ParamPtr param = ParamPtr(new PT(code_string, code));
diff --git a/src/lib/dns/tests/rdata_tsig_unittest.cc b/src/lib/dns/tests/rdata_tsig_unittest.cc
index 5c9a14f..62930b3 100644
--- a/src/lib/dns/tests/rdata_tsig_unittest.cc
+++ b/src/lib/dns/tests/rdata_tsig_unittest.cc
@@ -229,7 +229,7 @@ TEST_F(Rdata_TSIG_Test, createFromParams) {
                   any::TSIG(Name("hmac-sha1"), 1286779327, 300, 12,
                             fake_data, 16020, 18, 6, fake_data2)));
 
-    EXPECT_THROW(any::TSIG(Name("hmac-sha256"), 1LLU << 48, 300, 12,
+    EXPECT_THROW(any::TSIG(Name("hmac-sha256"), 1ULL << 48, 300, 12,
                            fake_data, 16020, 18, 6, fake_data2),
                  isc::OutOfRange);
     EXPECT_THROW(any::TSIG(Name("hmac-sha256"), 0, 300, 0, fake_data, 16020,
diff --git a/src/lib/dns/util/base_n.cc b/src/lib/dns/util/base_n.cc
index 9d0c777..41863d7 100644
--- a/src/lib/dns/util/base_n.cc
+++ b/src/lib/dns/util/base_n.cc
@@ -139,7 +139,7 @@ private:
 // DecodeNormalizer is an input iterator intended to be used as a filter
 // between the encoded baseX stream and binary_from_baseXX.
 // A DecodeNormalizer object is configured with three string iterators
-// (base, base_beinpad, and base_beginpad), specifying the head of the string,
+// (base, base_beginpad, and base_end), specifying the head of the string,
 // the beginning position of baseX padding (when there's padding), and
 // end of the string, respectively.  It internally iterators over the original
 // stream, and return each character of the encoded string via its dereference
diff --git a/src/lib/nsas/locks.h b/src/lib/nsas/locks.h
index 98197c3..695ad56 100644
--- a/src/lib/nsas/locks.h
+++ b/src/lib/nsas/locks.h
@@ -26,11 +26,6 @@
 /// Note that we need to include <config.h> in our .cc files for that
 /// to be set. we might want to enfore this at compile time with a check
 /// (TODO)
-/// Note that this also contains a workaround for Sunstudio; which
-/// probably won't completely work right now (that is, if the TODO
-/// above is completed), since that would also require some changes
-/// in most (at first glance unrelated) Makefiles
-/// (TODO2)
 
 #ifndef __LOCKS_
 #define __LOCKS_
diff --git a/src/lib/python/isc/config/config_data.py b/src/lib/python/isc/config/config_data.py
index 582c11c..cee1d34 100644
--- a/src/lib/python/isc/config/config_data.py
+++ b/src/lib/python/isc/config/config_data.py
@@ -461,8 +461,8 @@ class MultiConfigData:
                 spec_part_list = spec_part['list_item_spec']
                 list_value, status = self.get_value(identifier)
                 if list_value is None:
-                    print("Error: identifier '%s' not found" % identifier)
-                    return
+                    raise isc.cc.data.DataNotFoundError(identifier)
+
                 if type(list_value) != list:
                     # the identifier specified a single element
                     self._append_value_item(result, spec_part_list, identifier, all)
diff --git a/src/lib/python/isc/config/tests/config_data_test.py b/src/lib/python/isc/config/tests/config_data_test.py
index 1aded94..923e0b6 100644
--- a/src/lib/python/isc/config/tests/config_data_test.py
+++ b/src/lib/python/isc/config/tests/config_data_test.py
@@ -465,8 +465,8 @@ class TestMultiConfigData(unittest.TestCase):
 
         module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec24.spec")
         self.mcd.set_specification(module_spec)
-        maps = self.mcd.get_value_maps("/Spec24/item")
-        self.assertEqual([], maps)
+        self.assertRaises(isc.cc.data.DataNotFoundError,
+                          self.mcd.get_value_maps, "/Spec24/item", 4)
         self.mcd._set_current_config({ "Spec24": { "item": [] } })
         maps = self.mcd.get_value_maps("/Spec24/item")
         self.assertEqual([{'default': False, 'modified': False, 'name': 'Spec24/item', 'type': 'list', 'value': []}], maps)
diff --git a/src/lib/resolve/resolver_callback.h b/src/lib/resolve/resolver_callback.h
index f69d8a7..4244f19 100644
--- a/src/lib/resolve/resolver_callback.h
+++ b/src/lib/resolve/resolver_callback.h
@@ -15,9 +15,11 @@
 #ifndef _ISC_RESOLVER_CALLBACK_H
 #define _ISC_RESOLVER_CALLBACK_H 1
 
-#include <asiolink/asiolink.h>
+#include <asiolink/dns_server.h>
 #include <dns/message.h>
 
+#include <resolve/resolver_interface.h>
+
 namespace isc {
 namespace resolve {
 
diff --git a/src/lib/resolve/tests/resolver_callback_unittest.cc b/src/lib/resolve/tests/resolver_callback_unittest.cc
index 6370e22..666b853 100644
--- a/src/lib/resolve/tests/resolver_callback_unittest.cc
+++ b/src/lib/resolve/tests/resolver_callback_unittest.cc
@@ -13,8 +13,8 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <gtest/gtest.h>
+#include <asiolink/dns_server.h>
 #include <resolve/resolver_callback.h>
-#include <asiolink/asiolink.h>
 
 using namespace isc::resolve;
 
diff --git a/src/lib/testutils/srv_test.cc b/src/lib/testutils/srv_test.cc
index 4fec4ca..d5da8a0 100644
--- a/src/lib/testutils/srv_test.cc
+++ b/src/lib/testutils/srv_test.cc
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <config.h>
+
 #include <netinet/in.h>
 
 #include <dns/message.h>




More information about the bind10-changes mailing list