BIND 10 master, updated. 2cba8cb83cde4f34842898a848c0b1182bc20597 [master] Merge branch 'trac1424'
BIND 10 source code commits
bind10-changes at lists.isc.org
Sat Dec 31 02:03:49 UTC 2011
The branch, master has been updated
via 2cba8cb83cde4f34842898a848c0b1182bc20597 (commit)
via 365c733b967c7b0a53122f62931d459d1ec63b35 (commit)
via 2818dab13b61cdbbee27076e820e4069e3dd14d4 (commit)
from 1bc918fff46c6c812f73be52c107c8e394a5f0c5 (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 2cba8cb83cde4f34842898a848c0b1182bc20597
Merge: 1bc918f 365c733
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Fri Dec 30 18:00:55 2011 -0800
[master] Merge branch 'trac1424'
-----------------------------------------------------------------------
Summary of changes:
src/bin/resolver/main.cc | 5 +-
src/bin/resolver/resolver.cc | 12 +-
src/bin/resolver/resolver.h | 20 +--
src/bin/resolver/tests/resolver_config_unittest.cc | 124 +++++++++++++++++++-
src/bin/resolver/tests/resolver_unittest.cc | 1 -
5 files changed, 141 insertions(+), 21 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/resolver/main.cc b/src/bin/resolver/main.cc
index 79146da..090f211 100644
--- a/src/bin/resolver/main.cc
+++ b/src/bin/resolver/main.cc
@@ -220,7 +220,10 @@ main(int argc, char* argv[]) {
// Install all initial configurations. If loading configuration
// fails, it will be logged, but we start the server anyway, giving
// the user a second chance to correct the configuration.
- resolver->updateConfig(config_session->getFullConfig());
+ // By setting the 'startup' parameter to true, we ensure most of
+ // the default configuration will be installed even if listen_on
+ // fails.
+ resolver->updateConfig(config_session->getFullConfig(), true);
LOG_DEBUG(resolver_logger, RESOLVER_DBG_INIT, RESOLVER_CONFIG_LOADED);
LOG_INFO(resolver_logger, RESOLVER_STARTED);
diff --git a/src/bin/resolver/resolver.cc b/src/bin/resolver/resolver.cc
index be70f1b..367c16c 100644
--- a/src/bin/resolver/resolver.cc
+++ b/src/bin/resolver/resolver.cc
@@ -356,8 +356,7 @@ Resolver::Resolver() :
dns_lookup_(NULL),
dns_answer_(new MessageAnswer),
nsas_(NULL),
- cache_(NULL),
- configured_(false)
+ cache_(NULL)
{
// Operations referring to "this" must be done in the constructor body
// (some compilers will issue warnings if "this" is referred to in the
@@ -585,7 +584,7 @@ ResolverImpl::processNormalQuery(const IOMessage& io_message,
}
ConstElementPtr
-Resolver::updateConfig(ConstElementPtr config) {
+Resolver::updateConfig(ConstElementPtr config, bool startup) {
LOG_DEBUG(resolver_logger, RESOLVER_DBG_CONFIG, RESOLVER_CONFIG_UPDATED)
.arg(*config);
@@ -658,7 +657,7 @@ Resolver::updateConfig(ConstElementPtr config) {
// listenAddresses can fail to bind, so try them first
bool need_query_restart = false;
- if (listenAddressesE) {
+ if (!startup && listenAddressesE) {
setListenAddresses(listenAddresses);
need_query_restart = true;
}
@@ -677,12 +676,15 @@ Resolver::updateConfig(ConstElementPtr config) {
if (query_acl) {
setQueryACL(query_acl);
}
+ if (startup && listenAddressesE) {
+ setListenAddresses(listenAddresses);
+ need_query_restart = true;
+ }
if (need_query_restart) {
impl_->queryShutdown();
impl_->querySetup(*dnss_, *nsas_, *cache_);
}
- setConfigured();
return (isc::config::createAnswer());
} catch (const isc::Exception& error) {
diff --git a/src/bin/resolver/resolver.h b/src/bin/resolver/resolver.h
index 4b9c773..096f522 100644
--- a/src/bin/resolver/resolver.h
+++ b/src/bin/resolver/resolver.h
@@ -95,8 +95,13 @@ public:
isc::config::ModuleCCSession* getConfigSession() const;
void setConfigSession(isc::config::ModuleCCSession* config_session);
- /// \brief Handle commands from the config session
- isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
+ /// \brief Handle commands from the config session.
+ ///
+ /// By default, or if \c startup is set to false explicitly, this method
+ /// will ignore any other configuration parameters if listen_on fails;
+ /// if \c startup is true, it will install as many parameters as possible.
+ isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config,
+ bool startup = false);
/// \brief Assign an ASIO IO Service queue to this Resolver object
void setDNSService(isc::asiodns::DNSService& dnss);
@@ -130,13 +135,6 @@ public:
isc::asiolink::SimpleCallback* getCheckinProvider() { return (checkin_); }
/**
- * \brief Tell the Resolver that is has already been configured
- * so that it will only set some defaults the first time
- * (used by updateConfig() and tests)
- */
- void setConfigured() { configured_ = true; };
-
- /**
* \brief Specify the list of upstream servers.
*
* Specify the list off addresses of upstream servers to forward queries
@@ -266,10 +264,6 @@ private:
isc::asiodns::DNSAnswer* dns_answer_;
isc::nsas::NameserverAddressStore* nsas_;
isc::cache::ResolverCache* cache_;
- // This value is initally false, and will be set to true
- // when the initial configuration is done (updateConfig
- // should act a tiny bit different on the very first call)
- bool configured_;
};
#endif // __RESOLVER_H
diff --git a/src/bin/resolver/tests/resolver_config_unittest.cc b/src/bin/resolver/tests/resolver_config_unittest.cc
index c089041..7169331 100644
--- a/src/bin/resolver/tests/resolver_config_unittest.cc
+++ b/src/bin/resolver/tests/resolver_config_unittest.cc
@@ -14,12 +14,22 @@
#include <config.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <cerrno>
+#include <cstring>
#include <string>
#include <boost/scoped_ptr.hpp>
+#include <boost/noncopyable.hpp>
#include <gtest/gtest.h>
+#include <exceptions/exceptions.h>
+
#include <cc/data.h>
#include <config/ccsession.h>
@@ -52,6 +62,16 @@ using namespace isc::server_common;
using isc::UnitTestUtil;
namespace {
+const char* const TEST_ADDRESS = "127.0.0.1";
+const char* const TEST_PORT = "53535";
+
+// An internal exception class
+class TestConfigError : public isc::Exception {
+public:
+ TestConfigError(const char *file, size_t line, const char *what):
+ isc::Exception(file, line, what) {}
+};
+
class ResolverConfig : public ::testing::Test {
protected:
IOService ios;
@@ -63,7 +83,6 @@ protected:
scoped_ptr<const RequestContext> request;
ResolverConfig() : dnss(ios, NULL, NULL, NULL) {
server.setDNSService(dnss);
- server.setConfigured();
}
const RequestContext& createRequest(const string& source_addr) {
endpoint.reset(IOEndpoint::create(IPPROTO_UDP, IOAddress(source_addr),
@@ -155,6 +174,109 @@ TEST_F(ResolverConfig, rootAddressConfig) {
EXPECT_EQ(0, server.getRootAddresses().size());
}
+// The following two are helper classes to manage some temporary system
+// resources in an RAII manner.
+class ScopedAddrInfo : public boost::noncopyable {
+public:
+ ScopedAddrInfo(struct addrinfo* ai) : ai_(ai) {}
+ ~ScopedAddrInfo() { freeaddrinfo(ai_);}
+private:
+ struct addrinfo* ai_;
+};
+
+struct ScopedSocket : public boost::noncopyable {
+public:
+ ScopedSocket(int fd) : fd_(fd) {}
+ ~ScopedSocket() { close(fd_); }
+private:
+ const int fd_;
+};
+
+int
+createSocket(const char* address, const char* port) {
+ struct addrinfo hints, *res;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
+ const int error = getaddrinfo(address, port, &hints, &res);
+ if (error != 0) {
+ isc_throw(TestConfigError, "getaddrinfo failed: " <<
+ gai_strerror(error));
+ }
+ ScopedAddrInfo scoped_res(res);
+ const int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (s == -1) {
+ isc_throw(TestConfigError, "socket system call failed: " <<
+ strerror(errno));
+ }
+ if (bind(s, res->ai_addr, res->ai_addrlen) == -1) {
+ close(s);
+ isc_throw(TestConfigError, "bind system call failed: " <<
+ strerror(errno));
+ }
+ return (s);
+}
+
+void
+configAnswerCheck(ConstElementPtr config_answer, bool expect_success) {
+ EXPECT_EQ(Element::map, config_answer->getType());
+ EXPECT_TRUE(config_answer->contains("result"));
+
+ ConstElementPtr result = config_answer->get("result");
+ EXPECT_EQ(Element::list, result->getType());
+ EXPECT_EQ(expect_success ? 0 : 1, result->get(0)->intValue());
+}
+
+TEST_F(ResolverConfig, listenOnConfig) {
+ ConstElementPtr config(Element::fromJSON("{"
+ "\"listen_on\": ["
+ " {"
+ " \"address\": \"" +
+ string(TEST_ADDRESS) + "\","
+ " \"port\": " +
+ string(TEST_PORT) + "}]}"));
+ configAnswerCheck(server.updateConfig(config), true);
+}
+
+TEST_F(ResolverConfig, listenOnConfigFail) {
+ // Create and bind a socket that would make the subsequent listen_on fail
+ ScopedSocket sock(createSocket(TEST_ADDRESS, TEST_PORT));
+
+ ConstElementPtr config(Element::fromJSON("{"
+ "\"listen_on\": ["
+ " {"
+ " \"address\": \"" +
+ string(TEST_ADDRESS) + "\","
+ " \"port\": " +
+ string(TEST_PORT) + "}]}"));
+ configAnswerCheck(server.updateConfig(config), false);
+}
+
+TEST_F(ResolverConfig, listenOnAndOtherConfig) {
+ // Create and bind a socket that would make the subsequent listen_on fail
+ ScopedSocket sock(createSocket(TEST_ADDRESS, TEST_PORT));
+
+ // We are going to install a pair of "root_addresses" and "listen_on"
+ // in a single update.
+ const string config_str("{\"root_addresses\": ["
+ " {\"address\": \"192.0.2.1\","
+ " \"port\": 53}], "
+ "\"listen_on\": ["
+ " {\"address\": \"" + string(TEST_ADDRESS) + "\","
+ " \"port\": " + string(TEST_PORT) + "}]}");
+ // Normally, if listen_on fails the rest of the config parameters will
+ // be ignored.
+ ConstElementPtr config(Element::fromJSON(config_str));
+ configAnswerCheck(server.updateConfig(config), false);
+ EXPECT_EQ(0, server.getRootAddresses().size());
+
+ // On startup the other parameters will be installed anyway.
+ configAnswerCheck(server.updateConfig(config, true), false);
+ EXPECT_EQ(1, server.getRootAddresses().size());
+}
+
void
ResolverConfig::invalidTest(const string &JSON, const string& name) {
isc::testutils::portconfig::configRejected(server, JSON, name);
diff --git a/src/bin/resolver/tests/resolver_unittest.cc b/src/bin/resolver/tests/resolver_unittest.cc
index 71474dd..6b5cf68 100644
--- a/src/bin/resolver/tests/resolver_unittest.cc
+++ b/src/bin/resolver/tests/resolver_unittest.cc
@@ -39,7 +39,6 @@ protected:
ResolverTest() : server() {
// By default queries from the "default remote address" will be
// rejected, so we'll need to add an explicit ACL entry to allow that.
- server.setConfigured();
server.updateConfig(Element::fromJSON(
"{ \"query_acl\": "
" [ {\"action\": \"ACCEPT\","
More information about the bind10-changes
mailing list