[svn] commit: r3423 - in /branches/vorner-recursor-config: ./ src/bin/auth/ src/bin/recurse/ src/bin/recurse/tests/ src/lib/asiolink/ src/lib/asiolink/tests/
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Nov 3 10:48:28 UTC 2010
Author: vorner
Date: Wed Nov 3 10:48:27 2010
New Revision: 3423
Log:
Merge preparation, step 1
Doesn't compile yet. Only detected code-level conflicts resolved.
Modified:
branches/vorner-recursor-config/ (props changed)
branches/vorner-recursor-config/src/bin/auth/auth_srv.h
branches/vorner-recursor-config/src/bin/auth/main.cc
branches/vorner-recursor-config/src/bin/recurse/main.cc
branches/vorner-recursor-config/src/bin/recurse/recursor.cc
branches/vorner-recursor-config/src/bin/recurse/recursor.h
branches/vorner-recursor-config/src/bin/recurse/tests/Makefile.am
branches/vorner-recursor-config/src/bin/recurse/tests/recursor_unittest.cc
branches/vorner-recursor-config/src/lib/asiolink/Makefile.am
branches/vorner-recursor-config/src/lib/asiolink/asiolink.cc
branches/vorner-recursor-config/src/lib/asiolink/asiolink.h
branches/vorner-recursor-config/src/lib/asiolink/tests/asiolink_unittest.cc
Modified: branches/vorner-recursor-config/src/bin/auth/auth_srv.h
==============================================================================
--- branches/vorner-recursor-config/src/bin/auth/auth_srv.h (original)
+++ branches/vorner-recursor-config/src/bin/auth/auth_srv.h Wed Nov 3 10:48:27 2010
@@ -62,7 +62,7 @@
/// I/O service queue and return. When the server resumes, it can
/// send the reply.
///
- /// \param io_message The I/O service queue
+ /// \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
Modified: branches/vorner-recursor-config/src/bin/auth/main.cc
==============================================================================
--- branches/vorner-recursor-config/src/bin/auth/main.cc (original)
+++ branches/vorner-recursor-config/src/bin/auth/main.cc Wed Nov 3 10:48:27 2010
@@ -66,7 +66,7 @@
* class itself? */
static AuthSrv *auth_server;
-static IOService* io_service;
+static IOService io_service;
ConstElementPtr
my_config_handler(ConstElementPtr new_config) {
@@ -82,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);
@@ -193,6 +193,7 @@
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
@@ -200,16 +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 IOService(*port, *address,
- checkin, lookup, answer);
+ dns_service = new DNSService(io_service, *port, *address,
+ checkin, lookup, answer);
} else {
- io_service = new IOService(*port, use_ipv4, use_ipv6,
- checkin, lookup, answer);
- }
- auth_server->setIOService(*io_service);
+ 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,
@@ -221,7 +223,7 @@
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;
@@ -237,7 +239,7 @@
auth_server->updateConfig(ElementPtr());
cout << "[b10-auth] Server started." << endl;
- io_service->run();
+ io_service.run();
} catch (const std::exception& ex) {
cerr << "[b10-auth] Server failed: " << ex.what() << endl;
ret = 1;
@@ -250,7 +252,6 @@
delete xfrin_session;
delete config_session;
delete cc_session;
- delete io_service;
delete auth_server;
return (ret);
Modified: branches/vorner-recursor-config/src/bin/recurse/main.cc
==============================================================================
--- branches/vorner-recursor-config/src/bin/recurse/main.cc (original)
+++ branches/vorner-recursor-config/src/bin/recurse/main.cc Wed Nov 3 10:48:27 2010
@@ -62,7 +62,7 @@
// Default port current 5300 for testing purposes
static const string PROGRAM = "Recurse";
-static IOService* io_service;
+IOService io_service;
static Recursor *recursor;
ConstElementPtr
@@ -79,7 +79,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);
@@ -139,11 +139,12 @@
DNSLookup* lookup = recursor->getDNSLookupProvider();
DNSAnswer* answer = recursor->getDNSAnswerProvider();
- io_service = new IOService(checkin, lookup, answer);
- recursor->setIOService(*io_service);
+ DNSService dns_service(io_service, checkin, lookup, answer);
+
+ recursor->setDNSService(dns_service);
cout << "[b10-recurse] IOService created." << endl;
- cc_session = new Session(io_service->get_io_service());
+ cc_session = new Session(io_service.get_io_service());
cout << "[b10-recurse] Configuration session channel created." << endl;
config_session = new ModuleCCSession(specfile, *cc_session,
@@ -160,7 +161,7 @@
recursor->updateConfig(config_session->getFullConfig());
cout << "[b10-recurse] Server started." << endl;
- io_service->run();
+ io_service.run();
} catch (const std::exception& ex) {
cerr << "[b10-recurse] Server failed: " << ex.what() << endl;
ret = 1;
@@ -168,7 +169,6 @@
delete config_session;
delete cc_session;
- delete io_service;
delete recursor;
return (ret);
Modified: branches/vorner-recursor-config/src/bin/recurse/recursor.cc
==============================================================================
--- branches/vorner-recursor-config/src/bin/recurse/recursor.cc (original)
+++ branches/vorner-recursor-config/src/bin/recurse/recursor.cc Wed Nov 3 10:48:27 2010
@@ -76,8 +76,8 @@
queryShutdown();
}
- void querySetup(IOService& ios) {
- rec_query_ = new RecursiveQuery(ios, upstream_);
+ void querySetup(DNSService& dnss) {
+ rec_query_ = new RecursiveQuery(dnss, upstream_);
}
void queryShutdown() {
@@ -316,10 +316,10 @@
}
void
-Recursor::setIOService(asiolink::IOService& ios) {
+Recursor::setDNSService(asiolink::DNSService& dnss) {
impl_->queryShutdown();
- impl_->querySetup(ios);
- io_ = &ios;
+ impl_->querySetup(dnss);
+ dnss_ = &dnss;
}
void
Modified: branches/vorner-recursor-config/src/bin/recurse/recursor.h
==============================================================================
--- branches/vorner-recursor-config/src/bin/recurse/recursor.h (original)
+++ branches/vorner-recursor-config/src/bin/recurse/recursor.h Wed Nov 3 10:48:27 2010
@@ -51,7 +51,7 @@
/// I/O service queue and return. When the server resumes, it can
/// send the reply.
///
- /// \param io_message The I/O service queue
+ /// \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
@@ -76,10 +76,10 @@
isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
/// \brief Assign an ASIO IO Service queue to this Recursor object
- void setIOService(asiolink::IOService& ios);
+ void setDNSService(asiolink::DNSService& dnss);
/// \brief Return this object's ASIO IO Service queue
- asiolink::IOService& getIOService() const { return (*io_); }
+ asiolink::DNSService& getDNSService() const { return (*dnss_); }
/// \brief Return pointer to the DNS Lookup callback function
asiolink::DNSLookup* getDNSLookupProvider() { return (dns_lookup_); }
@@ -120,7 +120,7 @@
private:
RecursorImpl* impl_;
- asiolink::IOService* io_;
+ asiolink::DNSService* dnss_;
asiolink::SimpleCallback* checkin_;
asiolink::DNSLookup* dns_lookup_;
asiolink::DNSAnswer* dns_answer_;
Modified: branches/vorner-recursor-config/src/bin/recurse/tests/Makefile.am
==============================================================================
--- branches/vorner-recursor-config/src/bin/recurse/tests/Makefile.am (original)
+++ branches/vorner-recursor-config/src/bin/recurse/tests/Makefile.am Wed Nov 3 10:48:27 2010
@@ -35,24 +35,12 @@
noinst_PROGRAMS = $(TESTS)
-EXTRA_DIST = testdata/badExampleQuery_fromWire
-EXTRA_DIST += testdata/badExampleQuery_fromWire.spec
-EXTRA_DIST += testdata/example.com
-EXTRA_DIST += testdata/examplequery_fromWire
-EXTRA_DIST += testdata/examplequery_fromWire.spec
-EXTRA_DIST += testdata/example.sqlite3
-EXTRA_DIST += testdata/iqueryresponse_fromWire
-EXTRA_DIST += testdata/iqueryresponse_fromWire.spec
+EXTRA_DIST = testdata/iqueryresponse_fromWire
EXTRA_DIST += testdata/multiquestion_fromWire
-EXTRA_DIST += testdata/multiquestion_fromWire.spec
EXTRA_DIST += testdata/queryBadEDNS_fromWire
-EXTRA_DIST += testdata/queryBadEDNS_fromWire.spec
EXTRA_DIST += testdata/shortanswer_fromWire
-EXTRA_DIST += testdata/shortanswer_fromWire.spec
EXTRA_DIST += testdata/shortmessage_fromWire
EXTRA_DIST += testdata/shortquestion_fromWire
EXTRA_DIST += testdata/shortresponse_fromWire
EXTRA_DIST += testdata/simplequery_fromWire
-EXTRA_DIST += testdata/simplequery_fromWire.spec
EXTRA_DIST += testdata/simpleresponse_fromWire
-EXTRA_DIST += testdata/simpleresponse_fromWire.spec
Modified: branches/vorner-recursor-config/src/bin/recurse/tests/recursor_unittest.cc
==============================================================================
--- branches/vorner-recursor-config/src/bin/recurse/tests/recursor_unittest.cc (original)
+++ branches/vorner-recursor-config/src/bin/recurse/tests/recursor_unittest.cc Wed Nov 3 10:48:27 2010
@@ -63,15 +63,15 @@
class RecursorTest : public ::testing::Test {
protected:
- RecursorTest() : ios(*TEST_PORT, true, false, NULL, NULL, NULL),
- request_message(Message::RENDER),
- parse_message(new Message(Message::PARSE)),
- default_qid(0x1035), opcode(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(new OutputBuffer(0))
+ RecursorTest() : server(*DEFAULT_REMOTE_ADDRESS),
+ request_message(Message::RENDER),
+ parse_message(new Message(Message::PARSE)),
+ default_qid(0x1035), opcode(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(new OutputBuffer(0))
{
vector<pair<string, uint16_t> > upstream;
upstream.push_back(pair<string, uint16_t>(DEFAULT_REMOTE_ADDRESS, 53));
@@ -83,7 +83,6 @@
}
MockSession notify_session;
MockServer dnsserv;
- IOService ios;
Recursor server;
Message request_message;
MessagePtr parse_message;
Modified: branches/vorner-recursor-config/src/lib/asiolink/Makefile.am
==============================================================================
--- branches/vorner-recursor-config/src/lib/asiolink/Makefile.am (original)
+++ branches/vorner-recursor-config/src/lib/asiolink/Makefile.am Wed Nov 3 10:48:27 2010
@@ -12,11 +12,12 @@
# which would make the build fail with -Werror (our default setting).
lib_LTLIBRARIES = libasiolink.la
libasiolink_la_SOURCES = asiolink.cc asiolink.h
-libasiolink_la_SOURCES += iosocket.h
+libasiolink_la_SOURCES += iosocket.h iomessage.h
libasiolink_la_SOURCES += ioaddress.cc ioaddress.h
libasiolink_la_SOURCES += ioendpoint.cc ioendpoint.h
libasiolink_la_SOURCES += udpdns.cc internal/udpdns.h
libasiolink_la_SOURCES += tcpdns.cc internal/tcpdns.h
+libasiolink_la_SOURCES += internal/coroutine.h
# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
# B10_CXXFLAGS)
libasiolink_la_CXXFLAGS = $(AM_CXXFLAGS)
Modified: branches/vorner-recursor-config/src/lib/asiolink/asiolink.cc
==============================================================================
--- branches/vorner-recursor-config/src/lib/asiolink/asiolink.cc (original)
+++ branches/vorner-recursor-config/src/lib/asiolink/asiolink.cc Wed Nov 3 10:48:27 2010
@@ -46,15 +46,84 @@
namespace asiolink {
class IOServiceImpl {
+private:
+ IOServiceImpl(const IOService& source);
+ IOServiceImpl& operator=(const IOService& source);
public:
- IOServiceImpl(const char& port,
+ /// \brief The constructor
+ IOServiceImpl() : io_service_() {};
+ /// \brief The destructor.
+ ~IOServiceImpl() {};
+ //@}
+
+ /// \brief Start the underlying event loop.
+ ///
+ /// This method does not return control to the caller until
+ /// the \c stop() method is called via some handler.
+ void run() { io_service_.run(); };
+
+ /// \brief Run the underlying event loop for a single event.
+ ///
+ /// This method return control to the caller as soon as the
+ /// first handler has completed. (If no handlers are ready when
+ /// it is run, it will block until one is.)
+ void run_one() { io_service_.run_one();} ;
+
+ /// \brief Stop the underlying event loop.
+ ///
+ /// This will return the control to the caller of the \c run() method.
+ void stop() { io_service_.stop();} ;
+
+ /// \brief Return the native \c io_service object used in this wrapper.
+ ///
+ /// This is a short term work around to support other BIND 10 modules
+ /// that share the same \c io_service with the authoritative server.
+ /// It will eventually be removed once the wrapper interface is
+ /// generalized.
+ asio::io_service& get_io_service() { return io_service_; };
+private:
+ asio::io_service io_service_;
+};
+
+IOService::IOService() {
+ io_impl_ = new IOServiceImpl();
+}
+
+IOService::~IOService() {
+ delete io_impl_;
+}
+
+void
+IOService::run() {
+ io_impl_->run();
+}
+
+void
+IOService::run_one() {
+ io_impl_->run_one();
+}
+
+void
+IOService::stop() {
+ io_impl_->stop();
+}
+
+asio::io_service&
+IOService::get_io_service() {
+ return (io_impl_->get_io_service());
+}
+
+class DNSServiceImpl {
+public:
+ DNSServiceImpl(IOService& io_service, const char& port,
const ip::address* v4addr, const ip::address* v6addr,
SimpleCallback* checkin, DNSLookup* lookup,
DNSAnswer* answer);
- asio::io_service io_service_;
+ //asio::io_service io_service_;
// So it does not run out of work when there are no listening sockets
asio::io_service::work work_;
+ void stop();
typedef boost::shared_ptr<UDPServer> UDPServerPtr;
typedef boost::shared_ptr<TCPServer> TCPServerPtr;
typedef boost::shared_ptr<DNSServer> DNSServerPtr;
@@ -103,12 +172,14 @@
}
};
-IOServiceImpl::IOServiceImpl(const char& port,
- const ip::address* const v4addr,
- const ip::address* const v6addr,
- SimpleCallback* checkin,
- DNSLookup* lookup,
- DNSAnswer* answer) :
+DNSServiceImpl::DNSServiceImpl(IOService& io_service_,
+ const char& port,
+ const ip::address* const v4addr,
+ const ip::address* const v6addr,
+ SimpleCallback* checkin,
+ DNSLookup* lookup,
+ DNSAnswer* answer) :
+ // TODO MERGE move work to IOService
work_(io_service_),
checkin_(checkin),
lookup_(lookup),
@@ -123,36 +194,40 @@
}
}
-IOService::IOService(const char& port, const char& address,
- SimpleCallback* checkin,
- DNSLookup* lookup,
- DNSAnswer* answer) :
- impl_(new IOServiceImpl(port, NULL, NULL, checkin, lookup, answer))
+DNSService::DNSService(IOService& io_service,
+ const char& port, const char& address,
+ SimpleCallback* checkin,
+ DNSLookup* lookup,
+ DNSAnswer* answer) :
+ impl_(new IOServiceImpl(io_service, port, NULL, NULL, checkin, lookup,
+ answer)), io_service_(io_service)
{
addServer(port, &address);
}
-IOService::IOService(const char& port,
- const bool use_ipv4, const bool use_ipv6,
- SimpleCallback* checkin,
- DNSLookup* lookup,
- DNSAnswer* answer) :
- impl_(NULL)
+DNSService::DNSService(IOService& io_service,
+ const char& port,
+ const bool use_ipv4, const bool use_ipv6,
+ SimpleCallback* checkin,
+ DNSLookup* lookup,
+ DNSAnswer* answer) :
+ impl_(NULL), io_service_(io_service)
{
const ip::address v4addr_any = ip::address(ip::address_v4::any());
const ip::address* const v4addrp = use_ipv4 ? &v4addr_any : NULL;
const ip::address v6addr_any = ip::address(ip::address_v6::any());
const ip::address* const v6addrp = use_ipv6 ? &v6addr_any : NULL;
- impl_ = new IOServiceImpl(port, v4addrp, v6addrp, checkin, lookup, answer);
-}
-
-IOService::IOService(SimpleCallback* checkin, DNSLookup* lookup,
- DNSAnswer *answer) :
- impl_(new IOServiceImpl(*"", NULL, NULL, checkin, lookup, answer))
-{
-}
-
-IOService::~IOService() {
+ impl_ = new DNSServiceImpl(io_service, port, v4addrp, v6addrp, checkin, lookup, answer);
+}
+
+DNSService::DNSService(IOService& io_service, SimpleCallback* checkin,
+ DNSLookup* lookup, DNSAnswer *answer) :
+ impl_(new IOServiceImpl(io_service, *"0", NULL, NULL, checkin, lookup,
+ answer))
+{
+}
+
+DNSService::~DNSService() {
delete impl_;
}
@@ -172,17 +247,17 @@
}
void
-IOService::addServer(const char& port, const string& address) {
+DNSService::addServer(const char& port, const string& address) {
impl_->addServer(port, convertAddr(address));
}
void
-IOService::addServer(uint16_t port, const string &address) {
+DNSService::addServer(uint16_t port, const string &address) {
impl_->addServer(port, convertAddr(address));
}
void
-IOService::clearServers() {
+DNSService::clearServers() {
// FIXME: This does not work, it does not close the socket.
// How is it done?
impl_->servers_.clear();
@@ -208,9 +283,9 @@
return (impl_->io_service_);
}
-RecursiveQuery::RecursiveQuery(IOService& io_service,
+RecursiveQuery::RecursiveQuery(DNSService& dns_service,
const std::vector<std::pair<std::string, uint16_t> >& upstream) :
- io_service_(io_service), upstream_(upstream)
+ dns_service_(dns_service), upstream_(upstream)
{}
void
@@ -222,7 +297,7 @@
// the message should be sent via TCP or UDP, or sent initially via
// UDP and then fall back to TCP on failure, but for the moment
// we're only going to handle UDP.
- asio::io_service& io = io_service_.get_io_service();
+ asio::io_service& io = dns_service_.get_io_service();
// TODO: Better way to choose the server
int serverIndex(random() % upstream_.size());
UDPQuery q(io, question, upstream_[serverIndex].first,
Modified: branches/vorner-recursor-config/src/lib/asiolink/asiolink.h
==============================================================================
--- branches/vorner-recursor-config/src/lib/asiolink/asiolink.h (original)
+++ branches/vorner-recursor-config/src/lib/asiolink/asiolink.h Wed Nov 3 10:48:27 2010
@@ -38,6 +38,7 @@
#include <asiolink/ioendpoint.h>
#include <asiolink/iomessage.h>
#include <asiolink/iosocket.h>
+//#include <asio/io_service.hpp>
namespace asio {
// forward declaration for IOService::get_io_service() below
@@ -95,6 +96,7 @@
/// http://think-async.com/Asio/asio-1.3.1/doc/asio/reference/asio_handler_allocate.html
namespace asiolink {
+struct DNSServiceImpl;
struct IOServiceImpl;
/// \brief An exception that is thrown if an error occurs within the IO
@@ -114,17 +116,9 @@
/// \brief The \c IOService class is a wrapper for the ASIO \c io_service
/// class.
///
-/// Currently, the interface of this class is very specific to the
-/// authoritative/recursive DNS server implementationss in b10-auth
-/// and b10-recurse; this is reflected in the constructor signatures.
-/// Ultimately the plan is to generalize it so that other BIND 10
-/// modules can use this interface, too.
class IOService {
///
/// \name Constructors and Destructor
- ///
- /// These are currently very specific to the authoritative server
- /// implementation.
///
/// Note: The copy constructor and the assignment operator are
/// intentionally defined as private, making this class non-copyable.
@@ -133,22 +127,8 @@
IOService(const IOService& source);
IOService& operator=(const IOService& source);
public:
- /// \brief The constructor with a specific IP address and port on which
- /// the services listen on.
- IOService(const char& port, const char& address,
- SimpleCallback* checkin,
- DNSLookup* lookup,
- DNSAnswer* answer);
- /// \brief The constructor with a specific port on which the services
- /// listen on.
- ///
- /// It effectively listens on "any" IPv4 and/or IPv6 addresses.
- /// IPv4/IPv6 services will be available if and only if \c use_ipv4
- /// or \c use_ipv6 is \c true, respectively.
- IOService(const char& port, const bool use_ipv4, const bool use_ipv6,
- SimpleCallback* checkin,
- DNSLookup* lookup,
- DNSAnswer* answer);
+ /// \brief The constructor
+ IOService();
/// \brief The constructor without any servers.
///
/// Use addServer() to add some servers.
@@ -188,8 +168,71 @@
/// It will eventually be removed once the wrapper interface is
/// generalized.
asio::io_service& get_io_service();
-private:
- IOServiceImpl* impl_;
+
+private:
+ IOServiceImpl* io_impl_;
+};
+
+///
+/// DNSService is the service that handles DNS queries and answers with
+/// a given IOService.
+///
+class DNSService {
+ ///
+ /// \name Constructors and Destructor
+ ///
+ /// Note: The copy constructor and the assignment operator are
+ /// intentionally defined as private, making this class non-copyable.
+ //@{
+private:
+ DNSService(const DNSService& source);
+ DNSService& operator=(const DNSService& source);
+
+public:
+ /// \brief The constructor with a specific IP address and port on which
+ /// the services listen on.
+ ///
+ /// \param io_service The IOService to work with
+ /// \param port the port to listen on
+ /// \param address the IP address to listen on
+ /// \param checkin Provider for cc-channel events (see \c SimpleCallback)
+ /// \param lookup The lookup provider (see \c DNSLookup)
+ /// \param answer The answer provider (see \c DNSAnswer)
+ DNSService(IOService& io_service, const char& port,
+ const char& address, SimpleCallback* checkin,
+ DNSLookup* lookup, DNSAnswer* answer);
+ /// \brief The constructor with a specific port on which the services
+ /// listen on.
+ ///
+ /// It effectively listens on "any" IPv4 and/or IPv6 addresses.
+ /// IPv4/IPv6 services will be available if and only if \c use_ipv4
+ /// or \c use_ipv6 is \c true, respectively.
+ ///
+ /// \param io_service The IOService to work with
+ /// \param port the port to listen on
+ /// \param ipv4 If true, listen on ipv4 'any'
+ /// \param ipv6 If true, listen on ipv6 'any'
+ /// \param checkin Provider for cc-channel events (see \c SimpleCallback)
+ /// \param lookup The lookup provider (see \c DNSLookup)
+ /// \param answer The answer provider (see \c DNSAnswer)
+ DNSService(IOService& io_service, const char& port,
+ const bool use_ipv4, const bool use_ipv6,
+ SimpleCallback* checkin, DNSLookup* lookup,
+ DNSAnswer* answer);
+ /// \brief The destructor.
+ ~DNSService();
+ //@}
+
+ /// \brief Return the native \c io_service object used in this wrapper.
+ ///
+ /// This is a short term work around to support other BIND 10 modules
+ /// that share the same \c io_service with the authoritative server.
+ /// It will eventually be removed once the wrapper interface is
+ /// generalized.
+ asio::io_service& get_io_service() { return io_service_.get_io_service(); };
+private:
+ DNSServiceImpl* impl_;
+ IOService& io_service_;
};
/// \brief The \c DNSServer class is a wrapper (and base class) for
@@ -248,6 +291,9 @@
/// \brief Resume processing of the server coroutine after an
/// asynchronous call (e.g., to the DNS Lookup provider) has completed.
+ ///
+ /// \param done If true, this signals the system there is an answer
+ /// to return.
virtual inline void resume(const bool done) { self_->resume(done); }
/// \brief Indicate whether the server is able to send an answer
@@ -262,6 +308,8 @@
/// purposes during development and removed later. It allows
/// callers from outside the coroutine object to retrieve information
/// about its current state.
+ ///
+ /// \return The value of the 'coroutine' object
virtual inline int value() { return (self_->value()); }
/// \brief Returns a pointer to a clone of this DNSServer object.
@@ -270,6 +318,8 @@
/// normally be another \c DNSServer object containing a copy
/// of the original "self_" pointer. Calling clone() guarantees
/// that the underlying object is also correctly copied.
+ ///
+ /// \return A deep copy of this DNSServer object
virtual inline DNSServer* clone() { return (self_->clone()); }
//@}
@@ -349,6 +399,11 @@
/// This makes its call indirectly via the "self" pointer, ensuring
/// that the function ultimately invoked will be the one in the derived
/// class.
+ ///
+ /// \param io_message The event message to handle
+ /// \param message The DNS MessagePtr that needs handling
+ /// \param buffer The final answer is put here
+ /// \param DNSServer DNSServer object to use
virtual void operator()(const IOMessage& io_message,
isc::dns::MessagePtr message,
isc::dns::OutputBufferPtr buffer,
@@ -394,6 +449,14 @@
virtual ~DNSAnswer() {}
//@}
/// \brief The function operator
+ ///
+ /// This makes its call indirectly via the "self" pointer, ensuring
+ /// that the function ultimately invoked will be the one in the derived
+ /// class.
+ ///
+ /// \param io_message The event message to handle
+ /// \param message The DNS MessagePtr that needs handling
+ /// \param buffer The result is put here
virtual void operator()(const IOMessage& io_message,
isc::dns::MessagePtr message,
isc::dns::OutputBufferPtr buffer) const = 0;
@@ -436,6 +499,8 @@
/// This makes its call indirectly via the "self" pointer, ensuring
/// that the function ultimately invoked will be the one in the derived
/// class.
+ ///
+ /// \param io_message The event message to handle
virtual void operator()(const IOMessage& io_message) const {
(*self_)(io_message);
}
@@ -459,26 +524,30 @@
/// This is currently the only way to construct \c RecursiveQuery
/// object. The addresses of the forward nameservers is specified,
/// and every upstream query will be sent to one random address.
+ /// \param dns_service The DNS Service to perform the recursive
+ /// query on.
+ /// \param upstream Addresses and ports of the upstream servers
+ /// to forward queries to.
RecursiveQuery(IOService& io_service,
const std::vector<std::pair<std::string, uint16_t> >&
upstream);
//@}
/// \brief Initiates an upstream query in the \c RecursiveQuery object.
- ///
- /// \param question The question being answered <qname/qclass/qtype>
- /// \param buffer An output buffer into which the response can be copied
- /// \param server A pointer to the \c DNSServer object handling the client
///
/// When sendQuery() is called, a message is sent asynchronously to
/// the upstream name server. When a reply arrives, 'server'
/// is placed on the ASIO service queue via io_service::post(), so
/// that the original \c DNSServer objct can resume processing.
+ ///
+ /// \param question The question being answered <qname/qclass/qtype>
+ /// \param buffer An output buffer into which the response can be copied
+ /// \param server A pointer to the \c DNSServer object handling the client
void sendQuery(const isc::dns::Question& question,
isc::dns::OutputBufferPtr buffer,
DNSServer* server);
private:
- IOService& io_service_;
+ DNSService& dns_service_;
std::vector<std::pair<std::string, uint16_t> > upstream_;
};
Modified: branches/vorner-recursor-config/src/lib/asiolink/tests/asiolink_unittest.cc
==============================================================================
--- branches/vorner-recursor-config/src/lib/asiolink/tests/asiolink_unittest.cc (original)
+++ branches/vorner-recursor-config/src/lib/asiolink/tests/asiolink_unittest.cc Wed Nov 3 10:48:27 2010
@@ -135,69 +135,92 @@
}
TEST(IOServiceTest, badPort) {
- EXPECT_THROW(IOService(*"65536", true, false, NULL, NULL, NULL), IOError);
- EXPECT_THROW(IOService(*"5300.0", true, false, NULL, NULL, NULL), IOError);
- EXPECT_THROW(IOService(*"-1", true, false, NULL, NULL, NULL), IOError);
- EXPECT_THROW(IOService(*"domain", true, false, NULL, NULL, NULL), IOError);
+ IOService io_service;
+ EXPECT_THROW(DNSService(io_service, *"65536", true, false, NULL, NULL, NULL), IOError);
+ EXPECT_THROW(DNSService(io_service, *"5300.0", true, false, NULL, NULL, NULL), IOError);
+ EXPECT_THROW(DNSService(io_service, *"-1", true, false, NULL, NULL, NULL), IOError);
+ EXPECT_THROW(DNSService(io_service, *"domain", true, false, NULL, NULL, NULL), IOError);
}
TEST(IOServiceTest, badAddress) {
- EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"192.0.2.1.1", NULL, NULL, NULL), IOError);
- EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"2001:db8:::1", NULL, NULL, NULL), IOError);
- EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"localhost", NULL, NULL, NULL), IOError);
+ IOService io_service;
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"192.0.2.1.1", NULL, NULL, NULL), IOError);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"2001:db8:::1", NULL, NULL, NULL), IOError);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"localhost", NULL, NULL, NULL), IOError);
}
TEST(IOServiceTest, unavailableAddress) {
+ IOService io_service;
// These addresses should generally be unavailable as a valid local
// address, although there's no guarantee in theory.
- EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"255.255.0.0", NULL, NULL, NULL), IOError);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"255.255.0.0", NULL, NULL, NULL), IOError);
// Some OSes would simply reject binding attempt for an AF_INET6 socket
// to an IPv4-mapped IPv6 address. Even if those that allow it, since
// the corresponding IPv4 address is the same as the one used in the
// AF_INET socket case above, it should at least show the same result
// as the previous one.
- EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"::ffff:255.255.0.0", NULL, NULL, NULL), IOError);
-}
-
-TEST(IOServiceTest, duplicateBind) {
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:255.255.0.0", NULL, NULL, NULL), IOError);
+}
+
+TEST(IOServiceTest, duplicateBind_v6) {
// In each sub test case, second attempt should fail due to duplicate bind
+ IOService io_service;
// IPv6, "any" address
- IOService* io_service = new IOService(*TEST_SERVER_PORT, false, true, NULL, NULL, NULL);
- EXPECT_THROW(IOService(*TEST_SERVER_PORT, false, true, NULL, NULL, NULL), IOError);
- delete io_service;
+ DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, false, true, NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, false, true, NULL, NULL, NULL), IOError);
+ delete dns_service;
+
+}
+
+TEST(IOServiceTest, duplicateBind_v6_address) {
+ // In each sub test case, second attempt should fail due to duplicate bind
+ IOService io_service;
// IPv6, specific address
- io_service = new IOService(*TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL);
- EXPECT_THROW(IOService(*TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL), IOError);
- delete io_service;
+ DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL), IOError);
+ delete dns_service;
+
+}
+
+TEST(IOServiceTest, duplicateBind_v4) {
+ // In each sub test case, second attempt should fail due to duplicate bind
+ IOService io_service;
// IPv4, "any" address
- io_service = new IOService(*TEST_SERVER_PORT, true, false, NULL, NULL, NULL);
- EXPECT_THROW(IOService(*TEST_SERVER_PORT, true, false, NULL, NULL, NULL), IOError);
- delete io_service;
+ DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, true, false, NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, true, false, NULL, NULL, NULL), IOError);
+ delete dns_service;
+
+}
+
+TEST(IOServiceTest, duplicateBind_v4_address) {
+ // In each sub test case, second attempt should fail due to duplicate bind
+ IOService io_service;
// IPv4, specific address
- io_service = new IOService(*TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL);
- EXPECT_THROW(IOService(*TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL), IOError);
- delete io_service;
+ DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL), IOError);
+ delete dns_service;
}
// Disabled because IPv4-mapped addresses don't seem to be working with
// the IOService constructor
TEST(IOServiceTest, DISABLED_IPv4MappedDuplicateBind) {
+ IOService io_service;
// Duplicate bind on IPv4-mapped IPv6 address
- IOService* io_service = new IOService(*TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL);
- EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL), IOError);
- delete io_service;
+ DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL), IOError);
+ delete dns_service;
// XXX:
// Currently, this throws an "invalid argument" exception. I have
// not been able to get IPv4-mapped addresses to work.
- io_service = new IOService(*TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL);
- EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL), IOError);
- delete io_service;
+ dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL);
+ EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL), IOError);
+ delete dns_service;
}
// This function returns an addrinfo structure for use by tests, using
@@ -234,7 +257,7 @@
// received on the server side. It then checks the received data matches
// expected parameters.
// If initialization parameters of the IOService should be modified, the test
-// case can do it using the setIOService() method.
+// case can do it using the setDNSService() method.
// Note: the set of tests in ASIOLinkTest use actual network services and may
// involve undesirable side effects such as blocking.
class ASIOLinkTest : public ::testing::Test {
@@ -247,12 +270,9 @@
if (sock_ != -1) {
close(sock_);
}
- if (io_service_ != NULL) {
- delete io_service_;
- }
- if (callback_ != NULL) {
- delete callback_;
- }
+ delete dns_service_;
+ delete callback_;
+ delete io_service_;
}
// Send a test UDP packet to a mock server
@@ -324,21 +344,25 @@
// Set up an IO Service queue using the specified address
- void setIOService(const char& address) {
+ void setDNSService(const char& address) {
+ delete dns_service_;
+ dns_service_ = NULL;
delete io_service_;
- io_service_ = NULL;
+ io_service_ = new IOService();
callback_ = new ASIOCallBack(this);
- io_service_ = new IOService(*TEST_SERVER_PORT, address, callback_, NULL, NULL);
+ dns_service_ = new DNSService(*io_service_, *TEST_SERVER_PORT, address, callback_, NULL, NULL);
}
// Set up an IO Service queue using the "any" address, on IPv4 if
// 'use_ipv4' is true and on IPv6 if 'use_ipv6' is true.
- void setIOService(const bool use_ipv4, const bool use_ipv6) {
+ void setDNSService(const bool use_ipv4, const bool use_ipv6) {
+ delete dns_service_;
+ dns_service_ = NULL;
delete io_service_;
- io_service_ = NULL;
+ io_service_ = new IOService();
callback_ = new ASIOCallBack(this);
- io_service_ = new IOService(*TEST_SERVER_PORT, use_ipv4, use_ipv6, callback_,
- NULL, NULL);
+ dns_service_ = new DNSService(*io_service_, *TEST_SERVER_PORT, use_ipv4, use_ipv6, callback_,
+ NULL, NULL);
}
// Set up an IO Service queue without any addresses
@@ -455,7 +479,10 @@
io_service_->stop();
}
protected:
+ // We use a pointer for io_service_, because for some tests we
+ // need to recreate a new one within one onstance of this class
IOService* io_service_;
+ DNSService* dns_service_;
ASIOCallBack* callback_;
int callback_protocol_;
int callback_native_;
@@ -467,9 +494,10 @@
};
ASIOLinkTest::ASIOLinkTest() :
- io_service_(NULL), callback_(NULL), sock_(-1), res_(NULL)
+ dns_service_(NULL), callback_(NULL), sock_(-1), res_(NULL)
{
- setIOService(true, true);
+ io_service_ = new IOService();
+ setDNSService(true, true);
}
TEST_F(ASIOLinkTest, v6UDPSend) {
@@ -500,24 +528,24 @@
// an error on a subsequent read operation. We could do it, but for
// simplicity we only tests the easier cases for now.
- setIOService(*TEST_IPV6_ADDR);
+ setDNSService(*TEST_IPV6_ADDR);
doTest(AF_INET6, IPPROTO_UDP);
}
TEST_F(ASIOLinkTest, v6TCPSendSpecific) {
- setIOService(*TEST_IPV6_ADDR);
+ setDNSService(*TEST_IPV6_ADDR);
doTest(AF_INET6, IPPROTO_TCP);
EXPECT_THROW(sendTCP(AF_INET), IOError);
}
TEST_F(ASIOLinkTest, v4UDPSendSpecific) {
- setIOService(*TEST_IPV4_ADDR);
+ setDNSService(*TEST_IPV4_ADDR);
doTest(AF_INET, IPPROTO_UDP);
}
TEST_F(ASIOLinkTest, v4TCPSendSpecific) {
- setIOService(*TEST_IPV4_ADDR);
+ setDNSService(*TEST_IPV4_ADDR);
doTest(AF_INET, IPPROTO_TCP);
EXPECT_THROW(sendTCP(AF_INET6), IOError);
@@ -552,12 +580,12 @@
// Open only IPv6 TCP socket. A subsequent attempt of establishing an
// IPv4/TCP connection should fail. See above for why we only test this
// for TCP.
- setIOService(false, true);
+ setDNSService(false, true);
EXPECT_THROW(sendTCP(AF_INET), IOError);
}
TEST_F(ASIOLinkTest, v4TCPOnly) {
- setIOService(true, false);
+ setDNSService(true, false);
EXPECT_THROW(sendTCP(AF_INET6), IOError);
}
@@ -569,16 +597,16 @@
}
TEST_F(ASIOLinkTest, recursiveSetupV4) {
- setIOService(true, false);
+ setDNSService(true, false);
uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
- EXPECT_NO_THROW(RecursiveQuery(*io_service_, singleAddress(TEST_IPV6_ADDR,
+ EXPECT_NO_THROW(RecursiveQuery(*dns_service_, singleAddress(TEST_IPV6_ADDR,
port)));
}
TEST_F(ASIOLinkTest, recursiveSetupV6) {
- setIOService(false, true);
+ setDNSService(false, true);
uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
- EXPECT_NO_THROW(RecursiveQuery(*io_service_, singleAddress(TEST_IPV6_ADDR,
+ EXPECT_NO_THROW(RecursiveQuery(*dns_service_, singleAddress(TEST_IPV6_ADDR,
port)));
}
@@ -588,7 +616,7 @@
// port, and with the various callbacks defined in such a way as to ensure
// full code coverage including error cases.
TEST_F(ASIOLinkTest, recursiveSend) {
- setIOService(true, false);
+ setDNSService(true, false);
asio::io_service& io = io_service_->get_io_service();
// Note: We use the test prot plus one to ensure we aren't binding
@@ -597,7 +625,7 @@
asio::ip::address addr = asio::ip::address::from_string(TEST_IPV4_ADDR);
MockServer server(io, addr, port, NULL, NULL, NULL);
- RecursiveQuery rq(*io_service_, singleAddress(TEST_IPV4_ADDR, port));
+ RecursiveQuery rq(*dns_service_, singleAddress(TEST_IPV4_ADDR, port));
Question q(Name("example.com"), RRClass::IN(), RRType::TXT());
OutputBufferPtr buffer(new OutputBuffer(0));
More information about the bind10-changes
mailing list