[svn] commit: r3903 - in /trunk: ./ doc/ src/bin/auth/ src/bin/auth/benchmarks/ src/bin/auth/tests/ src/bin/auth/tests/testdata/ src/bin/bind10/ src/bin/bind10/tests/ src/bin/recurse/ src/bin/stats/tests/isc/util/ src/lib/ src/lib/asiolink/ src/lib/cc/ src/lib/dns/ src/lib/dns/tests/ src/lib/log/ src/lib/python/isc/utils/ src/lib/testutils/
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Dec 20 23:14:49 UTC 2010
Author: jelte
Date: Mon Dec 20 23:14:49 2010
New Revision: 3903
Log:
merged branches/trac327
Added:
trunk/src/bin/recurse/
- copied from r3902, branches/trac327/src/bin/recurse/
trunk/src/bin/recurse/Makefile.am
- copied unchanged from r3902, branches/trac327/src/bin/recurse/Makefile.am
trunk/src/bin/recurse/recurse.spec.pre.in
- copied unchanged from r3902, branches/trac327/src/bin/recurse/recurse.spec.pre.in
trunk/src/lib/asiolink/
- copied from r3902, branches/trac327/src/lib/asiolink/
trunk/src/lib/log/
- copied from r3902, branches/trac327/src/lib/log/
trunk/src/lib/testutils/
- copied from r3902, branches/trac327/src/lib/testutils/
Removed:
trunk/src/bin/auth/asio_link.cc
trunk/src/bin/auth/asio_link.h
trunk/src/bin/auth/tests/asio_link_unittest.cc
trunk/src/bin/auth/tests/testdata/
trunk/src/lib/python/isc/utils/
Modified:
trunk/ (props changed)
trunk/ChangeLog
trunk/configure.ac
trunk/doc/Doxyfile
trunk/src/bin/auth/Makefile.am
trunk/src/bin/auth/auth_srv.cc
trunk/src/bin/auth/auth_srv.h
trunk/src/bin/auth/benchmarks/Makefile.am
trunk/src/bin/auth/benchmarks/query_bench.cc
trunk/src/bin/auth/main.cc
trunk/src/bin/auth/tests/Makefile.am
trunk/src/bin/auth/tests/auth_srv_unittest.cc
trunk/src/bin/bind10/bind10.py.in (contents, props changed)
trunk/src/bin/bind10/run_bind10.sh.in
trunk/src/bin/bind10/tests/bind10_test.py
trunk/src/bin/stats/tests/isc/util/ (props changed)
trunk/src/lib/Makefile.am
trunk/src/lib/cc/session.cc
trunk/src/lib/dns/buffer.h
trunk/src/lib/dns/message.h
trunk/src/lib/dns/messagerenderer.h
trunk/src/lib/dns/tests/unittest_util.cc
trunk/src/lib/dns/tests/unittest_util.h
Modified: trunk/ChangeLog
==============================================================================
--- trunk/ChangeLog (original)
+++ trunk/ChangeLog Mon Dec 20 23:14:49 2010
@@ -1,3 +1,17 @@
+ 134. [func] vorner
+ b10-recurse supports timeouts and retries in forwarder mode.
+ (Trac #401, svn r3660)
+
+ 133. [func] vorner
+ New temporary logging function available in isc::log. It is used by
+ b10-recurse.
+ (Trac #393, r3602)
+
+ 132. [func] vorner
+ The b10-recursive is configured through config manager.
+ It has "listen_on" and "forward_addresses" options.
+ (Trac #389, r3448)
+
131. [func] feng, jerry
src/lib/datasrc: Introduced two template classes RBTree and RBNode
to provide the generic map with domain name as key and anything as
@@ -25,6 +39,7 @@
for root zone was added.
(Trac #85, svn r3836)
+>>>>>>> .merge-right.r3894
127. [bug] stephen
During normal operation process termination and resurrection messages
are now output regardless of the state of the verbose flag.
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Mon Dec 20 23:14:49 2010
@@ -556,9 +556,9 @@
src/bin/msgq/tests/Makefile
src/bin/auth/Makefile
src/bin/auth/tests/Makefile
- src/bin/auth/tests/testdata/Makefile
src/bin/auth/benchmarks/Makefile
src/bin/recurse/Makefile
+ src/bin/recurse/tests/Makefile
src/bin/xfrin/Makefile
src/bin/xfrin/tests/Makefile
src/bin/xfrout/Makefile
@@ -575,6 +575,8 @@
src/bin/usermgr/Makefile
src/bin/tests/Makefile
src/lib/Makefile
+ src/lib/asiolink/Makefile
+ src/lib/asiolink/tests/Makefile
src/lib/bench/Makefile
src/lib/bench/example/Makefile
src/lib/bench/tests/Makefile
@@ -609,6 +611,9 @@
src/lib/datasrc/Makefile
src/lib/datasrc/tests/Makefile
src/lib/xfr/Makefile
+ src/lib/log/Makefile
+ src/lib/testutils/Makefile
+ src/lib/testutils/testdata/Makefile
src/lib/nsas/Makefile
src/lib/nsas/tests/Makefile
])
@@ -625,9 +630,8 @@
src/bin/xfrout/xfrout.spec.pre
src/bin/xfrout/tests/xfrout_test
src/bin/xfrout/run_b10-xfrout.sh
- src/bin/recurse/recurse.py
src/bin/recurse/recurse.spec.pre
- src/bin/recurse/run_b10-recurse.sh
+ src/bin/recurse/spec_config.h.pre
src/bin/zonemgr/zonemgr.py
src/bin/zonemgr/zonemgr.spec.pre
src/bin/zonemgr/tests/zonemgr_test
Modified: trunk/doc/Doxyfile
==============================================================================
--- trunk/doc/Doxyfile (original)
+++ trunk/doc/Doxyfile Mon Dec 20 23:14:49 2010
@@ -568,7 +568,7 @@
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/lib/bench ../src/lib/nsas
+INPUT = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/lib/bench ../src/lib/log ../src/lib/asiolink/ ../src/lib/nsas
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
Modified: trunk/src/bin/auth/Makefile.am
==============================================================================
--- trunk/src/bin/auth/Makefile.am (original)
+++ trunk/src/bin/auth/Makefile.am Mon Dec 20 23:14:49 2010
@@ -3,8 +3,9 @@
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
-AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
-AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/cc -I$(top_builddir)/src/lib/cc
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/asiolink
+AM_CPPFLAGS += -I$(top_builddir)/src/lib/asiolink
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -33,26 +34,6 @@
spec_config.h: spec_config.h.pre
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
-# This is a wrapper library solely used for b10-auth. The ASIO header files
-# have some code fragments that would hit gcc's unused-parameter warning,
-# which would make the build fail with -Werror (our default setting).
-# We don't want to lower the warning level for our own code just for ASIO,
-# so as a workaround we extract the ASIO related code into a separate library,
-# only for which we accept the unused-parameter warning.
-lib_LIBRARIES = libasio_link.a
-libasio_link_a_SOURCES = asio_link.cc asio_link.h
-# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
-# B10_CXXFLAGS)
-libasio_link_a_CXXFLAGS = $(AM_CXXFLAGS)
-if USE_GXX
-libasio_link_a_CXXFLAGS += -Wno-unused-parameter
-endif
-if USE_CLANGPP
-# Same for clang++, but we need to turn off -Werror completely.
-libasio_link_a_CXXFLAGS += -Wno-error
-endif
-libasio_link_a_CPPFLAGS = $(AM_CPPFLAGS)
-
BUILT_SOURCES = spec_config.h
pkglibexec_PROGRAMS = b10-auth
b10_auth_SOURCES = auth_srv.cc auth_srv.h
@@ -65,7 +46,7 @@
b10_auth_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
b10_auth_LDADD += $(top_builddir)/src/lib/cc/libcc.la
b10_auth_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
-b10_auth_LDADD += libasio_link.a
+b10_auth_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
b10_auth_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
b10_auth_LDADD += $(SQLITE_LIBS)
Modified: trunk/src/bin/auth/auth_srv.cc
==============================================================================
--- trunk/src/bin/auth/auth_srv.cc (original)
+++ trunk/src/bin/auth/auth_srv.cc Mon Dec 20 23:14:49 2010
@@ -14,12 +14,20 @@
// $Id$
+#include <config.h>
+
#include <netinet/in.h>
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
+
+#include <asiolink/asiolink.h>
+
+#include <config/ccsession.h>
+
+#include <cc/data.h>
#include <exceptions/exceptions.h>
@@ -34,22 +42,16 @@
#include <dns/rrset.h>
#include <dns/rrttl.h>
#include <dns/message.h>
-#include <config/ccsession.h>
-#include <cc/data.h>
-#include <exceptions/exceptions.h>
#include <datasrc/query.h>
#include <datasrc/data_source.h>
#include <datasrc/static_datasrc.h>
#include <datasrc/sqlite3_datasrc.h>
-#include <cc/data.h>
-
#include <xfr/xfrout_client.h>
#include <auth/common.h>
#include <auth/auth_srv.h>
-#include <auth/asio_link.h>
using namespace std;
@@ -61,7 +63,7 @@
using namespace isc::data;
using namespace isc::config;
using namespace isc::xfr;
-using namespace asio_link;
+using namespace asiolink;
class AuthSrvImpl {
private:
@@ -73,32 +75,34 @@
~AuthSrvImpl();
isc::data::ConstElementPtr setDbFile(isc::data::ConstElementPtr config);
- bool processNormalQuery(const IOMessage& io_message, Message& message,
- MessageRenderer& response_renderer);
- bool processAxfrQuery(const IOMessage& io_message, Message& message,
- MessageRenderer& response_renderer);
- bool processNotify(const IOMessage& io_message, Message& message,
- MessageRenderer& response_renderer);
+ bool processNormalQuery(const IOMessage& io_message, MessagePtr message,
+ OutputBufferPtr buffer);
+ bool processAxfrQuery(const IOMessage& io_message, MessagePtr message,
+ OutputBufferPtr buffer);
+ bool processNotify(const IOMessage& io_message, MessagePtr message,
+ OutputBufferPtr buffer);
+
+ /// Currently non-configurable, but will be.
+ static const uint16_t DEFAULT_LOCAL_UDPSIZE = 4096;
+
+ /// These members are public because AuthSrv accesses them directly.
+ ModuleCCSession* config_session_;
+ bool verbose_mode_;
+ AbstractSession* xfrin_session_;
+
+ /// Hot spot cache
+ isc::datasrc::HotCache cache_;
+private:
std::string db_file_;
- ModuleCCSession* config_session_;
+
MetaDataSrc data_sources_;
/// We keep a pointer to the currently running sqlite datasource
/// so that we can specifically remove that one should the database
/// file change
ConstDataSrcPtr cur_datasrc_;
- bool verbose_mode_;
-
- AbstractSession* xfrin_session_;
-
bool xfrout_connected_;
AbstractXfroutClient& xfrout_client_;
-
- /// Currently non-configurable, but will be.
- static const uint16_t DEFAULT_LOCAL_UDPSIZE = 4096;
-
- /// Hot spot cache
- isc::datasrc::HotCache cache_;
};
AuthSrvImpl::AuthSrvImpl(const bool use_cache,
@@ -126,60 +130,127 @@
}
}
+// This is a derived class of \c DNSLookup, to serve as a
+// callback in the asiolink module. It calls
+// AuthSrv::processMessage() on a single DNS message.
+class MessageLookup : public DNSLookup {
+public:
+ MessageLookup(AuthSrv* srv) : server_(srv) {}
+ virtual void operator()(const IOMessage& io_message, MessagePtr message,
+ OutputBufferPtr buffer, DNSServer* server) const
+ {
+ server_->processMessage(io_message, message, buffer, server);
+ }
+private:
+ AuthSrv* server_;
+};
+
+// This is a derived class of \c DNSAnswer, to serve as a
+// callback in the asiolink module. It takes a completed
+// set of answer data from the DNS lookup and assembles it
+// into a wire-format response.
+class MessageAnswer : public DNSAnswer {
+public:
+ MessageAnswer(AuthSrv* srv) : server_(srv) {}
+ virtual void operator()(const IOMessage& io_message, MessagePtr message,
+ OutputBufferPtr buffer) const
+ {
+ MessageRenderer renderer(*buffer);
+ if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
+ ConstEDNSPtr edns(message->getEDNS());
+ renderer.setLengthLimit(edns ? edns->getUDPSize() :
+ Message::DEFAULT_MAX_UDPSIZE);
+ } else {
+ renderer.setLengthLimit(65535);
+ }
+ message->toWire(renderer);
+ if (server_->getVerbose()) {
+ cerr << "[b10-auth] sending a response (" << renderer.getLength()
+ << " bytes):\n" << message->toText() << endl;
+ }
+ }
+
+private:
+ AuthSrv* server_;
+};
+
+// This is a derived class of \c SimpleCallback, to serve
+// as a callback in the asiolink module. It checks for queued
+// configuration messages, and executes them if found.
+class ConfigChecker : public SimpleCallback {
+public:
+ ConfigChecker(AuthSrv* srv) : server_(srv) {}
+ virtual void operator()(const IOMessage&) const {
+ if (server_->getConfigSession()->hasQueuedMsgs()) {
+ server_->getConfigSession()->checkCommand();
+ }
+ }
+private:
+ AuthSrv* server_;
+};
+
AuthSrv::AuthSrv(const bool use_cache, AbstractXfroutClient& xfrout_client) :
- impl_(new AuthSrvImpl(use_cache, xfrout_client))
+ impl_(new AuthSrvImpl(use_cache, xfrout_client)),
+ checkin_(new ConfigChecker(this)),
+ dns_lookup_(new MessageLookup(this)),
+ dns_answer_(new MessageAnswer(this))
{}
AuthSrv::~AuthSrv() {
delete impl_;
+ delete checkin_;
+ delete dns_lookup_;
+ delete dns_answer_;
}
namespace {
class QuestionInserter {
public:
- QuestionInserter(Message* message) : message_(message) {}
+ QuestionInserter(MessagePtr message) : message_(message) {}
void operator()(const QuestionPtr question) {
message_->addQuestion(question);
}
- Message* message_;
+ MessagePtr message_;
};
void
-makeErrorMessage(Message& message, MessageRenderer& renderer,
+makeErrorMessage(MessagePtr message, OutputBufferPtr buffer,
const Rcode& rcode, const bool verbose_mode)
{
// extract the parameters that should be kept.
// XXX: with the current implementation, it's not easy to set EDNS0
// depending on whether the query had it. So we'll simply omit it.
- const qid_t qid = message.getQid();
- const bool rd = message.getHeaderFlag(Message::HEADERFLAG_RD);
- const bool cd = message.getHeaderFlag(Message::HEADERFLAG_CD);
- const Opcode& opcode = message.getOpcode();
+ const qid_t qid = message->getQid();
+ const bool rd = message->getHeaderFlag(Message::HEADERFLAG_RD);
+ const bool cd = message->getHeaderFlag(Message::HEADERFLAG_CD);
+ const Opcode& opcode = message->getOpcode();
vector<QuestionPtr> questions;
// If this is an error to a query or notify, we should also copy the
// question section.
if (opcode == Opcode::QUERY() || opcode == Opcode::NOTIFY()) {
- questions.assign(message.beginQuestion(), message.endQuestion());
- }
-
- message.clear(Message::RENDER);
- message.setQid(qid);
- message.setOpcode(opcode);
- message.setHeaderFlag(Message::HEADERFLAG_QR);
+ questions.assign(message->beginQuestion(), message->endQuestion());
+ }
+
+ message->clear(Message::RENDER);
+ message->setQid(qid);
+ message->setOpcode(opcode);
+ message->setHeaderFlag(Message::HEADERFLAG_QR);
if (rd) {
- message.setHeaderFlag(Message::HEADERFLAG_RD);
+ message->setHeaderFlag(Message::HEADERFLAG_RD);
}
if (cd) {
- message.setHeaderFlag(Message::HEADERFLAG_CD);
- }
- for_each(questions.begin(), questions.end(), QuestionInserter(&message));
- message.setRcode(rcode);
- message.toWire(renderer);
+ message->setHeaderFlag(Message::HEADERFLAG_CD);
+ }
+ for_each(questions.begin(), questions.end(), QuestionInserter(message));
+ message->setRcode(rcode);
+
+ MessageRenderer renderer(*buffer);
+ message->toWire(renderer);
if (verbose_mode) {
cerr << "[b10-auth] sending an error response (" <<
- renderer.getLength() << " bytes):\n" << message.toText() << endl;
+ renderer.getLength() << " bytes):\n" << message->toText() << endl;
}
}
}
@@ -219,143 +290,147 @@
return (impl_->config_session_);
}
-bool
-AuthSrv::processMessage(const IOMessage& io_message, Message& message,
- MessageRenderer& response_renderer)
+void
+AuthSrv::processMessage(const IOMessage& io_message, MessagePtr message,
+ OutputBufferPtr buffer, DNSServer* server)
{
InputBuffer request_buffer(io_message.getData(), io_message.getDataSize());
// First, check the header part. If we fail even for the base header,
// just drop the message.
try {
- message.parseHeader(request_buffer);
+ message->parseHeader(request_buffer);
// Ignore all responses.
- if (message.getHeaderFlag(Message::HEADERFLAG_QR)) {
+ if (message->getHeaderFlag(Message::HEADERFLAG_QR)) {
if (impl_->verbose_mode_) {
cerr << "[b10-auth] received unexpected response, ignoring"
<< endl;
}
- return (false);
+ server->resume(false);
+ return;
}
} catch (const Exception& ex) {
- return (false);
- }
-
- // Parse the message. On failure, return an appropriate error.
+ if (impl_->verbose_mode_) {
+ cerr << "[b10-auth] DNS packet exception: " << ex.what() << endl;
+ }
+ server->resume(false);
+ return;
+ }
+
try {
- message.fromWire(request_buffer);
+ // Parse the message.
+ message->fromWire(request_buffer);
} catch (const DNSProtocolError& error) {
if (impl_->verbose_mode_) {
cerr << "[b10-auth] returning " << error.getRcode().toText()
<< ": " << error.what() << endl;
}
- makeErrorMessage(message, response_renderer, error.getRcode(),
+ makeErrorMessage(message, buffer, error.getRcode(),
impl_->verbose_mode_);
- return (true);
+ server->resume(true);
+ return;
} catch (const Exception& ex) {
if (impl_->verbose_mode_) {
cerr << "[b10-auth] returning SERVFAIL: " << ex.what() << endl;
}
- makeErrorMessage(message, response_renderer, Rcode::SERVFAIL(),
+ makeErrorMessage(message, buffer, Rcode::SERVFAIL(),
impl_->verbose_mode_);
- return (true);
+ server->resume(true);
+ return;
} // other exceptions will be handled at a higher layer.
if (impl_->verbose_mode_) {
- cerr << "[b10-auth] received a message:\n" << message.toText() << endl;
+ cerr << "[b10-auth] received a message:\n" << message->toText() << endl;
}
// Perform further protocol-level validation.
- if (message.getOpcode() == Opcode::NOTIFY()) {
- return (impl_->processNotify(io_message, message, response_renderer));
- } else if (message.getOpcode() != Opcode::QUERY()) {
+ bool sendAnswer = true;
+ if (message->getOpcode() == Opcode::NOTIFY()) {
+ sendAnswer = impl_->processNotify(io_message, message, buffer);
+ } else if (message->getOpcode() != Opcode::QUERY()) {
if (impl_->verbose_mode_) {
cerr << "[b10-auth] unsupported opcode" << endl;
}
- makeErrorMessage(message, response_renderer, Rcode::NOTIMP(),
+ makeErrorMessage(message, buffer, Rcode::NOTIMP(),
impl_->verbose_mode_);
- return (true);
- }
-
- if (message.getRRCount(Message::SECTION_QUESTION) != 1) {
- makeErrorMessage(message, response_renderer, Rcode::FORMERR(),
+ } else if (message->getRRCount(Message::SECTION_QUESTION) != 1) {
+ makeErrorMessage(message, buffer, Rcode::FORMERR(),
impl_->verbose_mode_);
- return (true);
- }
-
- ConstQuestionPtr question = *message.beginQuestion();
- const RRType &qtype = question->getType();
- if (qtype == RRType::AXFR()) {
- return (impl_->processAxfrQuery(io_message, message,
- response_renderer));
- } else if (qtype == RRType::IXFR()) {
- makeErrorMessage(message, response_renderer, Rcode::NOTIMP(),
- impl_->verbose_mode_);
- return (true);
} else {
- return (impl_->processNormalQuery(io_message, message,
- response_renderer));
- }
+ ConstQuestionPtr question = *message->beginQuestion();
+ const RRType &qtype = question->getType();
+ if (qtype == RRType::AXFR()) {
+ sendAnswer = impl_->processAxfrQuery(io_message, message, buffer);
+ } else if (qtype == RRType::IXFR()) {
+ makeErrorMessage(message, buffer, Rcode::NOTIMP(),
+ impl_->verbose_mode_);
+ } else {
+ sendAnswer = impl_->processNormalQuery(io_message, message, buffer);
+ }
+ }
+
+ server->resume(sendAnswer);
}
bool
-AuthSrvImpl::processNormalQuery(const IOMessage& io_message, Message& message,
- MessageRenderer& response_renderer)
+AuthSrvImpl::processNormalQuery(const IOMessage& io_message, MessagePtr message,
+ OutputBufferPtr buffer)
{
- ConstEDNSPtr remote_edns = message.getEDNS();
+ ConstEDNSPtr remote_edns = message->getEDNS();
const bool dnssec_ok = remote_edns && remote_edns->getDNSSECAwareness();
const uint16_t remote_bufsize = remote_edns ? remote_edns->getUDPSize() :
Message::DEFAULT_MAX_UDPSIZE;
- message.makeResponse();
- message.setHeaderFlag(Message::HEADERFLAG_AA);
- message.setRcode(Rcode::NOERROR());
+ message->makeResponse();
+ message->setHeaderFlag(Message::HEADERFLAG_AA);
+ message->setRcode(Rcode::NOERROR());
if (remote_edns) {
EDNSPtr local_edns = EDNSPtr(new EDNS());
local_edns->setDNSSECAwareness(dnssec_ok);
local_edns->setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
- message.setEDNS(local_edns);
+ message->setEDNS(local_edns);
}
try {
- Query query(message, cache_, dnssec_ok);
+ Query query(*message, cache_, dnssec_ok);
data_sources_.doQuery(query);
} catch (const Exception& ex) {
if (verbose_mode_) {
cerr << "[b10-auth] Internal error, returning SERVFAIL: " <<
ex.what() << endl;
}
- makeErrorMessage(message, response_renderer, Rcode::SERVFAIL(),
- verbose_mode_);
+ makeErrorMessage(message, buffer, Rcode::SERVFAIL(), verbose_mode_);
return (true);
}
+
+ MessageRenderer renderer(*buffer);
const bool udp_buffer =
(io_message.getSocket().getProtocol() == IPPROTO_UDP);
- response_renderer.setLengthLimit(udp_buffer ? remote_bufsize : 65535);
- message.toWire(response_renderer);
+ renderer.setLengthLimit(udp_buffer ? remote_bufsize : 65535);
+ message->toWire(renderer);
+
if (verbose_mode_) {
cerr << "[b10-auth] sending a response ("
- << response_renderer.getLength()
- << " bytes):\n" << message.toText() << endl;
+ << renderer.getLength()
+ << " bytes):\n" << message->toText() << endl;
}
return (true);
}
bool
-AuthSrvImpl::processAxfrQuery(const IOMessage& io_message, Message& message,
- MessageRenderer& response_renderer)
+AuthSrvImpl::processAxfrQuery(const IOMessage& io_message, MessagePtr message,
+ OutputBufferPtr buffer)
{
if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
if (verbose_mode_) {
cerr << "[b10-auth] AXFR query over UDP isn't allowed" << endl;
}
- makeErrorMessage(message, response_renderer, Rcode::FORMERR(),
- verbose_mode_);
+ makeErrorMessage(message, buffer, Rcode::FORMERR(), verbose_mode_);
return (true);
}
@@ -382,8 +457,7 @@
cerr << "[b10-auth] Error in handling XFR request: " << err.what()
<< endl;
}
- makeErrorMessage(message, response_renderer, Rcode::SERVFAIL(),
- verbose_mode_);
+ makeErrorMessage(message, buffer, Rcode::SERVFAIL(), verbose_mode_);
return (true);
}
@@ -391,28 +465,26 @@
}
bool
-AuthSrvImpl::processNotify(const IOMessage& io_message, Message& message,
- MessageRenderer& response_renderer)
+AuthSrvImpl::processNotify(const IOMessage& io_message, MessagePtr message,
+ OutputBufferPtr buffer)
{
// The incoming notify must contain exactly one question for SOA of the
// zone name.
- if (message.getRRCount(Message::SECTION_QUESTION) != 1) {
+ if (message->getRRCount(Message::SECTION_QUESTION) != 1) {
if (verbose_mode_) {
cerr << "[b10-auth] invalid number of questions in notify: "
- << message.getRRCount(Message::SECTION_QUESTION) << endl;
- }
- makeErrorMessage(message, response_renderer, Rcode::FORMERR(),
- verbose_mode_);
+ << message->getRRCount(Message::SECTION_QUESTION) << endl;
+ }
+ makeErrorMessage(message, buffer, Rcode::FORMERR(), verbose_mode_);
return (true);
}
- ConstQuestionPtr question = *message.beginQuestion();
+ ConstQuestionPtr question = *message->beginQuestion();
if (question->getType() != RRType::SOA()) {
if (verbose_mode_) {
cerr << "[b10-auth] invalid question RR type in notify: "
<< question->getType() << endl;
}
- makeErrorMessage(message, response_renderer, Rcode::FORMERR(),
- verbose_mode_);
+ makeErrorMessage(message, buffer, Rcode::FORMERR(), verbose_mode_);
return (true);
}
@@ -470,10 +542,12 @@
return (false);
}
- message.makeResponse();
- message.setHeaderFlag(Message::HEADERFLAG_AA);
- message.setRcode(Rcode::NOERROR());
- message.toWire(response_renderer);
+ message->makeResponse();
+ message->setHeaderFlag(Message::HEADERFLAG_AA);
+ message->setRcode(Rcode::NOERROR());
+
+ MessageRenderer renderer(*buffer);
+ message->toWire(renderer);
return (true);
}
Modified: trunk/src/bin/auth/auth_srv.h
==============================================================================
--- trunk/src/bin/auth/auth_srv.h (original)
+++ trunk/src/bin/auth/auth_srv.h Mon Dec 20 23:14:49 2010
@@ -22,20 +22,12 @@
#include <cc/data.h>
#include <config/ccsession.h>
+#include <asiolink/asiolink.h>
+
namespace isc {
-namespace dns {
-class InputBuffer;
-class Message;
-class MessageRenderer;
-}
-
namespace xfr {
class AbstractXfroutClient;
-};
}
-
-namespace asio_link {
-class IOMessage;
}
/// \brief The implementation class for the \c AuthSrv class using the pimpl
@@ -84,11 +76,26 @@
isc::xfr::AbstractXfroutClient& xfrout_client);
~AuthSrv();
//@}
- /// \return \c true if the \a message contains a response to be returned;
- /// otherwise \c false.
- bool processMessage(const asio_link::IOMessage& io_message,
- isc::dns::Message& message,
- isc::dns::MessageRenderer& response_renderer);
+
+ /// \brief Process an incoming DNS message, then signal 'server' to resume
+ ///
+ /// A DNS query (or other message) has been received by a \c DNSServer
+ /// object. Find an answer, then post the \c DNSServer object on the
+ /// I/O service queue and return. When the server resumes, it can
+ /// send the reply.
+ ///
+ /// \param io_message The raw message received
+ /// \param message Pointer to the \c Message object
+ /// \param buffer Pointer to an \c OutputBuffer for the resposne
+ /// \param server Pointer to the \c DNSServer
+ void processMessage(const asiolink::IOMessage& io_message,
+ isc::dns::MessagePtr message,
+ isc::dns::OutputBufferPtr buffer,
+ asiolink::DNSServer* server);
+
+ /// \brief Set verbose flag
+ ///
+ /// \param on The new value of the verbose flag
/// \brief Enable or disable verbose logging.
///
@@ -103,6 +110,8 @@
/// This method never throws an exception.
///
/// \return \c true if verbose logging is enabled; otherwise \c false.
+
+ /// \brief Get the current value of the verbose flag
bool getVerbose() const;
/// \brief Updates the data source for the \c AuthSrv object.
@@ -161,6 +170,21 @@
/// \param config_session A pointer to \c ModuleCCSession object to receive
/// control commands and configuration updates.
void setConfigSession(isc::config::ModuleCCSession* config_session);
+
+ /// \brief Assign an ASIO IO Service queue to this Recursor object
+ void setIOService(asiolink::IOService& ios) { io_service_ = &ios; }
+
+ /// \brief Return this object's ASIO IO Service queue
+ asiolink::IOService& getIOService() const { return (*io_service_); }
+
+ /// \brief Return pointer to the DNS Lookup callback function
+ asiolink::DNSLookup* getDNSLookupProvider() const { return (dns_lookup_); }
+
+ /// \brief Return pointer to the DNS Answer callback function
+ asiolink::DNSAnswer* getDNSAnswerProvider() const { return (dns_answer_); }
+
+ /// \brief Return pointer to the Checkin callback function
+ asiolink::SimpleCallback* getCheckinProvider() const { return (checkin_); }
/// \brief Set or update the size (number of slots) of hot spot cache.
///
@@ -202,6 +226,10 @@
private:
AuthSrvImpl* impl_;
+ asiolink::IOService* io_service_;
+ asiolink::SimpleCallback* checkin_;
+ asiolink::DNSLookup* dns_lookup_;
+ asiolink::DNSAnswer* dns_answer_;
};
#endif // __AUTH_SRV_H
Modified: trunk/src/bin/auth/benchmarks/Makefile.am
==============================================================================
--- trunk/src/bin/auth/benchmarks/Makefile.am (original)
+++ trunk/src/bin/auth/benchmarks/Makefile.am Mon Dec 20 23:14:49 2010
@@ -17,5 +17,5 @@
query_bench_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
query_bench_LDADD += $(top_builddir)/src/lib/cc/libcc.la
query_bench_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
-query_bench_LDADD += $(top_builddir)/src/bin/auth/libasio_link.a
+query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
query_bench_LDADD += $(SQLITE_LIBS)
Modified: trunk/src/bin/auth/benchmarks/query_bench.cc
==============================================================================
--- trunk/src/bin/auth/benchmarks/query_bench.cc (original)
+++ trunk/src/bin/auth/benchmarks/query_bench.cc Mon Dec 20 23:14:49 2010
@@ -26,7 +26,6 @@
#include <dns/buffer.h>
#include <dns/message.h>
-#include <dns/messagerenderer.h>
#include <dns/name.h>
#include <dns/question.h>
#include <dns/rrclass.h>
@@ -34,7 +33,7 @@
#include <xfr/xfrout_client.h>
#include <auth/auth_srv.h>
-#include <auth/asio_link.h>
+#include <asiolink/asiolink.h>
using namespace std;
using namespace isc;
@@ -42,11 +41,21 @@
using namespace isc::dns;
using namespace isc::xfr;
using namespace isc::bench;
-using namespace asio_link;
+using namespace asiolink;
namespace {
// Commonly used constant:
XfroutClient xfrout_client("dummy_path"); // path doesn't matter
+
+// Just something to pass as the server to resume
+class DummyServer : public DNSServer {
+ public:
+ virtual void operator()(asio::error_code, size_t) { }
+ virtual void resume(const bool) { }
+ virtual DNSServer* clone() {
+ return new DummyServer(*this);
+ }
+};
class QueryBenchMark {
private:
@@ -56,12 +65,12 @@
typedef boost::shared_ptr<const IOEndpoint> IOEndpointPtr;
public:
QueryBenchMark(const int cache_slots, const char* const datasrc_file,
- const BenchQueries& queries, Message& query_message,
- MessageRenderer& renderer) :
+ const BenchQueries& queries, MessagePtr query_message,
+ OutputBufferPtr buffer) :
server_(new AuthSrv(cache_slots >= 0 ? true : false, xfrout_client)),
queries_(queries),
query_message_(query_message),
- renderer_(renderer),
+ buffer_(buffer),
dummy_socket(IOSocket::getDummyUDPSocket()),
dummy_endpoint(IOEndpointPtr(IOEndpoint::create(IPPROTO_UDP,
IOAddress("192.0.2.1"),
@@ -76,12 +85,13 @@
unsigned int run() {
BenchQueries::const_iterator query;
const BenchQueries::const_iterator query_end = queries_.end();
+ DummyServer server;
for (query = queries_.begin(); query != query_end; ++query) {
IOMessage io_message(&(*query)[0], (*query).size(), dummy_socket,
*dummy_endpoint);
- query_message_.clear(Message::PARSE);
- renderer_.clear();
- server_->processMessage(io_message, query_message_, renderer_);
+ query_message_->clear(Message::PARSE);
+ server_->processMessage(io_message, query_message_, buffer_,
+ &server);
}
return (queries_.size());
@@ -89,11 +99,12 @@
private:
AuthSrvPtr server_;
const BenchQueries& queries_;
- Message& query_message_;
- MessageRenderer& renderer_;
+ MessagePtr query_message_;
+ OutputBufferPtr buffer_;
IOSocket& dummy_socket;
IOEndpointPtr dummy_endpoint;
};
+
}
namespace isc {
@@ -143,9 +154,8 @@
BenchQueries queries;
loadQueryData(query_data_file, queries, RRClass::IN());
- OutputBuffer buffer(4096);
- MessageRenderer renderer(buffer);
- Message message(Message::PARSE);
+ OutputBufferPtr buffer(new OutputBuffer(4096));
+ MessagePtr message(new Message(Message::PARSE));
cout << "Parameters:" << endl;
cout << " Iterations: " << iteration << endl;
@@ -157,24 +167,24 @@
<< endl;
BenchMark<QueryBenchMark>(iteration,
QueryBenchMark(0, datasrc_file, queries, message,
- renderer));
+ buffer));
cout << "Benchmark enabling Hot Spot Cache with 10*#queries slots "
<< endl;
BenchMark<QueryBenchMark>(iteration,
QueryBenchMark(10 * queries.size(), datasrc_file,
- queries, message, renderer));
+ queries, message, buffer));
cout << "Benchmark enabling Hot Spot Cache with #queries/2 slots "
<< endl;
BenchMark<QueryBenchMark>(iteration,
QueryBenchMark(queries.size() / 2, datasrc_file,
- queries, message, renderer));
+ queries, message, buffer));
cout << "Benchmark disabling Hot Spot Cache" << endl;
BenchMark<QueryBenchMark>(iteration,
QueryBenchMark(-1, datasrc_file, queries,
- message, renderer));
+ message, buffer));
return (0);
}
Modified: trunk/src/bin/auth/main.cc
==============================================================================
--- trunk/src/bin/auth/main.cc (original)
+++ trunk/src/bin/auth/main.cc Mon Dec 20 23:14:49 2010
@@ -43,7 +43,7 @@
#include <auth/common.h>
#include <auth/change_user.h>
#include <auth/auth_srv.h>
-#include <auth/asio_link.h>
+#include <asiolink/asiolink.h>
using namespace std;
using namespace isc::data;
@@ -51,20 +51,22 @@
using namespace isc::config;
using namespace isc::dns;
using namespace isc::xfr;
+using namespace asiolink;
namespace {
-bool verbose_mode = false;
-
-const string PROGRAM = "Auth";
-const char* DNSPORT = "5300";
+static bool verbose_mode = false;
+
+// Default port current 5300 for testing purposes
+static const string PROGRAM = "Auth";
+static const char* DNSPORT = "5300";
/* need global var for config/command handlers.
* todo: turn this around, and put handlers in the authserver
* class itself? */
-AuthSrv *auth_server;
-
-asio_link::IOService* io_service;
+static AuthSrv *auth_server;
+
+static IOService io_service;
ConstElementPtr
my_config_handler(ConstElementPtr new_config) {
@@ -80,7 +82,7 @@
/* let's add that message to our answer as well */
answer = createAnswer(0, args);
} else if (command == "shutdown") {
- io_service->stop();
+ io_service.stop();
}
return (answer);
@@ -88,7 +90,16 @@
void
usage() {
- cerr << "Usage: b10-auth [-a address] [-p port] [-4|-6] [-nv]" << endl;
+ cerr << "Usage: b10-auth [-a address] [-p port] [-u user] [-4|-6] [-nv]"
+ << endl;
+ cerr << "\t-a: specify the address to listen on (default: all) " << endl;
+ cerr << "\t-p: specify the port to listen on (default: " << DNSPORT << ")"
+ << endl;
+ cerr << "\t-4: listen on all IPv4 addresses (incompatible with -a)" << endl;
+ cerr << "\t-6: listen on all IPv6 addresses (incompatible with -a)" << endl;
+ cerr << "\t-n: do not cache answers in memory" << endl;
+ cerr << "\t-u: change process UID to the specified user" << endl;
+ cerr << "\t-v: verbose output" << endl;
exit(1);
}
} // end of anonymous namespace
@@ -140,12 +151,14 @@
}
if (!use_ipv4 && !use_ipv6) {
- cerr << "[b10-auth] Error: -4 and -6 can't coexist" << endl;
+ cerr << "[b10-auth] Error: Cannot specify both -4 and -6 "
+ << "at the same time" << endl;
usage();
}
if ((!use_ipv4 || !use_ipv6) && address != NULL) {
- cerr << "[b10-auth] Error: -4|-6 and -a can't coexist" << endl;
+ cerr << "[b10-auth] Error: Cannot specify -4 or -6 "
+ << "at the same time as -a" << endl;
usage();
}
@@ -176,6 +189,11 @@
auth_server->setVerbose(verbose_mode);
cout << "[b10-auth] Server created." << endl;
+ SimpleCallback* checkin = auth_server->getCheckinProvider();
+ DNSLookup* lookup = auth_server->getDNSLookupProvider();
+ DNSAnswer* answer = auth_server->getDNSAnswerProvider();
+
+ DNSService* dns_service;
if (address != NULL) {
// XXX: we can only specify at most one explicit address.
// This also means the server cannot run in the dual address
@@ -183,15 +201,17 @@
// We don't bother to fix this problem, however. The -a option
// is a short term workaround until we support dynamic listening
// port allocation.
- io_service = new asio_link::IOService(auth_server, *port,
- *address);
+ dns_service = new DNSService(io_service, *port, *address,
+ checkin, lookup, answer);
} else {
- io_service = new asio_link::IOService(auth_server, *port,
- use_ipv4, use_ipv6);
- }
+ dns_service = new DNSService(io_service, *port, use_ipv4,
+ use_ipv6, checkin, lookup,
+ answer);
+ }
+ auth_server->setIOService(io_service);
cout << "[b10-auth] IOService created." << endl;
- cc_session = new Session(io_service->get_io_service());
+ cc_session = new Session(io_service.get_io_service());
cout << "[b10-auth] Configuration session channel created." << endl;
config_session = new ModuleCCSession(specfile, *cc_session,
@@ -203,15 +223,15 @@
changeUser(uid);
}
- xfrin_session = new Session(io_service->get_io_service());
+ xfrin_session = new Session(io_service.get_io_service());
cout << "[b10-auth] Xfrin session channel created." << endl;
xfrin_session->establish(NULL);
xfrin_session_established = true;
cout << "[b10-auth] Xfrin session channel established." << endl;
- // XXX: with the current interface to asio_link we have to create
+ // XXX: with the current interface to asiolink we have to create
// auth_server before io_service while Session needs io_service.
- // In a next step of refactoring we should make asio_link independent
+ // In a next step of refactoring we should make asiolink independent
// from auth_server, and create io_service, auth_server, and
// sessions in that order.
auth_server->setXfrinSession(xfrin_session);
@@ -219,9 +239,11 @@
auth_server->updateConfig(ElementPtr());
cout << "[b10-auth] Server started." << endl;
- io_service->run();
+ io_service.run();
+
+ delete dns_service;
} catch (const std::exception& ex) {
- cerr << "[b10-auth] Initialization failed: " << ex.what() << endl;
+ cerr << "[b10-auth] Server failed: " << ex.what() << endl;
ret = 1;
}
@@ -232,7 +254,6 @@
delete xfrin_session;
delete config_session;
delete cc_session;
- delete io_service;
delete auth_server;
return (ret);
Modified: trunk/src/bin/auth/tests/Makefile.am
==============================================================================
--- trunk/src/bin/auth/tests/Makefile.am (original)
+++ trunk/src/bin/auth/tests/Makefile.am Mon Dec 20 23:14:49 2010
@@ -1,11 +1,9 @@
-SUBDIRS = testdata .
-
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/bin
AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
AM_CPPFLAGS += $(BOOST_INCLUDES)
-AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
-AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/bin/auth/tests/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(top_srcdir)/src/lib/testutils/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/lib/testutils/testdata\"
AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -26,7 +24,6 @@
run_unittests_SOURCES += auth_srv_unittest.cc
run_unittests_SOURCES += query_unittest.cc
run_unittests_SOURCES += change_user_unittest.cc
-run_unittests_SOURCES += asio_link_unittest.cc
run_unittests_SOURCES += run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
@@ -34,10 +31,10 @@
run_unittests_LDADD += $(SQLITE_LIBS)
run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la
run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.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/cc/libcc.la
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
-run_unittests_LDADD += $(top_builddir)/src/bin/auth/libasio_link.a
run_unittests_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
endif
Modified: trunk/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- trunk/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ trunk/src/bin/auth/tests/auth_srv_unittest.cc Mon Dec 20 23:14:49 2010
@@ -15,35 +15,16 @@
// $Id$
#include <config.h>
-
-#include <gtest/gtest.h>
-
-#include <dns/buffer.h>
-#include <dns/name.h>
-#include <dns/message.h>
-#include <dns/messagerenderer.h>
-#include <dns/opcode.h>
-#include <dns/rcode.h>
-#include <dns/rrclass.h>
-#include <dns/rrtype.h>
-
-#include <cc/data.h>
-#include <cc/session.h>
-
-#include <xfr/xfrout_client.h>
-
#include <auth/auth_srv.h>
-#include <auth/asio_link.h>
-
-#include <dns/tests/unittest_util.h>
-
-using isc::UnitTestUtil;
+#include <testutils/srv_unittest.h>
+
using namespace std;
using namespace isc::cc;
using namespace isc::dns;
using namespace isc::data;
using namespace isc::xfr;
-using namespace asio_link;
+using namespace asiolink;
+using isc::UnitTestUtil;
namespace {
const char* const CONFIG_TESTDB =
@@ -52,445 +33,83 @@
// the sqlite3 test).
const char* const BADCONFIG_TESTDB =
"{ \"database_file\": \"" TEST_DATA_DIR "/nodir/notexist\"}";
-const char* const DEFAULT_REMOTE_ADDRESS = "192.0.2.1";
-
-class AuthSrvTest : public ::testing::Test {
-private:
- class MockXfroutClient : public AbstractXfroutClient {
- public:
- MockXfroutClient() :
- is_connected_(false), connect_ok_(true), send_ok_(true),
- disconnect_ok_(true)
- {}
- virtual void connect();
- virtual void disconnect();
- virtual int sendXfroutRequestInfo(int tcp_sock, const void* msg_data,
- uint16_t msg_len);
- bool isConnected() const { return (is_connected_); }
- void disableConnect() { connect_ok_ = false; }
- void disableDisconnect() { disconnect_ok_ = false; }
- void enableDisconnect() { disconnect_ok_ = true; }
- void disableSend() { send_ok_ = false; }
- private:
- bool is_connected_;
- bool connect_ok_;
- bool send_ok_;
- bool disconnect_ok_;
- };
-
- class MockSession : public AbstractSession {
- public:
- MockSession() :
- // by default we return a simple "success" message.
- msg_(Element::fromJSON("{\"result\": [0, \"SUCCESS\"]}")),
- send_ok_(true), receive_ok_(true)
- {}
- virtual void establish(const char* socket_file);
- virtual void disconnect();
- virtual int group_sendmsg(ConstElementPtr msg, string group,
- string instance, string to);
- virtual bool group_recvmsg(ConstElementPtr& envelope,
- ConstElementPtr& msg,
- bool nonblock, int seq);
- virtual void subscribe(string group, string instance);
- virtual void unsubscribe(string group, string instance);
- virtual void startRead(boost::function<void()> read_callback);
- virtual int reply(ConstElementPtr envelope, ConstElementPtr newmsg);
- virtual bool hasQueuedMsgs() const;
- virtual void setTimeout(size_t) {}
- virtual size_t getTimeout() const { return 0; };
-
- void setMessage(ConstElementPtr msg) { msg_ = msg; }
- void disableSend() { send_ok_ = false; }
- void disableReceive() { receive_ok_ = false; }
-
- ConstElementPtr sent_msg;
- string msg_destination;
- private:
- ConstElementPtr msg_;
- bool send_ok_;
- bool receive_ok_;
- };
-
+
+class AuthSrvTest : public SrvTestBase {
protected:
- AuthSrvTest() : server(true, xfrout),
- request_message(Message::RENDER),
- parse_message(Message::PARSE), default_qid(0x1035),
- opcode(Opcode::QUERY()), qname("www.example.com"),
- qclass(RRClass::IN()), qtype(RRType::A()),
- io_message(NULL), endpoint(NULL), request_obuffer(0),
- request_renderer(request_obuffer),
- response_obuffer(0), response_renderer(response_obuffer)
- {
+ AuthSrvTest() : server(true, xfrout) {
server.setXfrinSession(¬ify_session);
}
- ~AuthSrvTest() {
- delete io_message;
- delete endpoint;
- }
- MockSession notify_session;
MockXfroutClient xfrout;
AuthSrv server;
- Message request_message;
- Message parse_message;
- const qid_t default_qid;
- const Opcode opcode;
- const Name qname;
- const RRClass qclass;
- const RRType qtype;
- IOMessage* io_message;
- const IOEndpoint* endpoint;
- OutputBuffer request_obuffer;
- MessageRenderer request_renderer;
- OutputBuffer response_obuffer;
- MessageRenderer response_renderer;
- vector<uint8_t> data;
-
- void createDataFromFile(const char* const datafile, int protocol);
- void createRequestMessage(const Opcode& opcode, const Name& request_name,
- const RRClass& rrclass, const RRType& rrtype);
- void createRequestPacket(const Opcode& opcode, const Name& request_name,
- const RRClass& rrclass, const RRType& rrtype,
- int protocol);
- void createRequestPacket(int protocol);
};
-
-void
-AuthSrvTest::MockSession::establish(const char*) {}
-
-void
-AuthSrvTest::MockSession::disconnect() {}
-
-void
-AuthSrvTest::MockSession::subscribe(string, string)
-{}
-
-void
-AuthSrvTest::MockSession::unsubscribe(string, string)
-{}
-
-void
-AuthSrvTest::MockSession::startRead(boost::function<void()>)
-{}
-
-int
-AuthSrvTest::MockSession::reply(ConstElementPtr, ConstElementPtr) {
- return (-1);
-}
-
-bool
-AuthSrvTest::MockSession::hasQueuedMsgs() const {
- return (false);
-}
-
-int
-AuthSrvTest::MockSession::group_sendmsg(ConstElementPtr msg, string group,
- string, string)
-{
- if (!send_ok_) {
- isc_throw(XfroutError, "mock session send is disabled for test");
- }
-
- sent_msg = msg;
- msg_destination = group;
- return (0);
-}
-
-bool
-AuthSrvTest::MockSession::group_recvmsg(ConstElementPtr&,
- ConstElementPtr& msg, bool, int)
-{
- if (!receive_ok_) {
- isc_throw(XfroutError, "mock session receive is disabled for test");
- }
-
- msg = msg_;
- return (true);
-}
-
-void
-AuthSrvTest::MockXfroutClient::connect() {
- if (!connect_ok_) {
- isc_throw(XfroutError, "xfrout connection disabled for test");
- }
- is_connected_ = true;
-}
-
-void
-AuthSrvTest::MockXfroutClient::disconnect() {
- if (!disconnect_ok_) {
- isc_throw(XfroutError,
- "closing xfrout connection is disabled for test");
- }
- is_connected_ = false;
-}
-
-int
-AuthSrvTest::MockXfroutClient::sendXfroutRequestInfo(const int,
- const void*,
- const uint16_t)
-{
- if (!send_ok_) {
- isc_throw(XfroutError, "xfrout connection send is disabled for test");
- }
- return (0);
-}
-
-
-// These are flags to indicate whether the corresponding flag bit of the
-// DNS header is to be set in the test cases. (Note that the flag values
-// is irrelevant to their wire-format values)
-const unsigned int QR_FLAG = 0x1;
-const unsigned int AA_FLAG = 0x2;
-const unsigned int TC_FLAG = 0x4;
-const unsigned int RD_FLAG = 0x8;
-const unsigned int RA_FLAG = 0x10;
-const unsigned int AD_FLAG = 0x20;
-const unsigned int CD_FLAG = 0x40;
-
-void
-AuthSrvTest::createDataFromFile(const char* const datafile,
- const int protocol = IPPROTO_UDP)
-{
- delete io_message;
- data.clear();
-
- delete endpoint;
- endpoint = IOEndpoint::create(protocol,
- IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
- UnitTestUtil::readWireData(datafile, data);
- io_message = new IOMessage(&data[0], data.size(),
- protocol == IPPROTO_UDP ?
- IOSocket::getDummyUDPSocket() :
- IOSocket::getDummyTCPSocket(), *endpoint);
-}
-
-void
-AuthSrvTest::createRequestMessage(const Opcode& opcode,
- const Name& request_name,
- const RRClass& rrclass,
- const RRType& rrtype)
-{
- request_message.clear(Message::RENDER);
- request_message.setOpcode(opcode);
- request_message.setRcode(Rcode::NOERROR());
- request_message.setQid(default_qid);
- request_message.addQuestion(Question(request_name, rrclass, rrtype));
-}
-
-void
-AuthSrvTest::createRequestPacket(const Opcode& opcode,
- const Name& request_name,
- const RRClass& rrclass, const RRType& rrtype,
- const int protocol = IPPROTO_UDP)
-{
- createRequestMessage(opcode, request_name, rrclass, rrtype);
- createRequestPacket(protocol);
-}
-
-void
-AuthSrvTest::createRequestPacket(const int protocol = IPPROTO_UDP) {
- request_message.toWire(request_renderer);
-
- delete io_message;
- endpoint = IOEndpoint::create(protocol,
- IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
- io_message = new IOMessage(request_renderer.getData(),
- request_renderer.getLength(),
- protocol == IPPROTO_UDP ?
- IOSocket::getDummyUDPSocket() :
- IOSocket::getDummyTCPSocket(), *endpoint);
-}
-
-void
-headerCheck(const Message& message, const qid_t qid, const Rcode& rcode,
- const uint16_t opcodeval, const unsigned int flags,
- const unsigned int qdcount,
- const unsigned int ancount, const unsigned int nscount,
- const unsigned int arcount)
-{
- EXPECT_EQ(qid, message.getQid());
- EXPECT_EQ(rcode, message.getRcode());
- EXPECT_EQ(opcodeval, message.getOpcode().getCode());
- EXPECT_EQ((flags & QR_FLAG) != 0,
- message.getHeaderFlag(Message::HEADERFLAG_QR));
- EXPECT_EQ((flags & AA_FLAG) != 0,
- message.getHeaderFlag(Message::HEADERFLAG_AA));
- EXPECT_EQ((flags & TC_FLAG) != 0,
- message.getHeaderFlag(Message::HEADERFLAG_TC));
- EXPECT_EQ((flags & RA_FLAG) != 0,
- message.getHeaderFlag(Message::HEADERFLAG_RA));
- EXPECT_EQ((flags & RD_FLAG) != 0,
- message.getHeaderFlag(Message::HEADERFLAG_RD));
- EXPECT_EQ((flags & AD_FLAG) != 0,
- message.getHeaderFlag(Message::HEADERFLAG_AD));
- EXPECT_EQ((flags & CD_FLAG) != 0,
- message.getHeaderFlag(Message::HEADERFLAG_CD));
-
- EXPECT_EQ(qdcount, message.getRRCount(Message::SECTION_QUESTION));
- EXPECT_EQ(ancount, message.getRRCount(Message::SECTION_ANSWER));
- EXPECT_EQ(nscount, message.getRRCount(Message::SECTION_AUTHORITY));
- EXPECT_EQ(arcount, message.getRRCount(Message::SECTION_ADDITIONAL));
-}
// Unsupported requests. Should result in NOTIMP.
TEST_F(AuthSrvTest, unsupportedRequest) {
- for (unsigned int i = 0; i < 16; ++i) {
- // set Opcode to 'i', which iterators over all possible codes except
- // the standard query and notify
- if (i == Opcode::QUERY().getCode() ||
- i == Opcode::NOTIFY().getCode()) {
- continue;
- }
- createDataFromFile("simplequery_fromWire.wire");
- data[2] = ((i << 3) & 0xff);
-
- parse_message.clear(Message::PARSE);
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::NOTIMP(), i, QR_FLAG,
- 0, 0, 0, 0);
- }
+ UNSUPPORTED_REQUEST_TEST;
}
// Simple API check
TEST_F(AuthSrvTest, verbose) {
- EXPECT_FALSE(server.getVerbose());
- server.setVerbose(true);
- EXPECT_TRUE(server.getVerbose());
- server.setVerbose(false);
- EXPECT_FALSE(server.getVerbose());
+ VERBOSE_TEST;
}
// Multiple questions. Should result in FORMERR.
TEST_F(AuthSrvTest, multiQuestion) {
- createDataFromFile("multiquestion_fromWire.wire");
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
- QR_FLAG, 2, 0, 0, 0);
-
- QuestionIterator qit = parse_message.beginQuestion();
- EXPECT_EQ(Name("example.com"), (*qit)->getName());
- EXPECT_EQ(RRClass::IN(), (*qit)->getClass());
- EXPECT_EQ(RRType::A(), (*qit)->getType());
- ++qit;
- EXPECT_EQ(Name("example.com"), (*qit)->getName());
- EXPECT_EQ(RRClass::IN(), (*qit)->getClass());
- EXPECT_EQ(RRType::AAAA(), (*qit)->getType());
- ++qit;
- EXPECT_TRUE(qit == parse_message.endQuestion());
+ MULTI_QUESTION_TEST;
}
// Incoming data doesn't even contain the complete header. Must be silently
// dropped.
TEST_F(AuthSrvTest, shortMessage) {
- createDataFromFile("shortmessage_fromWire");
- EXPECT_FALSE(server.processMessage(*io_message, parse_message,
- response_renderer));
+ SHORT_MESSAGE_TEST;
}
// Response messages. Must be silently dropped, whether it's a valid response
// or malformed or could otherwise cause a protocol error.
TEST_F(AuthSrvTest, response) {
- // A valid (although unusual) response
- createDataFromFile("simpleresponse_fromWire.wire");
- EXPECT_FALSE(server.processMessage(*io_message, parse_message,
- response_renderer));
-
- // A response with a broken question section. must be dropped rather than
- // returning FORMERR.
- createDataFromFile("shortresponse_fromWire");
- EXPECT_FALSE(server.processMessage(*io_message, parse_message,
- response_renderer));
-
- // A response to iquery. must be dropped rather than returning NOTIMP.
- createDataFromFile("iqueryresponse_fromWire.wire");
- EXPECT_FALSE(server.processMessage(*io_message, parse_message,
- response_renderer));
+ RESPONSE_TEST;
}
// Query with a broken question
TEST_F(AuthSrvTest, shortQuestion) {
- createDataFromFile("shortquestion_fromWire");
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- // Since the query's question is broken, the question section of the
- // response should be empty.
- headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
- QR_FLAG, 0, 0, 0, 0);
+ SHORT_QUESTION_TEST;
}
// Query with a broken answer section
TEST_F(AuthSrvTest, shortAnswer) {
- createDataFromFile("shortanswer_fromWire.wire");
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
-
- // This is a bogus query, but question section is valid. So the response
- // should copy the question section.
- headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
- QR_FLAG, 1, 0, 0, 0);
-
- QuestionIterator qit = parse_message.beginQuestion();
- EXPECT_EQ(Name("example.com"), (*qit)->getName());
- EXPECT_EQ(RRClass::IN(), (*qit)->getClass());
- EXPECT_EQ(RRType::A(), (*qit)->getType());
- ++qit;
- EXPECT_TRUE(qit == parse_message.endQuestion());
+ SHORT_ANSWER_TEST;
}
// Query with unsupported version of EDNS.
TEST_F(AuthSrvTest, ednsBadVers) {
- createDataFromFile("queryBadEDNS_fromWire.wire");
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
-
- // The response must have an EDNS OPT RR in the additional section, but
- // it will be added automatically at the render time.
- // Note that the DNSSEC DO bit is cleared even if this bit in the query
- // is set. This is a limitation of the current implementation.
- headerCheck(parse_message, default_qid, Rcode::BADVERS(), opcode.getCode(),
- QR_FLAG, 1, 0, 0, 1);
- EXPECT_FALSE(parse_message.getEDNS()); // EDNS isn't added at this point
-
- parse_message.clear(Message::PARSE);
- InputBuffer ib(response_renderer.getData(), response_renderer.getLength());
- parse_message.fromWire(ib);
- EXPECT_EQ(Rcode::BADVERS(), parse_message.getRcode());
- EXPECT_TRUE(parse_message.getEDNS());
- EXPECT_FALSE(parse_message.getEDNS()->getDNSSECAwareness());
+ EDNS_BADVERS_TEST;
}
TEST_F(AuthSrvTest, AXFROverUDP) {
- // AXFR over UDP is invalid and should result in FORMERR.
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_UDP);
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
- QR_FLAG, 1, 0, 0, 0);
+ AXFR_OVER_UDP_TEST;
}
TEST_F(AuthSrvTest, AXFRSuccess) {
EXPECT_FALSE(xfrout.isConnected());
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_TCP);
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(), RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_TCP);
// On success, the AXFR query has been passed to a separate process,
// so we shouldn't have to respond.
- EXPECT_FALSE(server.processMessage(*io_message, parse_message,
- response_renderer));
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
EXPECT_TRUE(xfrout.isConnected());
}
TEST_F(AuthSrvTest, AXFRConnectFail) {
EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
xfrout.disableConnect();
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_TCP);
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::SERVFAIL(),
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(), RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_TCP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
EXPECT_FALSE(xfrout.isConnected());
}
@@ -498,19 +117,21 @@
TEST_F(AuthSrvTest, AXFRSendFail) {
// first send a valid query, making the connection with the xfr process
// open.
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_TCP);
- server.processMessage(*io_message, parse_message, response_renderer);
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(), RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_TCP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_TRUE(xfrout.isConnected());
xfrout.disableSend();
- parse_message.clear(Message::PARSE);
- response_renderer.clear();
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_TCP);
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::SERVFAIL(),
+ parse_message->clear(Message::PARSE);
+ response_obuffer->clear();
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(), RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_TCP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
// The connection should have been closed due to the send failure.
@@ -522,10 +143,11 @@
// should it be thrown.
xfrout.disableSend();
xfrout.disableDisconnect();
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_TCP);
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(), RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_TCP);
EXPECT_THROW(server.processMessage(*io_message, parse_message,
- response_renderer),
+ response_obuffer, &dnsserv),
XfroutError);
EXPECT_TRUE(xfrout.isConnected());
// XXX: we need to re-enable disconnect. otherwise an exception would be
@@ -534,31 +156,31 @@
}
TEST_F(AuthSrvTest, notify) {
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(Message::HEADERFLAG_AA);
- createRequestPacket(IPPROTO_UDP);
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
// An internal command message should have been created and sent to an
// external module. Check them.
- EXPECT_EQ("Zonemgr", notify_session.msg_destination);
+ EXPECT_EQ("Zonemgr", notify_session.getMessageDest());
EXPECT_EQ("notify",
- notify_session.sent_msg->get("command")->get(0)->stringValue());
+ notify_session.getSentMessage()->get("command")->get(0)->stringValue());
ConstElementPtr notify_args =
- notify_session.sent_msg->get("command")->get(1);
+ notify_session.getSentMessage()->get("command")->get(1);
EXPECT_EQ("example.com.", notify_args->get("zone_name")->stringValue());
EXPECT_EQ(DEFAULT_REMOTE_ADDRESS,
notify_args->get("master")->stringValue());
EXPECT_EQ("IN", notify_args->get("zone_class")->stringValue());
// On success, the server should return a response to the notify.
- headerCheck(parse_message, default_qid, Rcode::NOERROR(),
+ headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
// The question must be identical to that of the received notify
- ConstQuestionPtr question = *parse_message.beginQuestion();
+ ConstQuestionPtr question = *parse_message->beginQuestion();
EXPECT_EQ(Name("example.com"), question->getName());
EXPECT_EQ(RRClass::IN(), question->getClass());
EXPECT_EQ(RRType::SOA(), question->getType());
@@ -566,17 +188,17 @@
TEST_F(AuthSrvTest, notifyForCHClass) {
// Same as the previous test, but for the CH RRClass.
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::CH(),
- RRType::SOA());
- request_message.setHeaderFlag(Message::HEADERFLAG_AA);
- createRequestPacket(IPPROTO_UDP);
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::CH(), RRType::SOA());
+ request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
// Other conditions should be the same, so simply confirm the RR class is
// set correctly.
ConstElementPtr notify_args =
- notify_session.sent_msg->get("command")->get(1);
+ notify_session.getSentMessage()->get("command")->get(1);
EXPECT_EQ("CH", notify_args->get("zone_class")->stringValue());
}
@@ -587,118 +209,119 @@
request_message.setHeaderFlag(Message::HEADERFLAG_AA);
request_message.setQid(default_qid);
request_message.toWire(request_renderer);
- createRequestPacket(IPPROTO_UDP);
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::FORMERR(),
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
}
TEST_F(AuthSrvTest, notifyMultiQuestions) {
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
// add one more SOA question
request_message.addQuestion(Question(Name("example.com"), RRClass::IN(),
RRType::SOA()));
request_message.setHeaderFlag(Message::HEADERFLAG_AA);
- createRequestPacket(IPPROTO_UDP);
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::FORMERR(),
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
Opcode::NOTIFY().getCode(), QR_FLAG, 2, 0, 0, 0);
}
TEST_F(AuthSrvTest, notifyNonSOAQuestion) {
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::NS());
- request_message.setHeaderFlag(Message::HEADERFLAG_AA);
- createRequestPacket(IPPROTO_UDP);
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::FORMERR(),
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::NS());
+ request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
Opcode::NOTIFY().getCode(), QR_FLAG, 1, 0, 0, 0);
}
TEST_F(AuthSrvTest, notifyWithoutAA) {
// implicitly leave the AA bit off. our implementation will accept it.
- createRequestPacket(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::NOERROR(),
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
}
TEST_F(AuthSrvTest, notifyWithErrorRcode) {
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
request_message.setHeaderFlag(Message::HEADERFLAG_AA);
request_message.setRcode(Rcode::SERVFAIL());
- createRequestPacket(IPPROTO_UDP);
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::NOERROR(),
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
}
TEST_F(AuthSrvTest, notifyWithoutSession) {
server.setXfrinSession(NULL);
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(Message::HEADERFLAG_AA);
- createRequestPacket(IPPROTO_UDP);
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+ createRequestPacket(request_message, IPPROTO_UDP);
// we simply ignore the notify and let it be resent if an internal error
// happens.
- EXPECT_FALSE(server.processMessage(*io_message, parse_message,
- response_renderer));
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
TEST_F(AuthSrvTest, notifySendFail) {
notify_session.disableSend();
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(Message::HEADERFLAG_AA);
- createRequestPacket(IPPROTO_UDP);
-
- EXPECT_FALSE(server.processMessage(*io_message, parse_message,
- response_renderer));
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+ createRequestPacket(request_message, IPPROTO_UDP);
+
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
TEST_F(AuthSrvTest, notifyReceiveFail) {
notify_session.disableReceive();
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(Message::HEADERFLAG_AA);
- createRequestPacket(IPPROTO_UDP);
- EXPECT_FALSE(server.processMessage(*io_message, parse_message,
- response_renderer));
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
TEST_F(AuthSrvTest, notifyWithBogusSessionMessage) {
notify_session.setMessage(Element::fromJSON("{\"foo\": 1}"));
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(Message::HEADERFLAG_AA);
- createRequestPacket(IPPROTO_UDP);
- EXPECT_FALSE(server.processMessage(*io_message, parse_message,
- response_renderer));
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
TEST_F(AuthSrvTest, notifyWithSessionMessageError) {
notify_session.setMessage(
Element::fromJSON("{\"result\": [1, \"FAIL\"]}"));
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(Message::HEADERFLAG_AA);
- createRequestPacket(IPPROTO_UDP);
- EXPECT_FALSE(server.processMessage(*io_message, parse_message,
- response_renderer));
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(Message::HEADERFLAG_AA);
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
void
@@ -723,9 +346,9 @@
// response should have the AA flag on, and have an RR in each answer
// and authority section.
createDataFromFile("examplequery_fromWire.wire");
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
QR_FLAG | AA_FLAG, 1, 1, 1, 0);
}
@@ -737,9 +360,9 @@
// in a SERVFAIL response, and the answer and authority sections should
// be empty.
createDataFromFile("badExampleQuery_fromWire.wire");
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::SERVFAIL(),
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
}
@@ -752,9 +375,9 @@
// The original data source should still exist.
createDataFromFile("examplequery_fromWire.wire");
- EXPECT_TRUE(server.processMessage(*io_message, parse_message,
- response_renderer));
- headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
+ headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
QR_FLAG | AA_FLAG, 1, 1, 1, 0);
}
Modified: trunk/src/bin/bind10/bind10.py.in
==============================================================================
--- trunk/src/bin/bind10/bind10.py.in (original)
+++ trunk/src/bin/bind10/bind10.py.in Mon Dec 20 23:14:49 2010
@@ -194,8 +194,9 @@
class BoB:
"""Boss of BIND class."""
- def __init__(self, msgq_socket_file=None, auth_port=5300, address=None,
- nocache=False, verbose=False, setuid=None, username=None):
+ def __init__(self, msgq_socket_file=None, dns_port=5300, address=None,
+ forward=None, nocache=False, verbose=False, setuid=None,
+ username=None):
"""
Initialize the Boss of BIND. This is a singleton (only one can run).
@@ -204,7 +205,13 @@
what it is doing.
"""
self.address = address
- self.auth_port = auth_port
+ self.dns_port = dns_port
+ self.forward = None
+ self.recursive = False
+ if forward:
+ self.forward = forward
+ self.recursive = True
+ self.nocache = False
self.cc_session = None
self.ccs = None
self.cfg_start_auth = True
@@ -417,19 +424,26 @@
Start the Authoritative server
"""
# XXX: this must be read from the configuration manager in the future
- authargs = ['b10-auth', '-p', str(self.auth_port)]
- if self.address:
- authargs += ['-a', str(self.address)]
- if self.nocache:
- authargs += ['-n']
+ if self.recursive:
+ dns_prog = 'b10-recurse'
+ else:
+ dns_prog = 'b10-auth'
+ dnsargs = [dns_prog]
+ if not self.recursive:
+ # The recursive uses configuration manager for these
+ dnsargs += ['-p', str(self.dns_port)]
+ if self.address:
+ dnsargs += ['-a', str(self.address)]
+ if self.nocache:
+ dnsargs += ['-n']
if self.uid:
- authargs += ['-u', str(self.uid)]
- if self.verbose:
- authargs += ['-v']
+ dnsargs += ['-u', str(self.uid)]
+ if self.verbose:
+ dnsargs += ['-v']
# ... and start
- self.start_process("b10-auth", authargs, c_channel_env,
- self.auth_port, self.address)
+ self.start_process("b10-auth", dnsargs, c_channel_env,
+ self.dns_port, self.address)
def start_recurse(self, c_channel_env):
"""
@@ -540,6 +554,7 @@
def stop_all_processes(self):
"""Stop all processes."""
cmd = { "command": ['shutdown']}
+
self.cc_session.group_sendmsg(cmd, 'Cmdctl', 'Cmdctl')
self.cc_session.group_sendmsg(cmd, "ConfigManager", "ConfigManager")
self.cc_session.group_sendmsg(cmd, "Auth", "Auth")
@@ -547,7 +562,7 @@
self.cc_session.group_sendmsg(cmd, "Xfrout", "Xfrout")
self.cc_session.group_sendmsg(cmd, "Xfrin", "Xfrin")
self.cc_session.group_sendmsg(cmd, "Zonemgr", "Zonemgr")
- self.cc_session.group_sendmsg(cmd, "Boss", "Stats")
+ self.cc_session.group_sendmsg(cmd, "Stats", "Stats")
def stop_process(self, process):
"""Stop the given process, friendly-like."""
@@ -713,7 +728,7 @@
a valid port number. Used by OptionParser() on startup."""
try:
if opt_str in ['-p', '--port']:
- parser.values.auth_port = isc.net.parse.port_parse(value)
+ parser.values.dns_port = isc.net.parse.port_parse(value)
else:
raise OptionValueError("Unknown option " + opt_str)
except ValueError as e:
@@ -725,6 +740,8 @@
try:
if opt_str in ['-a', '--address']:
parser.values.address = isc.net.parse.addr_parse(value)
+ if opt_str in ['-f', '--forward']:
+ parser.values.forward = isc.net.parse.addr_parse(value)
else:
raise OptionValueError("Unknown option " + opt_str)
except ValueError:
@@ -744,17 +761,19 @@
parser = OptionParser(version=VERSION)
parser.add_option("-a", "--address", dest="address", type="string",
action="callback", callback=check_addr, default=None,
- help="address the b10-auth daemon will use (default: listen on all addresses)")
+ help="address the DNS server will use (default: listen on all addresses)")
+ parser.add_option("-f", "--forward", dest="forward", type="string",
+ action="callback", callback=check_addr, default='',
+ help="nameserver to which DNS queries should be forwarded")
parser.add_option("-m", "--msgq-socket-file", dest="msgq_socket_file",
type="string", default=None,
help="UNIX domain socket file the b10-msgq daemon will use")
parser.add_option("-n", "--no-cache", action="store_true", dest="nocache",
- default=False, help="disable hot-spot cache in b10-auth")
- parser.add_option("-p", "--port", dest="auth_port", type="int",
+ default=False, help="disable hot-spot cache in authoritative DNS server")
+ parser.add_option("-p", "--port", dest="dns_port", type="int",
action="callback", callback=check_port, default=5300,
- help="port the b10-auth daemon will use (default 5300)")
- parser.add_option("-u", "--user", dest="user",
- type="string", default=None,
+ help="port the DNS server will use (default 5300)")
+ parser.add_option("-u", "--user", dest="user", type="string", default=None,
help="Change user after startup (must run as root)")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
help="display more about what is going on")
@@ -799,10 +818,6 @@
if options.verbose:
sys.stdout.write("%s\n" % VERSION)
- # TODO: set process name, perhaps by:
- # http://code.google.com/p/procname/
- # http://github.com/lericson/procname/
-
# Create wakeup pipe for signal handlers
wakeup_pipe = os.pipe()
signal.set_wakeup_fd(wakeup_pipe[1])
@@ -818,9 +833,9 @@
signal.signal(signal.SIGPIPE, signal.SIG_IGN)
# Go bob!
- boss_of_bind = BoB(options.msgq_socket_file, options.auth_port,
- options.address, options.nocache, options.verbose,
- setuid, username)
+ boss_of_bind = BoB(options.msgq_socket_file, options.dns_port,
+ options.address, options.forward, options.nocache,
+ options.verbose, setuid, username)
startup_result = boss_of_bind.startup()
if startup_result:
sys.stderr.write("[bind10] Error on startup: %s\n" % startup_result)
Modified: trunk/src/bin/bind10/run_bind10.sh.in
==============================================================================
--- trunk/src/bin/bind10/run_bind10.sh.in (original)
+++ trunk/src/bin/bind10/run_bind10.sh.in Mon Dec 20 23:14:49 2010
@@ -20,10 +20,10 @@
BIND10_PATH=@abs_top_builddir@/src/bin/bind10
-PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/stats:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:@abs_top_builddir@/src/bin/recurse:$PATH
+PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/recurse:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/stats:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:$PATH
export PATH
-PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/lib/dns/python/.libs:@abs_top_builddir@/src/lib/xfr/.libs
+PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/lib/dns/python/.libs:@abs_top_builddir@/src/lib/xfr/.libs:@abs_top_builddir@/src/lib/log/.libs
export PYTHONPATH
# If necessary (rare cases), explicitly specify paths to dynamic libraries
Modified: trunk/src/bin/bind10/tests/bind10_test.py
==============================================================================
--- trunk/src/bin/bind10/tests/bind10_test.py (original)
+++ trunk/src/bin/bind10/tests/bind10_test.py Mon Dec 20 23:14:49 2010
@@ -78,7 +78,7 @@
bob = BoB()
self.assertEqual(bob.verbose, False)
self.assertEqual(bob.msgq_socket_file, None)
- self.assertEqual(bob.auth_port, 5300)
+ self.assertEqual(bob.dns_port, 5300)
self.assertEqual(bob.address, None)
self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.ccs, None)
@@ -95,7 +95,24 @@
bob = BoB("alt_socket_file")
self.assertEqual(bob.verbose, False)
self.assertEqual(bob.msgq_socket_file, "alt_socket_file")
- self.assertEqual(bob.auth_port, 5300)
+ self.assertEqual(bob.address, None)
+ self.assertEqual(bob.dns_port, 5300)
+ self.assertEqual(bob.cc_session, None)
+ self.assertEqual(bob.ccs, None)
+ self.assertEqual(bob.processes, {})
+ self.assertEqual(bob.dead_processes, {})
+ self.assertEqual(bob.runnable, False)
+ self.assertEqual(bob.uid, None)
+ self.assertEqual(bob.username, None)
+ self.assertEqual(bob.nocache, False)
+ self.assertEqual(bob.cfg_start_auth, True)
+ self.assertEqual(bob.cfg_start_recurse, False)
+
+ def test_init_alternate_dns_port(self):
+ bob = BoB(None, 9999)
+ self.assertEqual(bob.verbose, False)
+ self.assertEqual(bob.msgq_socket_file, None)
+ self.assertEqual(bob.dns_port, 9999)
self.assertEqual(bob.address, None)
self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.ccs, None)
@@ -108,28 +125,11 @@
self.assertEqual(bob.cfg_start_auth, True)
self.assertEqual(bob.cfg_start_recurse, False)
- def test_init_alternate_auth_port(self):
- bob = BoB(None, 9999)
- self.assertEqual(bob.verbose, False)
- self.assertEqual(bob.msgq_socket_file, None)
- self.assertEqual(bob.auth_port, 9999)
- self.assertEqual(bob.address, None)
- self.assertEqual(bob.cc_session, None)
- self.assertEqual(bob.ccs, None)
- self.assertEqual(bob.processes, {})
- self.assertEqual(bob.dead_processes, {})
- self.assertEqual(bob.runnable, False)
- self.assertEqual(bob.uid, None)
- self.assertEqual(bob.username, None)
- self.assertEqual(bob.nocache, False)
- self.assertEqual(bob.cfg_start_auth, True)
- self.assertEqual(bob.cfg_start_recurse, False)
-
def test_init_alternate_address(self):
bob = BoB(None, 1234, IPAddr('127.127.127.127'))
self.assertEqual(bob.verbose, False)
self.assertEqual(bob.msgq_socket_file, None)
- self.assertEqual(bob.auth_port, 1234)
+ self.assertEqual(bob.dns_port, 1234)
self.assertEqual(bob.address.addr, socket.inet_aton('127.127.127.127'))
self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.ccs, None)
Modified: trunk/src/lib/Makefile.am
==============================================================================
--- trunk/src/lib/Makefile.am (original)
+++ trunk/src/lib/Makefile.am Mon Dec 20 23:14:49 2010
@@ -1,1 +1,2 @@
-SUBDIRS = exceptions dns cc config datasrc python xfr bench nsas
+SUBDIRS = exceptions dns cc config datasrc python xfr bench log asiolink \
+ testutils nsas
Modified: trunk/src/lib/cc/session.cc
==============================================================================
--- trunk/src/lib/cc/session.cc (original)
+++ trunk/src/lib/cc/session.cc Mon Dec 20 23:14:49 2010
@@ -171,7 +171,7 @@
asio::async_read(socket_, asio::buffer(data, datalen),
boost::bind(&setResult, &read_result, _1));
asio::deadline_timer timer(socket_.io_service());
-
+
if (getTimeout() != 0) {
timer.expires_from_now(boost::posix_time::milliseconds(getTimeout()));
timer.async_wait(boost::bind(&setResult, &timer_result, _1));
Modified: trunk/src/lib/dns/buffer.h
==============================================================================
--- trunk/src/lib/dns/buffer.h (original)
+++ trunk/src/lib/dns/buffer.h Mon Dec 20 23:14:49 2010
@@ -25,6 +25,8 @@
#include <exceptions/exceptions.h>
+#include <boost/shared_ptr.hpp>
+
namespace isc {
namespace dns {
@@ -412,6 +414,16 @@
private:
std::vector<uint8_t> data_;
};
+
+/// \brief Pointer-like types pointing to \c InputBuffer or \c OutputBuffer
+///
+/// These types are expected to be used as an argument in asynchronous
+/// callback functions. The internal reference-counting will ensure that
+/// that ongoing state information will not be lost if the object
+/// that originated the asynchronous call falls out of scope.
+typedef boost::shared_ptr<InputBuffer> InputBufferPtr;
+typedef boost::shared_ptr<OutputBuffer> OutputBufferPtr;
+
}
}
#endif // __BUFFER_H
Modified: trunk/src/lib/dns/message.h
==============================================================================
--- trunk/src/lib/dns/message.h (original)
+++ trunk/src/lib/dns/message.h Mon Dec 20 23:14:49 2010
@@ -517,6 +517,14 @@
MessageImpl* impl_;
};
+/// \brief Pointer-like type pointing to a \c Message
+///
+/// This type is expected to be used as an argument in asynchronous
+/// callback functions. The internal reference-counting will ensure that
+/// that ongoing state information will not be lost if the object
+/// that originated the asynchronous call falls out of scope.
+typedef boost::shared_ptr<Message> MessagePtr;
+
std::ostream& operator<<(std::ostream& os, const Message& message);
}
}
Modified: trunk/src/lib/dns/messagerenderer.h
==============================================================================
--- trunk/src/lib/dns/messagerenderer.h (original)
+++ trunk/src/lib/dns/messagerenderer.h Mon Dec 20 23:14:49 2010
@@ -258,6 +258,7 @@
/// \param name A \c Name object to be written.
/// \param compress A boolean indicating whether to enable name compression.
void writeName(const Name& name, bool compress = true);
+ //@}
private:
struct MessageRendererImpl;
MessageRendererImpl* impl_;
Modified: trunk/src/lib/dns/tests/unittest_util.cc
==============================================================================
--- trunk/src/lib/dns/tests/unittest_util.cc (original)
+++ trunk/src/lib/dns/tests/unittest_util.cc Mon Dec 20 23:14:49 2010
@@ -25,13 +25,15 @@
#include <gtest/gtest.h>
+#include <dns/rcode.h>
#include <dns/name.h>
+#include <dns/message.h>
#include <dns/tests/unittest_util.h>
using namespace std;
+using namespace isc::dns;
using isc::UnitTestUtil;
-using isc::dns::NameComparisonResult;
namespace {
class UnitTestUtilConfig {
@@ -175,3 +177,19 @@
}
return (::testing::AssertionSuccess());
}
+
+void
+UnitTestUtil::createRequestMessage(Message& message,
+ const Opcode& opcode,
+ const uint16_t qid,
+ const Name& name,
+ const RRClass& rrclass,
+ const RRType& rrtype)
+{
+ message.clear(Message::RENDER);
+ message.setOpcode(opcode);
+ message.setRcode(Rcode::NOERROR());
+ message.setQid(qid);
+ message.addQuestion(Question(name, rrclass, rrtype));
+}
+
Modified: trunk/src/lib/dns/tests/unittest_util.h
==============================================================================
--- trunk/src/lib/dns/tests/unittest_util.h (original)
+++ trunk/src/lib/dns/tests/unittest_util.h Mon Dec 20 23:14:49 2010
@@ -21,6 +21,7 @@
#include <string>
#include <dns/name.h>
+#include <dns/message.h>
#include <gtest/gtest.h>
@@ -80,6 +81,20 @@
static ::testing::AssertionResult
matchName(const char* nameexp1, const char* nameexp2,
const isc::dns::Name& name1, const isc::dns::Name& name2);
+
+ ///
+ /// Populate a request message
+ ///
+ /// Create a request message in 'request_message' using the
+ /// opcode 'opcode' and the name/class/type query tuple specified in
+ /// 'name', 'rrclass' and 'rrtype.
+ static void
+ createRequestMessage(isc::dns::Message& request_message,
+ const isc::dns::Opcode& opcode,
+ const uint16_t qid,
+ const isc::dns::Name& name,
+ const isc::dns::RRClass& rrclass,
+ const isc::dns::RRType& rrtype);
};
}
#endif // __UNITTEST_UTIL_H
More information about the bind10-changes
mailing list