Commit 71009538 authored by Stephen Morris's avatar Stephen Morris
Browse files

Merge branch 'master' into trac1077

parents dd356abb c0578172
267. [func] stephen
268. [func] stephen
Add environment variable to allow redirection of logging output during
unit tests.
(Trac #1071, git 05164f9d61006869233b498d248486b4307ea8b6)
267. [func] tomek
Added a dummy module for DHCP6. This module does not actually
do anything at this point, and BIND 10 has no option for
starting it yet. It is included as a base for further
development.
(Trac #990, git 4a590df96a1b1d373e87f1f56edaceccb95f267d)
266. [func] Multiple developers
Convert various error messages, debugging and other output
to the new logging interface, including for b10-resolver,
......
......@@ -48,9 +48,9 @@ using namespace isc::datasrc;
using namespace isc::config;
namespace {
class AuthConmmandTest : public ::testing::Test {
class AuthCommandTest : public ::testing::Test {
protected:
AuthConmmandTest() : server(false, xfrout), rcode(-1) {
AuthCommandTest() : server(false, xfrout), rcode(-1) {
server.setStatisticsSession(&statistics_session);
}
void checkAnswer(const int expected_code) {
......@@ -67,14 +67,14 @@ public:
void stopServer(); // need to be public for boost::bind
};
TEST_F(AuthConmmandTest, unknownCommand) {
TEST_F(AuthCommandTest, unknownCommand) {
result = execAuthServerCommand(server, "no_such_command",
ConstElementPtr());
parseAnswer(rcode, result);
EXPECT_EQ(1, rcode);
}
TEST_F(AuthConmmandTest, DISABLED_unexpectedException) {
TEST_F(AuthCommandTest, DISABLED_unexpectedException) {
// execAuthServerCommand() won't catch standard exceptions.
// Skip this test for now: ModuleCCSession doesn't seem to validate
// commands.
......@@ -83,7 +83,7 @@ TEST_F(AuthConmmandTest, DISABLED_unexpectedException) {
runtime_error);
}
TEST_F(AuthConmmandTest, sendStatistics) {
TEST_F(AuthCommandTest, sendStatistics) {
result = execAuthServerCommand(server, "sendstats", ConstElementPtr());
// Just check some message has been sent. Detailed tests specific to
// statistics are done in its own tests.
......@@ -92,15 +92,15 @@ TEST_F(AuthConmmandTest, sendStatistics) {
}
void
AuthConmmandTest::stopServer() {
AuthCommandTest::stopServer() {
result = execAuthServerCommand(server, "shutdown", ConstElementPtr());
parseAnswer(rcode, result);
assert(rcode == 0); // make sure the test stops when something is wrong
}
TEST_F(AuthConmmandTest, shutdown) {
TEST_F(AuthCommandTest, shutdown) {
isc::asiolink::IntervalTimer itimer(server.getIOService());
itimer.setup(boost::bind(&AuthConmmandTest::stopServer, this), 1);
itimer.setup(boost::bind(&AuthCommandTest::stopServer, this), 1);
server.getIOService().run();
EXPECT_EQ(0, rcode);
}
......@@ -165,7 +165,7 @@ newZoneChecks(AuthSrv& server) {
find(Name("ns.test2.example"), RRType::AAAA()).code);
}
TEST_F(AuthConmmandTest, loadZone) {
TEST_F(AuthCommandTest, loadZone) {
configureZones(server);
ASSERT_EQ(0, system(INSTALL_PROG " " TEST_DATA_DIR
......@@ -182,7 +182,7 @@ TEST_F(AuthConmmandTest, loadZone) {
newZoneChecks(server);
}
TEST_F(AuthConmmandTest, loadBrokenZone) {
TEST_F(AuthCommandTest, loadBrokenZone) {
configureZones(server);
ASSERT_EQ(0, system(INSTALL_PROG " " TEST_DATA_DIR
......@@ -195,7 +195,7 @@ TEST_F(AuthConmmandTest, loadBrokenZone) {
zoneChecks(server); // zone shouldn't be replaced
}
TEST_F(AuthConmmandTest, loadUnreadableZone) {
TEST_F(AuthCommandTest, loadUnreadableZone) {
configureZones(server);
// install the zone file as unreadable
......@@ -209,7 +209,7 @@ TEST_F(AuthConmmandTest, loadUnreadableZone) {
zoneChecks(server); // zone shouldn't be replaced
}
TEST_F(AuthConmmandTest, loadZoneWithoutDataSrc) {
TEST_F(AuthCommandTest, loadZoneWithoutDataSrc) {
// try to execute load command without configuring the zone beforehand.
// it should fail.
result = execAuthServerCommand(server, "loadzone",
......@@ -218,7 +218,7 @@ TEST_F(AuthConmmandTest, loadZoneWithoutDataSrc) {
checkAnswer(1);
}
TEST_F(AuthConmmandTest, loadSqlite3DataSrc) {
TEST_F(AuthCommandTest, loadSqlite3DataSrc) {
// For sqlite3 data source we don't have to do anything (the data source
// (re)loads itself automatically)
result = execAuthServerCommand(server, "loadzone",
......@@ -228,7 +228,7 @@ TEST_F(AuthConmmandTest, loadSqlite3DataSrc) {
checkAnswer(0);
}
TEST_F(AuthConmmandTest, loadZoneInvalidParams) {
TEST_F(AuthCommandTest, loadZoneInvalidParams) {
configureZones(server);
// null arg
......
......@@ -60,6 +60,7 @@ b10_resolver_LDADD = $(top_builddir)/src/lib/dns/libdns++.la
b10_resolver_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
b10_resolver_LDADD += $(top_builddir)/src/lib/cc/libcc.la
b10_resolver_LDADD += $(top_builddir)/src/lib/util/libutil.la
b10_resolver_LDADD += $(top_builddir)/src/lib/acl/libdnsacl.la
b10_resolver_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
b10_resolver_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
b10_resolver_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
......@@ -68,7 +69,6 @@ b10_resolver_LDADD += $(top_builddir)/src/lib/log/liblog.la
b10_resolver_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la
b10_resolver_LDADD += $(top_builddir)/src/lib/cache/libcache.la
b10_resolver_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
b10_resolver_LDADD += $(top_builddir)/src/lib/acl/libacl.la
b10_resolver_LDADD += $(top_builddir)/src/lib/resolve/libresolve.la
b10_resolver_LDADD += $(top_builddir)/src/bin/auth/change_user.o
b10_resolver_LDFLAGS = -pthread
......
......@@ -26,7 +26,7 @@
#include <exceptions/exceptions.h>
#include <acl/acl.h>
#include <acl/dns.h>
#include <acl/loader.h>
#include <asiodns/asiodns.h>
......@@ -62,6 +62,7 @@ using boost::shared_ptr;
using namespace isc;
using namespace isc::util;
using namespace isc::acl;
using isc::acl::dns::RequestACL;
using namespace isc::dns;
using namespace isc::data;
using namespace isc::config;
......@@ -82,7 +83,9 @@ public:
client_timeout_(4000),
lookup_timeout_(30000),
retries_(3),
query_acl_(new Resolver::ClientACL(REJECT)),
// we apply "reject all" (implicit default of the loader) ACL by
// default:
query_acl_(acl::dns::getRequestLoader().load(Element::fromJSON("[]"))),
rec_query_(NULL)
{}
......@@ -160,11 +163,11 @@ public:
OutputBufferPtr buffer,
DNSServer* server);
const Resolver::ClientACL& getQueryACL() const {
const RequestACL& getQueryACL() const {
return (*query_acl_);
}
void setQueryACL(shared_ptr<const Resolver::ClientACL> new_acl) {
void setQueryACL(shared_ptr<const RequestACL> new_acl) {
query_acl_ = new_acl;
}
......@@ -192,7 +195,7 @@ public:
private:
/// ACL on incoming queries
shared_ptr<const Resolver::ClientACL> query_acl_;
shared_ptr<const RequestACL> query_acl_;
/// Object to handle upstream queries
RecursiveQuery* rec_query_;
......@@ -514,8 +517,10 @@ ResolverImpl::processNormalQuery(const IOMessage& io_message,
const RRClass qclass = question->getClass();
// Apply query ACL
Client client(io_message);
const BasicAction query_action(getQueryACL().execute(client));
const Client client(io_message);
const BasicAction query_action(
getQueryACL().execute(acl::dns::RequestContext(
client.getRequestSourceIPAddress())));
if (query_action == isc::acl::REJECT) {
LOG_INFO(resolver_logger, RESOLVER_QUERY_REJECTED)
.arg(question->getName()).arg(qtype).arg(qclass).arg(client);
......@@ -574,32 +579,6 @@ ResolverImpl::processNormalQuery(const IOMessage& io_message,
return (RECURSION);
}
namespace {
// This is a simplified ACL parser for the initial implementation with minimal
// external dependency. For a longer term we'll switch to a more generic
// loader with allowing more complicated ACL syntax.
shared_ptr<const Resolver::ClientACL>
createQueryACL(isc::data::ConstElementPtr acl_config) {
if (!acl_config) {
return (shared_ptr<const Resolver::ClientACL>());
}
shared_ptr<Resolver::ClientACL> new_acl(
new Resolver::ClientACL(REJECT));
BOOST_FOREACH(ConstElementPtr rule, acl_config->listValue()) {
ConstElementPtr action = rule->get("action");
ConstElementPtr from = rule->get("from");
if (!action || !from) {
isc_throw(BadValue, "query ACL misses mandatory parameter");
}
new_acl->append(shared_ptr<IPCheck<Client> >(
new IPCheck<Client>(from->stringValue())),
defaultActionLoader(action));
}
return (new_acl);
}
}
ConstElementPtr
Resolver::updateConfig(ConstElementPtr config) {
LOG_DEBUG(resolver_logger, RESOLVER_DBG_CONFIG, RESOLVER_CONFIG_UPDATED)
......@@ -616,8 +595,10 @@ Resolver::updateConfig(ConstElementPtr config) {
ConstElementPtr listenAddressesE(config->get("listen_on"));
AddressList listenAddresses(parseAddresses(listenAddressesE,
"listen_on"));
shared_ptr<const ClientACL> query_acl(createQueryACL(
config->get("query_acl")));
const ConstElementPtr query_acl_cfg(config->get("query_acl"));
const shared_ptr<const RequestACL> query_acl =
query_acl_cfg ? acl::dns::getRequestLoader().load(query_acl_cfg) :
shared_ptr<RequestACL>();
bool set_timeouts(false);
int qtimeout = impl_->query_timeout_;
int ctimeout = impl_->client_timeout_;
......@@ -777,13 +758,13 @@ Resolver::getListenAddresses() const {
return (impl_->listen_);
}
const Resolver::ClientACL&
const RequestACL&
Resolver::getQueryACL() const {
return (impl_->getQueryACL());
}
void
Resolver::setQueryACL(shared_ptr<const ClientACL> new_acl) {
Resolver::setQueryACL(shared_ptr<const RequestACL> new_acl) {
if (!new_acl) {
isc_throw(InvalidParameter, "NULL pointer is passed to setQueryACL");
}
......
......@@ -21,10 +21,9 @@
#include <boost/shared_ptr.hpp>
#include <acl/acl.h>
#include <cc/data.h>
#include <config/ccsession.h>
#include <acl/dns.h>
#include <dns/message.h>
#include <util/buffer.h>
......@@ -41,12 +40,6 @@
#include <resolve/resolver_interface.h>
namespace isc {
namespace server_common {
class Client;
}
}
class ResolverImpl;
/**
......@@ -246,13 +239,10 @@ public:
*/
int getRetries() const;
// Shortcut typedef used for query ACL.
typedef isc::acl::ACL<isc::server_common::Client> ClientACL;
/// Get the query ACL.
///
/// \exception None
const ClientACL& getQueryACL() const;
const isc::acl::dns::RequestACL& getQueryACL() const;
/// Set the new query ACL.
///
......@@ -265,7 +255,8 @@ public:
/// \exception InvalidParameter The given pointer is NULL
///
/// \param new_acl The new ACL to replace the existing one.
void setQueryACL(boost::shared_ptr<const ClientACL> new_acl);
void setQueryACL(boost::shared_ptr<const isc::acl::dns::RequestACL>
new_acl);
private:
ResolverImpl* impl_;
......
......@@ -39,6 +39,7 @@ run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
run_unittests_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
run_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
run_unittests_LDADD += $(top_builddir)/src/lib/acl/libdnsacl.la
run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
run_unittests_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
......
......@@ -43,6 +43,7 @@
using namespace std;
using boost::scoped_ptr;
using namespace isc::acl;
using isc::acl::dns::RequestContext;
using namespace isc::data;
using namespace isc::testutils;
using namespace isc::asiodns;
......@@ -57,19 +58,22 @@ protected:
DNSService dnss;
Resolver server;
scoped_ptr<const IOEndpoint> endpoint;
scoped_ptr<const IOMessage> request;
scoped_ptr<const IOMessage> query_message;
scoped_ptr<const Client> client;
scoped_ptr<const RequestContext> request;
ResolverConfig() : dnss(ios, NULL, NULL, NULL) {
server.setDNSService(dnss);
server.setConfigured();
}
const Client& createClient(const string& source_addr) {
const RequestContext& createRequest(const string& source_addr) {
endpoint.reset(IOEndpoint::create(IPPROTO_UDP, IOAddress(source_addr),
53210));
request.reset(new IOMessage(NULL, 0, IOSocket::getDummyUDPSocket(),
*endpoint));
client.reset(new Client(*request));
return (*client);
query_message.reset(new IOMessage(NULL, 0,
IOSocket::getDummyUDPSocket(),
*endpoint));
client.reset(new Client(*query_message));
request.reset(new RequestContext(client->getRequestSourceIPAddress()));
return (*request);
}
void invalidTest(const string &JSON, const string& name);
};
......@@ -100,14 +104,14 @@ TEST_F(ResolverConfig, forwardAddresses) {
TEST_F(ResolverConfig, forwardAddressConfig) {
// Try putting there some address
ElementPtr config(Element::fromJSON("{"
"\"forward_addresses\": ["
" {"
" \"address\": \"192.0.2.1\","
" \"port\": 53"
" }"
"]"
"}"));
ConstElementPtr config(Element::fromJSON("{"
"\"forward_addresses\": ["
" {"
" \"address\": \"192.0.2.1\","
" \"port\": 53"
" }"
"]"
"}"));
ConstElementPtr result(server.updateConfig(config));
EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
EXPECT_TRUE(server.isForwarding());
......@@ -127,14 +131,14 @@ TEST_F(ResolverConfig, forwardAddressConfig) {
TEST_F(ResolverConfig, rootAddressConfig) {
// Try putting there some address
ElementPtr config(Element::fromJSON("{"
"\"root_addresses\": ["
" {"
" \"address\": \"192.0.2.1\","
" \"port\": 53"
" }"
"]"
"}"));
ConstElementPtr config(Element::fromJSON("{"
"\"root_addresses\": ["
" {"
" \"address\": \"192.0.2.1\","
" \"port\": 53"
" }"
"]"
"}"));
ConstElementPtr result(server.updateConfig(config));
EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
ASSERT_EQ(1, server.getRootAddresses().size());
......@@ -210,12 +214,12 @@ TEST_F(ResolverConfig, timeouts) {
}
TEST_F(ResolverConfig, timeoutsConfig) {
ElementPtr config = Element::fromJSON("{"
"\"timeout_query\": 1000,"
"\"timeout_client\": 2000,"
"\"timeout_lookup\": 3000,"
"\"retries\": 4"
"}");
ConstElementPtr config = Element::fromJSON("{"
"\"timeout_query\": 1000,"
"\"timeout_client\": 2000,"
"\"timeout_lookup\": 3000,"
"\"retries\": 4"
"}");
ConstElementPtr result(server.updateConfig(config));
EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
EXPECT_EQ(1000, server.getQueryTimeout());
......@@ -253,51 +257,51 @@ TEST_F(ResolverConfig, invalidTimeoutsConfig) {
TEST_F(ResolverConfig, defaultQueryACL) {
// If no configuration is loaded, the default ACL should reject everything.
EXPECT_EQ(REJECT, server.getQueryACL().execute(createClient("192.0.2.1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(createRequest("192.0.2.1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(
createClient("2001:db8::1")));
createRequest("2001:db8::1")));
// The following would be allowed if the server had loaded the default
// configuration from the spec file. In this context it should not have
// happened, and they should be rejected just like the above cases.
EXPECT_EQ(REJECT, server.getQueryACL().execute(createClient("127.0.0.1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(createClient("::1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(createRequest("127.0.0.1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(createRequest("::1")));
}
TEST_F(ResolverConfig, emptyQueryACL) {
// Explicitly configured empty ACL should have the same effect.
ElementPtr config(Element::fromJSON("{ \"query_acl\": [] }"));
ConstElementPtr config(Element::fromJSON("{ \"query_acl\": [] }"));
ConstElementPtr result(server.updateConfig(config));
EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
EXPECT_EQ(REJECT, server.getQueryACL().execute(createClient("192.0.2.1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(createRequest("192.0.2.1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(
createClient("2001:db8::1")));
createRequest("2001:db8::1")));
}
TEST_F(ResolverConfig, queryACLIPv4) {
// A simple "accept" query for a specific IPv4 address
ElementPtr config(Element::fromJSON(
"{ \"query_acl\": "
" [ {\"action\": \"ACCEPT\","
" \"from\": \"192.0.2.1\"} ] }"));
ConstElementPtr config(Element::fromJSON(
"{ \"query_acl\": "
" [ {\"action\": \"ACCEPT\","
" \"from\": \"192.0.2.1\"} ] }"));
ConstElementPtr result(server.updateConfig(config));
EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
EXPECT_EQ(ACCEPT, server.getQueryACL().execute(createClient("192.0.2.1")));
EXPECT_EQ(ACCEPT, server.getQueryACL().execute(createRequest("192.0.2.1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(
createClient("2001:db8::1")));
createRequest("2001:db8::1")));
}
TEST_F(ResolverConfig, queryACLIPv6) {
// same for IPv6
ElementPtr config(Element::fromJSON(
"{ \"query_acl\": "
" [ {\"action\": \"ACCEPT\","
" \"from\": \"2001:db8::1\"} ] }"));
ConstElementPtr config(Element::fromJSON(
"{ \"query_acl\": "
" [ {\"action\": \"ACCEPT\","
" \"from\": \"2001:db8::1\"} ] }"));
ConstElementPtr result(server.updateConfig(config));
EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
EXPECT_EQ(REJECT, server.getQueryACL().execute(createClient("192.0.2.1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(createRequest("192.0.2.1")));
EXPECT_EQ(ACCEPT, server.getQueryACL().execute(
createClient("2001:db8::1")));
createRequest("2001:db8::1")));
}
TEST_F(ResolverConfig, multiEntryACL) {
......@@ -306,25 +310,26 @@ TEST_F(ResolverConfig, multiEntryACL) {
// as it should have been tested in the underlying ACL module. All we
// have to do to check is a reasonably complicated ACL configuration is
// loaded as expected.
ElementPtr config(Element::fromJSON(
"{ \"query_acl\": "
" [ {\"action\": \"ACCEPT\","
" \"from\": \"192.0.2.1\"},"
" {\"action\": \"REJECT\","
" \"from\": \"192.0.2.0/24\"},"
" {\"action\": \"DROP\","
" \"from\": \"2001:db8::1\"},"
"] }"));
ConstElementPtr config(Element::fromJSON(
"{ \"query_acl\": "
" [ {\"action\": \"ACCEPT\","
" \"from\": \"192.0.2.1\"},"
" {\"action\": \"REJECT\","
" \"from\": \"192.0.2.0/24\"},"
" {\"action\": \"DROP\","
" \"from\": \"2001:db8::1\"},"
"] }"));
ConstElementPtr result(server.updateConfig(config));
EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
EXPECT_EQ(ACCEPT, server.getQueryACL().execute(createClient("192.0.2.1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(createClient("192.0.2.2")));
EXPECT_EQ(ACCEPT, server.getQueryACL().execute(createRequest("192.0.2.1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(createRequest("192.0.2.2")));
EXPECT_EQ(DROP, server.getQueryACL().execute(
createClient("2001:db8::1")));
createRequest("2001:db8::1")));
EXPECT_EQ(REJECT, server.getQueryACL().execute(
createClient("2001:db8::2"))); // match the default rule
createRequest("2001:db8::2"))); // match the default rule
}
int
getResultCode(ConstElementPtr result) {
int rcode;
......@@ -332,6 +337,22 @@ getResultCode(ConstElementPtr result) {
return (rcode);
}
TEST_F(ResolverConfig, queryACLActionOnly) {
// "action only" rule will be accepted by the loader, which can
// effectively change the default action.
ConstElementPtr config(Element::fromJSON(
"{ \"query_acl\": "
" [ {\"action\": \"ACCEPT\","
" \"from\": \"192.0.2.1\"},"
" {\"action\": \"DROP\"} ] }"));
EXPECT_EQ(0, getResultCode(server.updateConfig(config)));
EXPECT_EQ(ACCEPT, server.getQueryACL().execute(createRequest("192.0.2.1")));
// We reject non matching queries by default, but the last resort
// rule should have changed the action in that case to "DROP".
EXPECT_EQ(DROP, server.getQueryACL().execute(createRequest("192.0.2.2")));
}
TEST_F(ResolverConfig, badQueryACL) {
// Most of these cases shouldn't happen in practice because the syntax
// check should be performed before updateConfig(). But we check at
......@@ -346,10 +367,6 @@ TEST_F(ResolverConfig, badQueryACL) {
server.updateConfig(
Element::fromJSON("{ \"query_acl\":"
" [ {\"from\": \"192.0.2.1\"} ] }"))));
EXPECT_EQ(1, getResultCode(
server.updateConfig(
Element::fromJSON("{ \"query_acl\":"
" [ {\"action\": \"DROP\"} ] }"))));
// invalid "action"
EXPECT_EQ(1, getResultCode(
server.updateConfig(
......@@ -361,7 +378,6 @@ TEST_F(ResolverConfig, badQueryACL) {
Element::fromJSON("{ \"query_acl\":"
" [ {\"action\": \"BADACTION\","
" \"from\": \"192.0.2.1\"}]}"))));
// invalid "from"
EXPECT_EQ(1, getResultCode(
server.updateConfig(
......
......@@ -27,6 +27,7 @@
using namespace std;
using namespace isc::dns;
using namespace isc::data;
using isc::acl::dns::RequestACL;
using namespace isc::testutils;
using isc::UnitTestUtil;
......@@ -156,8 +157,7 @@ TEST_F(ResolverTest, notifyFail) {
TEST_F(ResolverTest, setQueryACL) {
// valid cases are tested through other tests. We only explicitly check
// an invalid case: passing a NULL shared pointer.
EXPECT_THROW(server.setQueryACL(
boost::shared_ptr<const Resolver::ClientACL>()),
EXPECT_THROW(server.setQueryACL(boost::shared_ptr<const RequestACL>()),
isc::InvalidParameter);
}
......
......@@ -12,20 +12,107 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include "dns.h"
#include <memory>
#include <string>
#include <vector>