BIND 10 master, updated. 555c57669226bca31e961412fde174f04db876ab Merge #1599
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Feb 28 09:04:15 UTC 2012
The branch, master has been updated
via 555c57669226bca31e961412fde174f04db876ab (commit)
via 3b8892835a95f7b17f93f5f3ca36c14da1a82363 (commit)
via ccc2fb769ced7cef416b55d9074591022b8a673b (commit)
via 69360a12e78e7567f88dcd3079c9a56be534ea7d (commit)
via 6ec73d5de3e72a8d6adbb7e3bc353b68584b344f (commit)
via d6d42bcdfcc80b450b89937ffd5ba39b071b3f37 (commit)
via 0c0161c6e555e2c8b33b3291043727bc07324dc2 (commit)
via ecd7dbe0f231c04d19eba3cd02ff513a23a9003a (commit)
via f472a687b70982f906bcc96900fdbc3ee8d36ff6 (commit)
via aa0318899f62fc3069572bb18bc6dd071bb8448d (commit)
from 04f9d8ebe54788a4f4f3aa7be7d50347a26565c0 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 555c57669226bca31e961412fde174f04db876ab
Merge: 04f9d8ebe54788a4f4f3aa7be7d50347a26565c0 3b8892835a95f7b17f93f5f3ca36c14da1a82363
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Tue Feb 28 09:42:09 2012 +0100
Merge #1599
-----------------------------------------------------------------------
Summary of changes:
src/lib/asiodns/Makefile.am | 1 +
src/lib/asiodns/dns_server.h | 16 --
src/lib/asiodns/sync_udp_server.cc | 216 ++++++++++++++++++++++++++
src/lib/asiodns/sync_udp_server.h | 159 +++++++++++++++++++
src/lib/asiodns/tcp_server.h | 3 -
src/lib/asiodns/tests/dns_server_unittest.cc | 119 ++++++++++----
src/lib/asiodns/udp_server.cc | 5 -
src/lib/asiodns/udp_server.h | 10 --
8 files changed, 460 insertions(+), 69 deletions(-)
create mode 100644 src/lib/asiodns/sync_udp_server.cc
create mode 100644 src/lib/asiodns/sync_udp_server.h
-----------------------------------------------------------------------
diff --git a/src/lib/asiodns/Makefile.am b/src/lib/asiodns/Makefile.am
index b5d030d..a03f147 100644
--- a/src/lib/asiodns/Makefile.am
+++ b/src/lib/asiodns/Makefile.am
@@ -24,6 +24,7 @@ libasiodns_la_SOURCES += dns_server.h
libasiodns_la_SOURCES += dns_service.cc dns_service.h
libasiodns_la_SOURCES += tcp_server.cc tcp_server.h
libasiodns_la_SOURCES += udp_server.cc udp_server.h
+libasiodns_la_SOURCES += sync_udp_server.cc sync_udp_server.h
libasiodns_la_SOURCES += io_fetch.cc io_fetch.h
libasiodns_la_SOURCES += logger.h logger.cc
diff --git a/src/lib/asiodns/dns_server.h b/src/lib/asiodns/dns_server.h
index d3a8528..119aa66 100644
--- a/src/lib/asiodns/dns_server.h
+++ b/src/lib/asiodns/dns_server.h
@@ -88,22 +88,6 @@ public:
/// to return.
virtual void resume(const bool done) { self_->resume(done); }
- /// \brief Indicate whether the server is able to send an answer
- /// to a query.
- ///
- /// This is presently used only for testing purposes.
- virtual bool hasAnswer() { return (self_->hasAnswer()); }
-
- /// \brief Returns the current value of the 'coroutine' object
- ///
- /// This is a temporary method, intended to be used for debugging
- /// 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 int value() { return (self_->value()); }
-
/// \brief Returns a pointer to a clone of this DNSServer object.
///
/// When a \c DNSServer object is copied or assigned, the result will
diff --git a/src/lib/asiodns/sync_udp_server.cc b/src/lib/asiodns/sync_udp_server.cc
new file mode 100644
index 0000000..b60315f
--- /dev/null
+++ b/src/lib/asiodns/sync_udp_server.cc
@@ -0,0 +1,216 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+
+#include <asio.hpp>
+#include <asio/error.hpp>
+
+#include "sync_udp_server.h"
+#include "logger.h"
+
+#include <asiolink/dummy_io_cb.h>
+#include <asiolink/udp_endpoint.h>
+#include <asiolink/udp_socket.h>
+
+#include <boost/bind.hpp>
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h> // for some IPC/network system calls
+#include <errno.h>
+
+using namespace std;
+using namespace boost;
+using namespace isc::asiolink;
+
+namespace isc {
+namespace asiodns {
+
+SyncUDPServer::SyncUDPServer(asio::io_service& io_service,
+ const asio::ip::address& addr,
+ const uint16_t port,
+ asiolink::SimpleCallback* checkin,
+ DNSLookup* lookup, DNSAnswer* answer) :
+ output_buffer_(new isc::util::OutputBuffer(0)),
+ query_(new isc::dns::Message(isc::dns::Message::PARSE)),
+ answer_(new isc::dns::Message(isc::dns::Message::RENDER)),
+ io_(io_service), checkin_callback_(checkin), lookup_callback_(lookup),
+ answer_callback_(answer), stopped_(false)
+{
+ // We must use different instantiations for v4 and v6;
+ // otherwise ASIO will bind to both
+ asio::ip::udp proto = addr.is_v4() ? asio::ip::udp::v4() :
+ asio::ip::udp::v6();
+ socket_.reset(new asio::ip::udp::socket(io_service, proto));
+ socket_->set_option(asio::socket_base::reuse_address(true));
+ if (addr.is_v6()) {
+ socket_->set_option(asio::ip::v6_only(true));
+ }
+ socket_->bind(asio::ip::udp::endpoint(addr, port));
+}
+
+SyncUDPServer::SyncUDPServer(asio::io_service& io_service, const int fd,
+ const int af, asiolink::SimpleCallback* checkin,
+ DNSLookup* lookup, DNSAnswer* answer) :
+ output_buffer_(new isc::util::OutputBuffer(0)),
+ query_(new isc::dns::Message(isc::dns::Message::PARSE)),
+ answer_(new isc::dns::Message(isc::dns::Message::RENDER)),
+ io_(io_service), checkin_callback_(checkin), lookup_callback_(lookup),
+ answer_callback_(answer), stopped_(false)
+{
+ if (af != AF_INET && af != AF_INET6) {
+ isc_throw(InvalidParameter, "Address family must be either AF_INET "
+ "or AF_INET6, not " << af);
+ }
+ LOG_DEBUG(logger, DBGLVL_TRACE_BASIC, ASIODNS_FD_ADD_UDP).arg(fd);
+ try {
+ socket_.reset(new asio::ip::udp::socket(io_service));
+ socket_->assign(af == AF_INET6 ? asio::ip::udp::v6() :
+ asio::ip::udp::v4(), fd);
+ } catch (const std::exception& exception) {
+ // Whatever the thing throws, it is something from ASIO and we
+ // convert it
+ isc_throw(IOError, exception.what());
+ }
+}
+
+void
+SyncUDPServer::scheduleRead() {
+ socket_->async_receive_from(asio::buffer(data_, MAX_LENGTH), sender_,
+ boost::bind(&SyncUDPServer::handleRead, this,
+ _1, _2));
+}
+
+void
+SyncUDPServer::handleRead(const asio::error_code& ec, const size_t length) {
+ // Abort on fatal errors
+ if (ec) {
+ using namespace asio::error;
+ if (ec.value() != would_block && ec.value() != try_again &&
+ ec.value() != interrupted) {
+ return;
+ }
+ }
+ // Some kind of interrupt, spurious wakeup, or like that. Just try reading
+ // again.
+ if (ec || length == 0) {
+ scheduleRead();
+ return;
+ }
+ // OK, we have a real packet of data. Let's dig into it!
+
+ // XXX: This is taken (and ported) from UDPSocket class. What the hell does
+ // it really mean?
+
+ // The UDP socket class has been extended with asynchronous functions
+ // and takes as a template parameter a completion callback class. As
+ // UDPServer does not use these extended functions (only those defined
+ // in the IOSocket base class) - but needs a UDPSocket to get hold of
+ // the underlying Boost UDP socket - DummyIOCallback is used. This
+ // provides the appropriate operator() but is otherwise functionless.
+ UDPSocket<DummyIOCallback> socket(*socket_);
+ UDPEndpoint endpoint(sender_);
+ IOMessage message(data_, length, socket, endpoint);
+ if (checkin_callback_ != NULL) {
+ (*checkin_callback_)(message);
+ if (stopped_) {
+ return;
+ }
+ }
+
+ // If we don't have a DNS Lookup provider, there's no point in
+ // continuing; we exit the coroutine permanently.
+ if (lookup_callback_ == NULL) {
+ scheduleRead();
+ return;
+ }
+
+ // Make sure the buffers are fresh
+ output_buffer_->clear();
+ query_->clear(isc::dns::Message::PARSE);
+ answer_->clear(isc::dns::Message::RENDER);
+
+ // Mark that we don't have an answer yet.
+ done_ = false;
+ resume_called_ = false;
+
+ // Call the actual lookup
+ (*lookup_callback_)(message, query_, answer_, output_buffer_, this);
+
+ if (!resume_called_) {
+ isc_throw(isc::Unexpected,
+ "No resume called from the lookup callback");
+ }
+
+ if (stopped_) {
+ return;
+ }
+
+ if (done_) {
+ // Good, there's an answer.
+ // Call the answer callback to render it.
+ (*answer_callback_)(message, query_, answer_, output_buffer_);
+
+ if (stopped_) {
+ return;
+ }
+
+ socket_->send_to(asio::buffer(output_buffer_->getData(),
+ output_buffer_->getLength()),
+ sender_);
+ }
+
+ // And schedule handling another socket.
+ scheduleRead();
+}
+
+void
+SyncUDPServer::operator()(asio::error_code, size_t) {
+ // To start the server, we just schedule reading of data when they
+ // arrive.
+ scheduleRead();
+}
+
+/// Stop the UDPServer
+void
+SyncUDPServer::stop() {
+ /// Using close instead of cancel, because cancel
+ /// will only cancel the asynchornized event already submitted
+ /// to io service, the events post to io service after
+ /// cancel still can be scheduled by io service, if
+ /// the socket is cloesed, all the asynchronized event
+ /// for it won't be scheduled by io service not matter it is
+ /// submit to io serice before or after close call. And we will
+ //. get bad_descriptor error
+ socket_->close();
+ stopped_ = true;
+}
+
+/// Post this coroutine on the ASIO service queue so that it will
+/// resume processing where it left off. The 'done' parameter indicates
+/// whether there is an answer to return to the client.
+void
+SyncUDPServer::resume(const bool done) {
+ resume_called_ = true;
+ done_ = done;
+}
+
+bool
+SyncUDPServer::hasAnswer() {
+ return (done_);
+}
+
+} // namespace asiodns
+} // namespace isc
diff --git a/src/lib/asiodns/sync_udp_server.h b/src/lib/asiodns/sync_udp_server.h
new file mode 100644
index 0000000..85a9e37
--- /dev/null
+++ b/src/lib/asiodns/sync_udp_server.h
@@ -0,0 +1,159 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __SYNC_UDP_SERVER_H
+#define __SYNC_UDP_SERVER_H 1
+
+#ifndef ASIO_HPP
+#error "asio.hpp must be included before including this, see asiolink.h as to why"
+#endif
+
+#include "dns_answer.h"
+#include "dns_lookup.h"
+#include "dns_server.h"
+
+#include <dns/message.h>
+#include <asiolink/simple_callback.h>
+#include <util/buffer.h>
+#include <exceptions.h>
+
+#include <boost/noncopyable.hpp>
+
+namespace isc {
+namespace asiodns {
+
+/// \brief An UDP server that doesn't asynchronous lookup handlers.
+///
+/// That means, the lookup handler must provide the answer right away.
+/// This allows for implementation with less overhead, compared with
+/// the UDPClass.
+class SyncUDPServer : public DNSServer, public boost::noncopyable {
+public:
+ /// \brief Constructor
+ /// \param io_service the asio::io_service to work with
+ /// \param addr the IP address to listen for queries on
+ /// \param port the port to listen for queries on
+ /// \param checkin the callbackprovider for non-DNS events
+ /// \param lookup the callbackprovider for DNS lookup events
+ /// \param answer the callbackprovider for DNS answer events
+ explicit SyncUDPServer(asio::io_service& io_service,
+ const asio::ip::address& addr, const uint16_t port,
+ isc::asiolink::SimpleCallback* checkin = NULL,
+ DNSLookup* lookup = NULL,
+ DNSAnswer* answer = NULL);
+
+ /// \brief Constructor
+ /// \param io_service the asio::io_service to work with
+ /// \param fd the file descriptor of opened UDP socket
+ /// \param af address family, either AF_INET or AF_INET6
+ /// \param checkin the callbackprovider for non-DNS events
+ /// \param lookup the callbackprovider for DNS lookup events
+ /// \param answer the callbackprovider for DNS answer events
+ /// \throw isc::InvalidParameter if af is neither AF_INET nor AF_INET6
+ /// \throw isc::asiolink::IOError when a low-level error happens, like the
+ /// fd is not a valid descriptor.
+ SyncUDPServer(asio::io_service& io_service, const int fd, const int af,
+ isc::asiolink::SimpleCallback* checkin = NULL,
+ DNSLookup* lookup = NULL, DNSAnswer* answer = NULL);
+
+ /// \brief Start the SyncUDPServer.
+ ///
+ /// This is the function operator to keep interface with other server
+ /// classes. They need that because they're coroutines.
+ virtual void operator()(asio::error_code ec = asio::error_code(),
+ size_t length = 0);
+
+ /// \brief Calls the lookup callback
+ virtual void asyncLookup() {
+ isc_throw(Unexpected,
+ "SyncUDPServer doesn't support asyncLookup by design, use "
+ "UDPServer if you need it.");
+ }
+
+ /// \brief Stop the running server
+ /// \note once the server stopped, it can't restart
+ virtual void stop();
+
+ /// \brief Resume operation
+ ///
+ /// Note that unlike other servers, this one expects it to be called
+ /// directly from the lookup callback. If it isn't, the server will
+ /// throw an Unexpected exception (probably to the event loop, which
+ /// would usually lead to termination of the program, but that's OK,
+ /// as it would be serious programmer error).
+ ///
+ /// \param done Set this to true if the lookup action is done and
+ /// we have an answer
+ virtual void resume(const bool done);
+
+ /// \brief Check if we have an answer
+ ///
+ /// \return true if we have an answer
+ virtual bool hasAnswer();
+
+ /// \brief Clones the object
+ ///
+ /// Since cloning is for the use of coroutines, the synchronous UDP server
+ /// does not need to be cloned. Therefore supporting it would be needless
+ /// work, and trying to clone it would be a programmer error anyway, this
+ /// throws Unexpected.
+ ///
+ /// \return a newly allocated copy of this object
+ virtual DNSServer* clone() {
+ isc_throw(Unexpected, "SyncUDPServer can't be cloned.");
+ }
+private:
+ // Internal state & buffers. We don't use the PIMPL idiom, as this class
+ // isn't usually used directly anyway.
+
+ // Maximum size of incoming UDP packet
+ static const size_t MAX_LENGTH = 4096;
+ // Buffer for incoming data
+ uint8_t data_[MAX_LENGTH];
+ // The buffer to render the output to and send it.
+ // If it was OK to have just a buffer, not the wrapper class,
+ // we could reuse the data_
+ isc::util::OutputBufferPtr output_buffer_;
+ // Objects to hold the query message and the answer
+ isc::dns::MessagePtr query_, answer_;
+ // The socket used for the communication
+ std::auto_ptr<asio::ip::udp::socket> socket_;
+ // The event loop we use
+ asio::io_service& io_;
+ // Place the socket puts the sender of a packet when it is received
+ asio::ip::udp::endpoint sender_;
+ // Callbacks
+ const asiolink::SimpleCallback* checkin_callback_;
+ const DNSLookup* lookup_callback_;
+ const DNSAnswer* answer_callback_;
+ // Answers from the lookup callback (not sent directly, but signalled
+ // through resume()
+ bool resume_called_, done_;
+ // This turns true when the server stops. Allows for not sending the
+ // answer after we closed the socket.
+ bool stopped_;
+
+ // Auxiliary functions
+
+ // Schedule next read on the socket. Just a wrapper around
+ // socket_->async_read_from with the correct parameters.
+ void scheduleRead();
+ // Callback from the socket's read call (called when there's an error or
+ // when a new packet comes).
+ void handleRead(const asio::error_code& ec, const size_t length);
+};
+
+} // namespace asiodns
+} // namespace isc
+#endif // __SYNC_UDP_SERVER_H
diff --git a/src/lib/asiodns/tcp_server.h b/src/lib/asiodns/tcp_server.h
index d079e97..a75fddb 100644
--- a/src/lib/asiodns/tcp_server.h
+++ b/src/lib/asiodns/tcp_server.h
@@ -62,9 +62,6 @@ public:
void asyncLookup();
void stop();
void resume(const bool done);
- bool hasAnswer() { return (done_); }
- int value() { return (get_value()); }
-
DNSServer* clone() {
TCPServer* s = new TCPServer(*this);
return (s);
diff --git a/src/lib/asiodns/tests/dns_server_unittest.cc b/src/lib/asiodns/tests/dns_server_unittest.cc
index c9bbe7c..0064bba 100644
--- a/src/lib/asiodns/tests/dns_server_unittest.cc
+++ b/src/lib/asiodns/tests/dns_server_unittest.cc
@@ -19,6 +19,7 @@
#include <asiolink/io_endpoint.h>
#include <asiolink/io_error.h>
#include <asiodns/udp_server.h>
+#include <asiodns/sync_udp_server.h>
#include <asiodns/tcp_server.h>
#include <asiodns/dns_answer.h>
#include <asiodns/dns_lookup.h>
@@ -112,15 +113,22 @@ class DummyChecker : public SimpleCallback, public ServerStopper {
// \brief no lookup logic at all,just provide a checkpoint to stop the server
class DummyLookup : public DNSLookup, public ServerStopper {
- public:
- void operator()(const IOMessage& io_message,
- isc::dns::MessagePtr message,
- isc::dns::MessagePtr answer_message,
- isc::util::OutputBufferPtr buffer,
- DNSServer* server) const {
- stopServer();
+public:
+ DummyLookup() :
+ allow_resume_(true)
+ { }
+ void operator()(const IOMessage& io_message,
+ isc::dns::MessagePtr message,
+ isc::dns::MessagePtr answer_message,
+ isc::util::OutputBufferPtr buffer,
+ DNSServer* server) const {
+ stopServer();
+ if (allow_resume_) {
server->resume(true);
}
+ }
+ // If you want it not to call resume, set this to false
+ bool allow_resume_;
};
// \brief copy the data received from user to the answer part
@@ -314,10 +322,11 @@ class TCPClient : public SimpleClient {
// two servers, UDP client will only communicate with UDP server, same for TCP
// client
//
-// This is only the active part of the test. We run the test case twice, once
+// This is only the active part of the test. We run the test case four times, once
// for each type of initialization (once when giving it the address and port,
-// once when giving the file descriptor), to ensure it works both ways exactly
-// the same.
+// once when giving the file descriptor) multiplied by once for each type of UDP
+// server (UDPServer and SyncUDPServer), to ensure it works exactly the same.
+template<class UDPServerClass>
class DNSServerTestBase : public::testing::Test {
protected:
DNSServerTestBase() :
@@ -396,7 +405,7 @@ class DNSServerTestBase : public::testing::Test {
SimpleAnswer* const answer_;
UDPClient* const udp_client_;
TCPClient* const tcp_client_;
- UDPServer* udp_server_;
+ UDPServerClass* udp_server_;
TCPServer* tcp_server_;
// To access them in signal handle function, the following
@@ -406,18 +415,23 @@ class DNSServerTestBase : public::testing::Test {
};
// Initialization with name and port
-class AddrPortInit : public DNSServerTestBase {
+template<class UDPServerClass>
+class AddrPortInit : public DNSServerTestBase<UDPServerClass> {
protected:
AddrPortInit() {
- udp_server_ = new UDPServer(service, server_address_, server_port,
- checker_, lookup_, answer_);
- tcp_server_ = new TCPServer(service, server_address_, server_port,
- checker_, lookup_, answer_);
+ this->udp_server_ = new UDPServerClass(this->service,
+ this->server_address_,
+ server_port, this->checker_,
+ this->lookup_, this->answer_);
+ this->tcp_server_ = new TCPServer(this->service, this->server_address_,
+ server_port, this->checker_,
+ this->lookup_, this->answer_);
}
};
// Initialization by the file descriptor
-class FdInit : public DNSServerTestBase {
+template<class UDPServerClass>
+class FdInit : public DNSServerTestBase<UDPServerClass> {
private:
// Opens the file descriptor for us
// It uses the low-level C api, as it seems to be the easiest way to get
@@ -465,12 +479,14 @@ protected:
void SetUp() {
const int fdUDP(getFd(SOCK_DGRAM));
ASSERT_NE(-1, fdUDP) << strerror(errno);
- udp_server_ = new UDPServer(service, fdUDP, AF_INET6, checker_,
- lookup_, answer_);
+ this->udp_server_ = new UDPServerClass(this->service, fdUDP, AF_INET6,
+ this->checker_, this->lookup_,
+ this->answer_);
const int fdTCP(getFd(SOCK_STREAM));
ASSERT_NE(-1, fdTCP) << strerror(errno);
- tcp_server_ = new TCPServer(service, fdTCP, AF_INET6, checker_,
- lookup_, answer_);
+ this->tcp_server_ = new TCPServer(this->service, fdTCP, AF_INET6,
+ this->checker_, this->lookup_,
+ this->answer_);
}
};
@@ -478,11 +494,24 @@ protected:
template<class Parent>
class DNSServerTest : public Parent { };
-typedef ::testing::Types<AddrPortInit, FdInit> ServerTypes;
+typedef ::testing::Types<AddrPortInit<UDPServer>, AddrPortInit<SyncUDPServer>,
+ FdInit<UDPServer>, FdInit<SyncUDPServer> >
+ ServerTypes;
TYPED_TEST_CASE(DNSServerTest, ServerTypes);
-bool DNSServerTestBase::io_service_is_time_out = false;
-asio::io_service* DNSServerTestBase::current_service(NULL);
+typedef ::testing::Types<UDPServer, SyncUDPServer> UDPServerTypes;
+TYPED_TEST_CASE(DNSServerTestBase, UDPServerTypes);
+
+template<class UDPServerClass>
+bool DNSServerTestBase<UDPServerClass>::io_service_is_time_out = false;
+template<class UDPServerClass>
+asio::io_service* DNSServerTestBase<UDPServerClass>::current_service(NULL);
+
+typedef ::testing::Types<AddrPortInit<SyncUDPServer>, FdInit<SyncUDPServer> >
+ SyncTypes;
+template<class Parent>
+class SyncServerTest : public Parent { };
+TYPED_TEST_CASE(SyncServerTest, SyncTypes);
// Test whether server stopped successfully after client get response
// client will send query and start to wait for response, once client
@@ -608,17 +637,20 @@ TYPED_TEST(DNSServerTest, stopTCPServeMoreThanOnce) {
}
// It raises an exception when invalid address family is passed
-TEST_F(DNSServerTestBase, invalidFamily) {
+// The parameter here doesn't mean anything
+TYPED_TEST(DNSServerTestBase, invalidFamily) {
// We abuse DNSServerTestBase for this test, as we don't need the
// initialization.
- EXPECT_THROW(UDPServer(service, 0, AF_UNIX, checker_, lookup_,
- answer_), isc::InvalidParameter);
- EXPECT_THROW(TCPServer(service, 0, AF_UNIX, checker_, lookup_,
- answer_), isc::InvalidParameter);
+ EXPECT_THROW(TypeParam(this->service, 0, AF_UNIX, this->checker_,
+ this->lookup_, this->answer_),
+ isc::InvalidParameter);
+ EXPECT_THROW(TCPServer(this->service, 0, AF_UNIX, this->checker_,
+ this->lookup_, this->answer_),
+ isc::InvalidParameter);
}
// It raises an exception when invalid address family is passed
-TEST_F(DNSServerTestBase, invalidTCPFD) {
+TYPED_TEST(DNSServerTestBase, invalidTCPFD) {
// We abuse DNSServerTestBase for this test, as we don't need the
// initialization.
/*
@@ -630,11 +662,12 @@ TEST_F(DNSServerTestBase, invalidTCPFD) {
EXPECT_THROW(UDPServer(service, -1, AF_INET, checker_, lookup_,
answer_), isc::asiolink::IOError);
*/
- EXPECT_THROW(TCPServer(service, -1, AF_INET, checker_, lookup_,
- answer_), isc::asiolink::IOError);
+ EXPECT_THROW(TCPServer(this->service, -1, AF_INET, this->checker_,
+ this->lookup_, this->answer_),
+ isc::asiolink::IOError);
}
-TEST_F(DNSServerTestBase, DISABLED_invalidUDPFD) {
+TYPED_TEST(DNSServerTestBase, DISABLED_invalidUDPFD) {
/*
FIXME: The UDP server doesn't fail reliably with an invalid FD.
We need to find a way to trigger it reliably (it seems epoll
@@ -642,8 +675,24 @@ TEST_F(DNSServerTestBase, DISABLED_invalidUDPFD) {
not the others, maybe we could make it run this at least on epoll-based
systems).
*/
- EXPECT_THROW(UDPServer(service, -1, AF_INET, checker_, lookup_,
- answer_), isc::asiolink::IOError);
+ EXPECT_THROW(TypeParam(this->service, -1, AF_INET, this->checker_,
+ this->lookup_, this->answer_),
+ isc::asiolink::IOError);
+}
+
+// Check it rejects some of the unsupported operatirons
+TYPED_TEST(SyncServerTest, unsupportedOps) {
+ EXPECT_THROW(this->udp_server_->clone(), isc::Unexpected);
+ EXPECT_THROW(this->udp_server_->asyncLookup(), isc::Unexpected);
+}
+
+// Check it rejects forgotten resume (eg. insists that it is synchronous)
+TYPED_TEST(SyncServerTest, mustResume) {
+ this->lookup_->allow_resume_ = false;
+ ASSERT_THROW(this->testStopServerByStopper(this->udp_server_,
+ this->udp_client_,
+ this->lookup_),
+ isc::Unexpected);
}
}
diff --git a/src/lib/asiodns/udp_server.cc b/src/lib/asiodns/udp_server.cc
index 820db4c..990949e 100644
--- a/src/lib/asiodns/udp_server.cc
+++ b/src/lib/asiodns/udp_server.cc
@@ -343,10 +343,5 @@ UDPServer::resume(const bool done) {
data_->io_.post(*this);
}
-bool
-UDPServer::hasAnswer() {
- return (data_->done_);
-}
-
} // namespace asiodns
} // namespace isc
diff --git a/src/lib/asiodns/udp_server.h b/src/lib/asiodns/udp_server.h
index c82b78c..2b6a574 100644
--- a/src/lib/asiodns/udp_server.h
+++ b/src/lib/asiodns/udp_server.h
@@ -83,16 +83,6 @@ public:
/// we have an answer
void resume(const bool done);
- /// \brief Check if we have an answer
- ///
- /// \return true if we have an answer
- bool hasAnswer();
-
- /// \brief Returns the coroutine state value
- ///
- /// \return the coroutine state value
- int value() { return (get_value()); }
-
/// \brief Clones the object
///
/// \return a newly allocated copy of this object
More information about the bind10-changes
mailing list