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) :
/// 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
/// The following functions implement the \c TCPServer class.
///
/// The constructor
-TCPServer::TCPServer(io_service& io_service,
- const ip::address& addr, const uint16_t port,
- const SimpleCallback* checkin,
- const DNSLookup* lookup,
- const DNSAnswer* answer) :
- io_(io_service), done_(false),
- checkin_callback_(checkin), lookup_callback_(lookup),
- answer_callback_(answer)
-{
- tcp::endpoint endpoint(addr, port);
- acceptor_.reset(new tcp::acceptor(io_service));
- acceptor_->open(endpoint.protocol());
- // Set v6-only (we use a separate instantiation for v4,
- // otherwise asio will bind to both v4 and v6
- if (addr.is_v6()) {
- acceptor_->set_option(ip::v6_only(true));
- }
- acceptor_->set_option(tcp::acceptor::reuse_address(true));
- acceptor_->bind(endpoint);
- acceptor_->listen();
-}
-
TCPServer::TCPServer(io_service& io_service, int fd, int af,
const SimpleCallback* checkin,
const DNSLookup* lookup,
/// defined in coroutine.h.
class TCPServer : public virtual DNSServer, public virtual coroutine {
public:
- explicit TCPServer(asio::io_service& io_service,
- const asio::ip::address& addr, const uint16_t port,
- const isc::asiolink::SimpleCallback* checkin = NULL,
- const DNSLookup* lookup = NULL,
- const DNSAnswer* answer = NULL);
-
/// \brief Constructor
/// \param io_service the asio::io_service to work with
/// \param fd the file descriptor of opened TCP socket
static bool io_service_is_time_out;
};
-// Initialization with name and port
-template<class UDPServerClass>
-class AddrPortInit : public DNSServerTestBase<UDPServerClass> {
-protected:
- AddrPortInit() {
- 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
+// Initialization (by the file descriptor)
template<class UDPServerClass>
class FdInit : public DNSServerTestBase<UDPServerClass> {
private:
template<class Parent>
class DNSServerTest : public Parent { };
-typedef ::testing::Types<AddrPortInit<UDPServer>, AddrPortInit<SyncUDPServer>,
- FdInit<UDPServer>, FdInit<SyncUDPServer> >
+typedef ::testing::Types<FdInit<UDPServer>, FdInit<SyncUDPServer> >
ServerTypes;
TYPED_TEST_CASE(DNSServerTest, ServerTypes);
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
// get response, udp server will be stopped, the io service won't quit
EXPECT_TRUE(this->serverStopSucceed());
}
-static void stopServerManyTimes(DNSServer *server, unsigned int times) {
+void
+stopServerManyTimes(DNSServer *server, unsigned int times) {
for (unsigned int i = 0; i < times; ++i) {
server->stop();
}
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);
+// A specialized test type for SyncUDPServer.
+typedef FdInit<SyncUDPServer> SyncServerTest;
+
+// Check it rejects some of the unsupported operations
+TEST_F(SyncServerTest, unsupportedOps) {
+ EXPECT_THROW(udp_server_->clone(), isc::Unexpected);
+ EXPECT_THROW(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_),
+TEST_F(SyncServerTest, mustResume) {
+ lookup_->allow_resume_ = false;
+ ASSERT_THROW(testStopServerByStopper(udp_server_, udp_client_, lookup_),
isc::Unexpected);
}
///
/// The constructor. It just creates new internal state object
/// and lets it handle the initialization.
-UDPServer::UDPServer(io_service& io_service, const ip::address& addr,
- const uint16_t port, SimpleCallback* checkin,
- DNSLookup* lookup, DNSAnswer* answer) :
- data_(new Data(io_service, addr, port, checkin, lookup, answer))
-{ }
-
UDPServer::UDPServer(io_service& io_service, int fd, int af,
SimpleCallback* checkin, DNSLookup* lookup,
DNSAnswer* answer) :
///
class UDPServer : public virtual DNSServer, public virtual coroutine {
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 UDPServer(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