Browse Source

[4029] Removed unused files (tentative)

Francis Dupont 9 years ago
parent
commit
d45798e087

+ 1 - 12
src/lib/asiodns/Makefile.am

@@ -2,9 +2,6 @@ SUBDIRS = . tests
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += $(BOOST_INCLUDES)
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/asiolink -I$(top_builddir)/src/lib/asiolink
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/util -I$(top_builddir)/src/lib/util
 
 AM_CXXFLAGS = $(KEA_CXXFLAGS)
 
@@ -20,15 +17,7 @@ s-messages: asiodns_messages.mes
 BUILT_SOURCES = asiodns_messages.h asiodns_messages.cc
 
 lib_LTLIBRARIES = libkea-asiodns.la
-libkea_asiodns_la_SOURCES = dns_answer.h
-libkea_asiodns_la_SOURCES += asiodns.h
-libkea_asiodns_la_SOURCES += dns_lookup.h
-libkea_asiodns_la_SOURCES += dns_server.h
-libkea_asiodns_la_SOURCES += dns_service.cc dns_service.h
-libkea_asiodns_la_SOURCES += tcp_server.cc tcp_server.h
-libkea_asiodns_la_SOURCES += udp_server.cc udp_server.h
-libkea_asiodns_la_SOURCES += sync_udp_server.cc sync_udp_server.h
-libkea_asiodns_la_SOURCES += io_fetch.cc io_fetch.h
+libkea_asiodns_la_SOURCES = io_fetch.cc io_fetch.h
 libkea_asiodns_la_SOURCES += logger.h logger.cc
 
 nodist_libkea_asiodns_la_SOURCES = asiodns_messages.cc asiodns_messages.h

+ 0 - 23
src/lib/asiodns/asiodns.h

@@ -1,23 +0,0 @@
-// Copyright (C) 2011  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 ASIODNS_H
-#define ASIODNS_H 1
-
-#include <asiodns/dns_service.h>
-#include <asiodns/dns_server.h>
-#include <asiodns/dns_lookup.h>
-#include <asiodns/dns_answer.h>
-
-#endif // ASIODNS_H

+ 0 - 77
src/lib/asiodns/dns_answer.h

@@ -1,77 +0,0 @@
-// Copyright (C) 2011  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 ASIOLINK_DNS_ANSWER_H
-#define ASIOLINK_DNS_ANSWER_H 1
-
-#include <asiolink/io_message.h>
-#include <util/buffer.h>
-#include <dns/message.h>
-
-namespace isc {
-namespace asiodns {
-
-/// \brief The \c DNSAnswer class is an abstract base class for a DNS
-/// Answer provider function.
-///
-/// Specific derived class implementations are hidden within the
-/// implementation.  Instances of the derived classes can be called
-/// as functions via the operator() interface.  Pointers to these
-/// instances can then be provided to the \c IOService class
-/// via its constructor.
-///
-/// A DNS Answer provider function takes answer data that has been obtained
-/// from a DNS Lookup provider function and readies it to be sent to the
-/// client.  After it has run, the OutputBuffer object passed to it should
-/// contain the answer to the query rendered into wire format.
-class DNSAnswer {
-    ///
-    /// \name Constructors and Destructor
-    ///
-    /// Note: The copy constructor and the assignment operator are
-    /// intentionally defined as private, making this class non-copyable.
-    //@{
-private:
-    DNSAnswer(const DNSAnswer& source);
-    DNSAnswer& operator=(const DNSAnswer& source);
-protected:
-    /// \brief The default constructor.
-    ///
-    /// This is intentionally defined as \c protected as this base class
-    /// should never be instantiated (except as part of a derived class).
-    DNSAnswer() {}
-public:
-    /// \brief The destructor
-    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 query_message The DNS MessagePtr of the original query
-    /// \param answer_message The DNS MessagePtr of the answer we are
-    /// building
-    /// \param buffer Intermediate data results are put here
-    virtual void operator()(const asiolink::IOMessage& io_message,
-                            isc::dns::MessagePtr query_message,
-                            isc::dns::MessagePtr answer_message,
-                            isc::util::OutputBufferPtr buffer) const = 0;
-};
-
-}      // namespace asiodns
-}      // namespace isc
-#endif // ASIOLINK_DNS_ANSWER_H

+ 0 - 87
src/lib/asiodns/dns_lookup.h

@@ -1,87 +0,0 @@
-// Copyright (C) 2011  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 ASIOLINK_DNS_LOOKUP_H
-#define ASIOLINK_DNS_LOOKUP_H 1
-
-#include <asiolink/io_message.h>
-#include <asiodns/dns_server.h>
-#include <dns/message.h>
-#include <util/buffer.h>
-
-namespace isc {
-namespace asiodns {
-
-/// \brief The \c DNSLookup class is an abstract base class for a DNS
-/// Lookup provider function.
-///
-/// Specific derived class implementations are hidden within the
-/// implementation.  Instances of the derived classes can be called
-/// as functions via the operator() interface.  Pointers to these
-/// instances can then be provided to the \c IOService class
-/// via its constructor.
-///
-/// A DNS Lookup provider function obtains the data needed to answer
-/// a DNS query (e.g., from authoritative data source, cache, or upstream
-/// query).  After it has run, the OutputBuffer object passed to it
-/// should contain the answer to the query, in an internal representation.
-class DNSLookup {
-    ///
-    /// \name Constructors and Destructor
-    ///
-    /// Note: The copy constructor and the assignment operator are
-    /// intentionally defined as private, making this class non-copyable.
-    //@{
-private:
-    DNSLookup(const DNSLookup& source);
-    DNSLookup& operator=(const DNSLookup& source);
-protected:
-    /// \brief The default constructor.
-    ///
-    /// This is intentionally defined as \c protected as this base class
-    /// should never be instantiated (except as part of a derived class).
-    DNSLookup() {
-        self_ = this;
-    }
-public:
-    /// \brief The destructor
-    virtual ~DNSLookup() {}
-    //@}
-    /// \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 answer_message The final answer will be constructed in
-    ///                       this MessagePtr
-    /// \param buffer The final answer is put here
-    /// \param server DNSServer object to use
-    virtual void operator()(const asiolink::IOMessage& io_message,
-                            isc::dns::MessagePtr message,
-                            isc::dns::MessagePtr answer_message,
-                            isc::util::OutputBufferPtr buffer,
-                            DNSServer* server) const
-    {
-        (*self_)(io_message, message, answer_message, buffer, server);
-    }
-private:
-    DNSLookup* self_;
-};
-
-}      // namespace asiodns
-}      // namespace isc
-#endif // ASIOLINK_DNS_LOOKUP_H

+ 0 - 155
src/lib/asiodns/dns_server.h

@@ -1,155 +0,0 @@
-// Copyright (C) 2011  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 ASIOLINK_DNS_SERVER_H
-#define ASIOLINK_DNS_SERVER_H 1
-
-#include <asiolink/io_message.h>
-
-namespace isc {
-namespace asiodns {
-
-/// \brief The \c DNSServer class is a wrapper (and base class) for
-/// classes which provide DNS server functionality.
-///
-/// The classes derived from this one, \c TCPServer and \c UDPServer,
-/// act as the interface layer between clients sending queries, and
-/// functions defined elsewhere that provide answers to those queries.
-/// Those functions are described in more detail below under
-/// \c SimpleCallback, \c DNSLookup, and \c DNSAnswer.
-///
-/// Notes to developers:
-/// When constructed, this class (and its derived classes) will have its
-/// "self_" member set to point to "this".  Objects of this class (as
-/// instantiated through a base class) are sometimes passed by
-/// reference (as this superclass); calls to methods in the base
-/// class are then rerouted via this pointer to methods in the derived
-/// class.  This allows code from outside asiodns, with no specific
-/// knowledge of \c TCPServer or \c UDPServer, to access their methods.
-///
-/// This class is both assignable and copy-constructable.  Its subclasses
-/// use the "stackless coroutine" pattern, meaning that it will copy itself
-/// when "forking", and that instances will be posted as ASIO handler
-/// objects, which are always copied.
-///
-/// Because these objects are frequently copied, it is recommended
-/// that derived classes be kept small to reduce copy overhead.
-class DNSServer {
-protected:
-    ///
-    /// \name Constructors and destructors
-    ///
-    /// This is intentionally defined as \c protected, as this base class
-    /// should never be instantiated except as part of a derived class.
-    //@{
-    DNSServer() {
-        self_ = this;
-    }
-public:
-    /// \brief The destructor
-    virtual ~DNSServer() {}
-    //@}
-
-    ///
-    /// \name Class methods
-    ///
-    /// These methods all make their calls indirectly via the "self_"
-    /// pointer, ensuring that the functions ultimately invoked will be
-    /// the ones in the derived class.  This makes it possible to pass
-    /// instances of derived classes as references to this base class
-    /// without losing access to derived class data.
-    ///
-    //@{
-    /// \brief The function operator
-    virtual void operator()(asio::error_code ec = asio::error_code(),
-                            size_t length = 0)
-    {
-        (*self_)(ec, length);
-    }
-
-    /// \brief Stop current running server
-    virtual void stop() { self_->stop();}
-
-    /// \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 void resume(const bool done) { self_->resume(done); }
-
-    /// \brief Returns a pointer to a clone of this DNSServer object.
-    ///
-    /// When a \c DNSServer object is copied or assigned, the result will
-    /// 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 DNSServer* clone() { return (self_->clone()); }
-    //@}
-
-    /// \brief Set timeout for incoming TCP connections
-    ///
-    /// Since this value is not relevant for every type of DNSServer
-    /// (like UDPServer), it has a no-op default implementation.
-    /// It is in the base class because the AuthSrv's DNSService has
-    /// no direct access to the derived API's after initialization,
-    /// and it does need to update running servers if the timeout
-    /// setting is changed.
-    ///
-    /// \param timeout The timeout in milliseconds
-    virtual void setTCPRecvTimeout(size_t) {}
-
-protected:
-    /// \brief Lookup handler object.
-    ///
-    /// This is a protected class; it can only be instantiated
-    /// from within a derived class of \c DNSServer.
-    ///
-    /// A server object that has received a query creates an instance
-    /// of this class and scheudles it on the ASIO service queue
-    /// using asio::io_service::post().  When the handler executes, it
-    /// calls the asyncLookup() method in the server object to start a
-    /// DNS lookup.  When the lookup is complete, the server object is
-    /// scheduled to resume, again using io_service::post().
-    ///
-    /// Note that the calling object is copied into the handler object,
-    /// not referenced.  This is because, once the calling object yields
-    /// control to the handler, it falls out of scope and may disappear
-    template <typename T>
-    class AsyncLookup {
-    public:
-        AsyncLookup(T& caller) : caller_(caller) {}
-        void operator()() { caller_.asyncLookup(); }
-    private:
-        T caller_;
-    };
-
-    /// \brief Carries out a DNS lookup.
-    ///
-    /// This function calls the \c DNSLookup object specified by the
-    /// DNS server when the \c IOService was created, passing along
-    /// the details of the query and a pointer back to the current
-    /// server object.  It is called asynchronously via the AsyncLookup
-    /// handler class.
-    virtual void asyncLookup() { self_->asyncLookup(); }
-
-private:
-    DNSServer* self_;
-};
-
-
-} // namespace asiodns
-} // namespace isc
-#endif // ASIOLINK_DNS_SERVER_H

+ 0 - 132
src/lib/asiodns/dns_service.cc

@@ -1,132 +0,0 @@
-// Copyright (C) 2011  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 <exceptions/exceptions.h>
-
-#include <dns_service.h>
-
-#include <asiolink/io_service.h>
-
-#include <asio.hpp> // xxx_server.h requires this to be included first
-#include <tcp_server.h>
-#include <udp_server.h>
-#include <sync_udp_server.h>
-
-#include <boost/foreach.hpp>
-
-using namespace isc::asiolink;
-
-namespace isc {
-namespace asiodns {
-
-class DNSLookup;
-class DNSAnswer;
-
-class DNSServiceImpl {
-public:
-    DNSServiceImpl(IOService& io_service,
-                   DNSLookup* lookup, DNSAnswer* answer) :
-            io_service_(io_service), lookup_(lookup),
-            answer_(answer), tcp_recv_timeout_(5000)
-    {}
-
-    IOService& io_service_;
-
-    typedef boost::shared_ptr<UDPServer> UDPServerPtr;
-    typedef boost::shared_ptr<SyncUDPServer> SyncUDPServerPtr;
-    typedef boost::shared_ptr<TCPServer> TCPServerPtr;
-    typedef boost::shared_ptr<DNSServer> DNSServerPtr;
-    std::vector<DNSServerPtr> servers_;
-    DNSLookup* lookup_;
-    DNSAnswer* answer_;
-    size_t tcp_recv_timeout_;
-
-    template<class Ptr, class Server> void addServerFromFD(int fd, int af) {
-        Ptr server(new Server(io_service_.get_io_service(), fd, af,
-                              lookup_, answer_));
-        startServer(server);
-    }
-
-    // SyncUDPServer has different constructor signature so it cannot be
-    // templated.
-    void addSyncUDPServerFromFD(int fd, int af) {
-        SyncUDPServerPtr server(SyncUDPServer::create(
-                                    io_service_.get_io_service(), fd, af,
-                                    lookup_));
-        startServer(server);
-    }
-
-    void setTCPRecvTimeout(size_t timeout) {
-        // Store it for future tcp connections
-        tcp_recv_timeout_ = timeout;
-        // Update existing (TCP) Servers
-        std::vector<DNSServerPtr>::iterator it = servers_.begin();
-        for (; it != servers_.end(); ++it) {
-            (*it)->setTCPRecvTimeout(timeout);
-        }
-    }
-
-private:
-    void startServer(DNSServerPtr server) {
-        server->setTCPRecvTimeout(tcp_recv_timeout_);
-        (*server)();
-        servers_.push_back(server);
-    }
-};
-
-DNSService::DNSService(IOService& io_service,
-                       DNSLookup* lookup, DNSAnswer *answer) :
-    impl_(new DNSServiceImpl(io_service, lookup, answer)),
-    io_service_(io_service)
-{
-}
-
-DNSService::~DNSService() {
-    delete impl_;
-}
-
-void DNSService::addServerTCPFromFD(int fd, int af) {
-    impl_->addServerFromFD<DNSServiceImpl::TCPServerPtr, TCPServer>(fd, af);
-}
-
-void DNSService::addServerUDPFromFD(int fd, int af, ServerFlag options) {
-    if ((~SERVER_DEFINED_FLAGS & static_cast<unsigned int>(options)) != 0) {
-        isc_throw(isc::InvalidParameter, "Invalid DNS/UDP server option: "
-                  << options);
-    }
-    if ((options & SERVER_SYNC_OK) != 0) {
-        impl_->addSyncUDPServerFromFD(fd, af);
-    } else {
-        impl_->addServerFromFD<DNSServiceImpl::UDPServerPtr, UDPServer>(
-            fd, af);
-    }
-}
-
-void
-DNSService::clearServers() {
-    BOOST_FOREACH(const DNSServiceImpl::DNSServerPtr& s, impl_->servers_) {
-        s->stop();
-    }
-    impl_->servers_.clear();
-}
-
-void
-DNSService::setTCPRecvTimeout(size_t timeout) {
-    impl_->setTCPRecvTimeout(timeout);
-}
-
-} // namespace asiodns
-} // namespace isc

+ 0 - 217
src/lib/asiodns/dns_service.h

@@ -1,217 +0,0 @@
-// Copyright (C) 2011  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 ASIOLINK_DNS_SERVICE_H
-#define ASIOLINK_DNS_SERVICE_H 1
-
-// The commented header occurs to be unused so we remove it to get
-// rid of dependency on resolver.
-// #include <resolve/resolver_interface.h>
-
-#include <asiolink/io_service.h>
-#include <asiolink/simple_callback.h>
-
-namespace isc {
-namespace asiodns {
-
-class DNSLookup;
-class DNSAnswer;
-class DNSServiceImpl;
-
-/// \brief A base class for common \c DNSService interfaces.
-///
-/// This class is defined mainly for test code so it can use a faked/mock
-/// version of a derived class and test scenarios that would involve
-/// \c DNSService without actually instantiating the real service class.
-///
-/// It doesn't intend to be a customization for other purposes - we generally
-/// expect non test code only use \c DNSService directly.
-/// For this reason most of the detailed description are given in the
-/// \c DNSService class.  See that for further details of specific methods
-/// and class behaviors.
-class DNSServiceBase {
-protected:
-    /// \brief Default constructor.
-    ///
-    /// This is protected so this class couldn't be accidentally instantiated
-    /// directly, even if there were no pure virtual functions.
-    DNSServiceBase() {}
-
-public:
-    /// \brief Flags for optional server properties.
-    ///
-    /// The values of this enumerable type are intended to be used to specify
-    /// a particular property of the server created via the \c addServer
-    /// variants.  As we see need for more such properties, a compound
-    /// form of flags (i.e., a single value generated by bitwise OR'ed
-    /// multiple flag values) will be allowed.
-    ///
-    /// Note: the description is given here because it's used in the method
-    /// signature.  It essentially belongs to the derived \c DNSService
-    /// class.
-    enum ServerFlag {
-        SERVER_DEFAULT = 0, ///< The default flag (no particular property)
-        SERVER_SYNC_OK = 1 ///< The server can act in the "synchronous" mode.
-                           ///< In this mode, the client ensures that the
-                           ///< lookup provider always completes the query
-                           ///< process and it immediately releases the
-                           ///< ownership of the given buffer.  This allows
-                           ///< the server implementation to introduce some
-                           ///< optimization such as omitting unnecessary
-                           ///< operation or reusing internal resources.
-                           ///< Note that in functionality the non
-                           ///< "synchronous" mode is compatible with the
-                           ///< synchronous mode; it's up to the server
-                           ///< implementation whether it exploits the
-                           ///< information given by the client.
-    };
-
-public:
-    /// \brief The destructor.
-    virtual ~DNSServiceBase() {}
-
-    virtual void addServerTCPFromFD(int fd, int af) = 0;
-    virtual void addServerUDPFromFD(int fd, int af,
-                                    ServerFlag options = SERVER_DEFAULT) = 0;
-    virtual void clearServers() = 0;
-
-    /// \brief Set the timeout for TCP DNS services
-    ///
-    /// The timeout is used for incoming TCP connections, so
-    /// that the connection is dropped if not all query data
-    /// is read.
-    ///
-    /// For existing DNSServer objects, where the timeout is
-    /// relevant (i.e. TCPServer instances), the timeout value
-    /// is updated.
-    /// The given value is also kept to use for DNSServer instances
-    /// which are created later
-    ///
-    /// \param timeout The timeout in milliseconds
-    virtual void setTCPRecvTimeout(size_t timeout) = 0;
-
-    virtual asiolink::IOService& getIOService() = 0;
-};
-
-/// \brief Handle DNS Queries
-///
-/// DNSService is the service that handles DNS queries and answers with
-/// a given IOService. This class is mainly intended to hold all the
-/// logic that is shared between the authoritative and the recursive
-/// server implementations. As such, it handles asio and listening
-/// sockets.
-class DNSService : public DNSServiceBase {
-    ///
-    /// \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);
-
-private:
-    // Bit or'ed all defined \c ServerFlag values.  Used internally for
-    // compatibility check.  Note that this doesn't have to be used by
-    // applications, and doesn't have to be defined in the "base" class.
-    static const unsigned int SERVER_DEFINED_FLAGS = 1;
-
-public:
-    /// \brief The constructor without any servers.
-    ///
-    /// Use addServerTCPFromFD() or addServerUDPFromFD() to add some servers.
-    ///
-    /// \param io_service The IOService to work with
-    /// \param lookup The lookup provider (see \c DNSLookup)
-    /// \param answer The answer provider (see \c DNSAnswer)
-    DNSService(asiolink::IOService& io_service,
-               DNSLookup* lookup, DNSAnswer* answer);
-
-    /// \brief The destructor.
-    virtual ~DNSService();
-    //@}
-
-    /// \brief Add another TCP server/listener to the service from already
-    /// opened file descriptor
-    ///
-    /// Adds a new TCP server using an already opened file descriptor (eg. it
-    /// only wraps it so the file descriptor is usable within the event loop).
-    /// The file descriptor must be associated with a TCP socket of the given
-    /// address family that is bound to an appropriate port (and possibly a
-    /// specific address) and is ready for listening to new connection
-    /// requests but has not actually started listening.
-    ///
-    /// At the moment, TCP servers don't support any optional properties;
-    /// so unlike the UDP version of the method it doesn't have an \c options
-    /// argument.
-    ///
-    /// \param fd the file descriptor to be used.
-    /// \param af the address family of the file descriptor. Must be either
-    ///     AF_INET or AF_INET6.
-    /// \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 or it can't be listened on.
-    virtual void addServerTCPFromFD(int fd, int af);
-
-    /// \brief Add another UDP server to the service from already opened
-    ///    file descriptor
-    ///
-    /// Adds a new UDP server using an already opened file descriptor (eg. it
-    /// only wraps it so the file descriptor is usable within the event loop).
-    /// The file descriptor must be associated with a UDP socket of the given
-    /// address family that is bound to an appropriate port (and possibly a
-    /// specific address).
-    ///
-    /// \param fd the file descriptor to be used.
-    /// \param af the address family of the file descriptor. Must be either
-    ///     AF_INET or AF_INET6.
-    /// \param options Optional properties of the server (see ServerFlag).
-    ///
-    /// \throw isc::InvalidParameter if af is neither AF_INET nor AF_INET6,
-    ///     or the given \c options include an unsupported or invalid value.
-    /// \throw isc::asiolink::IOError when a low-level error happens, like the
-    ///     fd is not a valid descriptor or it can't be listened on.
-    virtual void addServerUDPFromFD(int fd, int af,
-                                    ServerFlag options = SERVER_DEFAULT);
-
-    /// \brief Remove all servers from the service
-    void clearServers();
-
-    /// \brief Return the native \c io_service object used in this wrapper.
-    ///
-    /// This is a short term work around to support other Kea 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(); }
-
-    /// \brief Return the IO Service Object
-    ///
-    /// \return IOService object for this DNS service.
-    virtual asiolink::IOService& getIOService() { return (io_service_);}
-
-    virtual void setTCPRecvTimeout(size_t timeout);
-private:
-    DNSServiceImpl* impl_;
-    asiolink::IOService& io_service_;
-};
-
-} // namespace asiodns
-} // namespace isc
-#endif // ASIOLINK_DNS_SERVICE_H
-
-// Local Variables:
-// mode: c++
-// End:

+ 0 - 186
src/lib/asiodns/sync_udp_server.cc

@@ -1,186 +0,0 @@
-// 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 <cassert>
-
-#include <sys/types.h>
-#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 isc::asiolink;
-
-namespace isc {
-namespace asiodns {
-
-SyncUDPServerPtr
-SyncUDPServer::create(asio::io_service& io_service, const int fd,
-                      const int af, DNSLookup* lookup)
-{
-    return (SyncUDPServerPtr(new SyncUDPServer(io_service, fd, af, lookup)));
-}
-
-SyncUDPServer::SyncUDPServer(asio::io_service& io_service, const int fd,
-                             const int af, DNSLookup* lookup) :
-    output_buffer_(new isc::util::OutputBuffer(0)),
-    query_(new isc::dns::Message(isc::dns::Message::PARSE)),
-    udp_endpoint_(sender_), lookup_callback_(lookup),
-    resume_called_(false), done_(false), stopped_(false)
-{
-    if (af != AF_INET && af != AF_INET6) {
-        isc_throw(InvalidParameter, "Address family must be either AF_INET "
-                  "or AF_INET6, not " << af);
-    }
-    if (!lookup) {
-        isc_throw(InvalidParameter, "null lookup callback given to "
-                  "SyncUDPServer");
-    }
-    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());
-    }
-    udp_socket_.reset(new UDPSocket<DummyIOCallback>(*socket_));
-}
-
-void
-SyncUDPServer::scheduleRead() {
-    socket_->async_receive_from(
-        asio::mutable_buffers_1(data_, MAX_LENGTH), sender_,
-        boost::bind(&SyncUDPServer::handleRead, shared_from_this(), _1, _2));
-}
-
-void
-SyncUDPServer::handleRead(const asio::error_code& ec, const size_t length) {
-    if (stopped_) {
-        // stopped_ can be set to true only after the socket object is closed.
-        // checking this would also detect premature destruction of 'this'
-        // object.
-        assert(socket_ && !socket_->is_open());
-        return;
-    }
-    if (ec) {
-        using namespace asio::error;
-        const asio::error_code::value_type err_val = ec.value();
-
-        // See TCPServer::operator() for details on error handling.
-        if (err_val == operation_aborted || err_val == bad_descriptor) {
-            return;
-        }
-        if (err_val != would_block && err_val != try_again &&
-            err_val != interrupted) {
-            LOG_ERROR(logger, ASIODNS_UDP_SYNC_RECEIVE_FAIL).arg(ec.message());
-        }
-    }
-    if (ec || length == 0) {
-        scheduleRead();
-        return;
-    }
-    // OK, we have a real packet of data. Let's dig into it!
-
-    // Make sure the buffers are fresh.  Note that we don't touch query_
-    // because it's supposed to be cleared in lookup_callback_.  We should
-    // eventually even remove this member variable (and remove it from
-    // the lookup_callback_ interface, but until then, any callback
-    // implementation should be careful that it's the responsibility of
-    // the callback implementation.  See also #2239).
-    output_buffer_->clear();
-
-    // Mark that we don't have an answer yet.
-    done_ = false;
-    resume_called_ = false;
-
-    // Call the actual lookup
-    const IOMessage message(data_, length, *udp_socket_, udp_endpoint_);
-    (*lookup_callback_)(message, query_, answer_, output_buffer_, this);
-
-    if (!resume_called_) {
-        isc_throw(isc::Unexpected,
-                  "No resume called from the lookup callback");
-    }
-
-    if (done_) {
-        // Good, there's an answer.
-        socket_->send_to(asio::const_buffers_1(output_buffer_->getData(),
-                                               output_buffer_->getLength()),
-                         sender_, 0, ec_);
-        if (ec_) {
-            LOG_ERROR(logger, ASIODNS_UDP_SYNC_SEND_FAIL).
-                      arg(sender_.address().to_string()).arg(ec_.message());
-        }
-    }
-
-    // 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 asynchronized 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 closed, all the asynchronized event
-    /// for it won't be scheduled by io service not matter it is
-    /// submit to io service before or after close call. And we will
-    /// get bad_descriptor error.
-    socket_->close(ec_);
-    stopped_ = true;
-    if (ec_) {
-        LOG_ERROR(logger, ASIODNS_SYNC_UDP_CLOSE_FAIL).arg(ec_.message());
-    }
-}
-
-void
-SyncUDPServer::resume(const bool done) {
-    resume_called_ = true;
-    done_ = done;
-}
-
-bool
-SyncUDPServer::hasAnswer() {
-    return (done_);
-}
-
-} // namespace asiodns
-} // namespace isc

+ 0 - 196
src/lib/asiodns/sync_udp_server.h

@@ -1,196 +0,0 @@
-// 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 <asiolink/dummy_io_cb.h>
-#include <asiolink/udp_socket.h>
-#include <util/buffer.h>
-#include <exceptions/exceptions.h>
-
-#include <boost/function.hpp>
-#include <boost/noncopyable.hpp>
-#include <boost/scoped_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
-
-#include <stdint.h>
-
-namespace isc {
-namespace asiodns {
-
-class SyncUDPServer;
-typedef boost::shared_ptr<SyncUDPServer> SyncUDPServerPtr;
-
-/// \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 \c UDPServer class.
-///
-/// This class inherits from boost::enable_shared_from_this so a shared
-/// pointer of this object can be passed in an ASIO callback and won't be
-/// accidentally destroyed while waiting for events.  To enforce this style
-/// of creation, a static factory method is provided, and the constructor is
-/// hidden as a private.
-class SyncUDPServer : public DNSServer,
-                      public boost::enable_shared_from_this<SyncUDPServer>,
-                      boost::noncopyable
-{
-private:
-    /// \brief Constructor.
-    ///
-    /// This is hidden as private (see the class description).
-    SyncUDPServer(asio::io_service& io_service, const int fd, const int af,
-                  DNSLookup* lookup);
-
-public:
-    /// \brief Factory of SyncUDPServer object in the form of shared_ptr.
-    ///
-    /// Due to the nature of this server, it's meaningless if the lookup
-    /// callback is NULL.  So this method explicitly rejects that case
-    /// with an exception.  Likewise, it doesn't take "checkin" or "answer"
-    /// callbacks.  In fact, calling "checkin" from receive callback does not
-    /// make sense for any of the DNSServer variants (see Trac #2935);
-    /// "answer" callback is simply unnecessary for this class because a
-    /// complete answer is built in the lookup callback (it's the user's
-    /// responsibility to guarantee that condition).
-    ///
-    /// \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 lookup the callbackprovider for DNS lookup events (must not be
-    ///        NULL)
-    ///
-    /// \throw isc::InvalidParameter if af is neither AF_INET nor AF_INET6
-    /// \throw isc::InvalidParameter lookup is NULL
-    /// \throw isc::asiolink::IOError when a low-level error happens, like the
-    ///     fd is not a valid descriptor.
-    static SyncUDPServerPtr create(asio::io_service& io_service, const int fd,
-                                   const int af, DNSLookup* lookup);
-
-    /// \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.  The latter isn't
-    // used and only defined as a placeholder as the callback signature
-    // requires it.
-    isc::dns::MessagePtr query_, answer_;
-    // The socket used for the communication
-    boost::scoped_ptr<asio::ip::udp::socket> socket_;
-    // Wrapper of socket_ in the form of asiolink::IOSocket.
-    // "DummyIOCallback" is not necessary for this class, but using the
-    // template is the easiest way to create a UDP instance of IOSocket.
-    boost::scoped_ptr<asiolink::UDPSocket<asiolink::DummyIOCallback> >
-    udp_socket_;
-    // Place the socket puts the sender of a packet when it is received
-    asio::ip::udp::endpoint sender_;
-    // Wrapper of sender_ in the form of asiolink::IOEndpoint.  It's set to
-    // refer to sender_ on initialization, and keeps the reference throughout
-    // this server class.
-    asiolink::UDPEndpoint udp_endpoint_;
-    // Callback
-    const DNSLookup* lookup_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_;
-    // Placeholder for error code object.  It will be passed to ASIO library
-    // to have it set in case of error.
-    asio::error_code ec_;
-
-    // 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
-
-// Local Variables:
-// mode: c++
-// End:

+ 0 - 319
src/lib/asiodns/tcp_server.cc

@@ -1,319 +0,0 @@
-// Copyright (C) 2011  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 <util/buffer.h>
-
-#include <asio.hpp>
-#include <asiolink/dummy_io_cb.h>
-#include <asiolink/tcp_endpoint.h>
-#include <asiolink/tcp_socket.h>
-#include <asiodns/tcp_server.h>
-#include <asiodns/logger.h>
-
-#include <boost/shared_array.hpp>
-
-#include <cassert>
-#include <unistd.h>             // for some IPC/network system calls
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <errno.h>
-
-// Note: we intentionally avoid 'using namespace asio' to avoid conflicts with
-// std:: definitions in C++11.
-using asio::io_service;
-using asio::buffer;
-using asio::const_buffer;
-using asio::ip::tcp;
-
-using namespace std;
-using namespace isc::dns;
-using namespace isc::util;
-using namespace isc::asiolink;
-
-namespace isc {
-namespace asiodns {
-
-/// The following functions implement the \c TCPServer class.
-///
-/// The constructor
-TCPServer::TCPServer(io_service& io_service, int fd, int af,
-                     const DNSLookup* lookup,
-                     const DNSAnswer* answer) :
-    io_(io_service), done_(false),
-    lookup_callback_(lookup),
-    answer_callback_(answer)
-{
-    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_TCP).arg(fd);
-
-    try {
-        acceptor_.reset(new tcp::acceptor(io_service));
-        acceptor_->assign(af == AF_INET6 ? tcp::v6() : tcp::v4(), fd);
-        acceptor_->listen();
-    } catch (const std::exception& exception) {
-        // Whatever the thing throws, it is something from ASIO and we convert
-        // it
-        isc_throw(IOError, exception.what());
-    }
-    // Set it to some value. It should be set to the right one
-    // immediately, but set it to something non-zero just in case.
-    tcp_recv_timeout_.reset(new size_t(5000));
-}
-
-namespace {
-// Called by the timeout_ deadline timer if the client takes too long.
-// If not aborted, cancels the given socket
-// (in which case TCPServer::operator() will be called to continue,
-// with an 'aborted' error code.)
-void doTimeOut(boost::shared_ptr<asio::ip::tcp::socket> socket,
-               const asio::error_code& error)
-{
-    if (error != asio::error::operation_aborted) {
-        socket->cancel();
-    }
-}
-}
-
-void
-TCPServer::operator()(asio::error_code ec, size_t length) {
-    /// Because the coroutine reentry block is implemented as
-    /// a switch statement, inline variable declarations are not
-    /// permitted.  Certain variables used below can be declared here.
-
-    boost::array<const_buffer,2> bufs;
-    OutputBuffer lenbuf(TCP_MESSAGE_LENGTHSIZE);
-
-    CORO_REENTER (this) {
-        do {
-            /// Create a socket to listen for connections (no-throw operation)
-            socket_.reset(new tcp::socket(acceptor_->get_io_service()));
-
-            /// Wait for new connections. In the event of non-fatal error,
-            /// try again
-            do {
-                CORO_YIELD acceptor_->async_accept(*socket_, *this);
-                if (ec) {
-                    using namespace asio::error;
-                    const asio::error_code::value_type err_val = ec.value();
-                    // The following two cases can happen when this server is
-                    // stopped: operation_aborted in case it's stopped after
-                    // starting accept().  bad_descriptor in case it's stopped
-                    // even before starting.  In these cases we should simply
-                    // stop handling events.
-                    if (err_val == operation_aborted ||
-                        err_val == bad_descriptor) {
-                        return;
-                    }
-                    // Other errors should generally be temporary and we should
-                    // keep waiting for new connections.  We log errors that
-                    // should really be rare and would only be caused by an
-                    // internal erroneous condition (not an odd remote
-                    // behavior).
-                    if (err_val != would_block && err_val != try_again &&
-                        err_val != connection_aborted &&
-                        err_val != interrupted) {
-                        LOG_ERROR(logger, ASIODNS_TCP_ACCEPT_FAIL).
-                            arg(ec.message());
-                    }
-                }
-            } while (ec);
-
-            /// Fork the coroutine by creating a copy of this one and
-            /// scheduling it on the ASIO service queue.  The parent
-            /// will continue listening for DNS connections while the child
-            /// handles the one that has just arrived.
-            CORO_FORK io_.post(TCPServer(*this));
-        } while (is_parent());
-
-        // From this point, we'll simply return on error, which will
-        // immediately trigger destroying this object, cleaning up all
-        // resources including any open sockets.
-
-        /// Instantiate the data buffer that will be used by the
-        /// asynchronous read call.
-        data_.reset(new char[MAX_LENGTH]);
-
-        /// Start a timer to drop the connection if it is idle.  note that
-        // we pass a shared_ptr of the socket object so that it won't be
-        // destroyed at least until the timeout callback (including abort)
-        // is called.
-        if (*tcp_recv_timeout_ > 0) {
-            timeout_.reset(new asio::deadline_timer(io_)); // shouldn't throw
-            timeout_->expires_from_now( // consider any exception fatal.
-                boost::posix_time::milliseconds(*tcp_recv_timeout_));
-            timeout_->async_wait(boost::bind(&doTimeOut, socket_,
-                                             asio::placeholders::error));
-        }
-
-        /// Read the message, in two parts.  First, the message length:
-        CORO_YIELD async_read(*socket_, asio::buffer(data_.get(),
-                              TCP_MESSAGE_LENGTHSIZE), *this);
-        if (ec) {
-            LOG_DEBUG(logger, DBGLVL_TRACE_BASIC, ASIODNS_TCP_READLEN_FAIL).
-                arg(ec.message());
-            return;
-        }
-
-        /// Now read the message itself. (This is done in a different scope
-        /// to allow inline variable declarations.)
-        CORO_YIELD {
-            InputBuffer dnsbuffer(data_.get(), length);
-            const uint16_t msglen = dnsbuffer.readUint16();
-            async_read(*socket_, asio::buffer(data_.get(), msglen), *this);
-        }
-        if (ec) {
-            LOG_DEBUG(logger, DBGLVL_TRACE_BASIC, ASIODNS_TCP_READDATA_FAIL).
-                arg(ec.message());
-            return;
-        }
-
-        // Create an \c IOMessage object to store the query.
-        //
-        // (XXX: It would be good to write a factory function
-        // that would quickly generate an IOMessage object without
-        // all these calls to "new".)
-        peer_.reset(new TCPEndpoint(socket_->remote_endpoint(ec)));
-        if (ec) {
-            LOG_DEBUG(logger, DBGLVL_TRACE_BASIC, ASIODNS_TCP_GETREMOTE_FAIL).
-                arg(ec.message());
-            return;
-        }
-
-        // The TCP socket class has been extended with asynchronous functions
-        // and takes as a template parameter a completion callback class.  As
-        // TCPServer does not use these extended functions (only those defined
-        // in the IOSocket base class) - but needs a TCPSocket to get hold of
-        // the underlying Boost TCP socket - DummyIOCallback is used.  This
-        // provides the appropriate operator() but is otherwise functionless.
-        iosock_.reset(new TCPSocket<DummyIOCallback>(*socket_));
-        io_message_.reset(new IOMessage(data_.get(), length, *iosock_,
-                                        *peer_));
-
-        // If we don't have a DNS Lookup provider, there's no point in
-        // continuing; we exit the coroutine permanently.
-        if (lookup_callback_ == NULL) {
-            return;
-        }
-
-        // Reset or instantiate objects that will be needed by the
-        // DNS lookup and the write call.
-        respbuf_.reset(new OutputBuffer(0));
-        query_message_.reset(new Message(Message::PARSE));
-        answer_message_.reset(new Message(Message::RENDER));
-
-        // Schedule a DNS lookup, and yield.  When the lookup is
-        // finished, the coroutine will resume immediately after
-        // this point.  On resume, this method should be called with its
-        // default parameter values (because of the signature of post()'s
-        // handler), so ec shouldn't indicate any error.
-        CORO_YIELD io_.post(AsyncLookup<TCPServer>(*this));
-        assert(!ec);
-
-        // The 'done_' flag indicates whether we have an answer
-        // to send back.  If not, exit the coroutine permanently.
-        if (!done_) {
-            // Explicitly close() isn't necessary for most cases. But for the
-            // very connection, socket_ is shared with the original owner of
-            // the server object and would stay open.
-            // TODO: should we keep the connection open for a short time
-            // to see if new requests come in?
-            socket_->close(ec);
-            if (ec) {
-                LOG_DEBUG(logger, 0, ASIODNS_TCP_CLOSE_FAIL).arg(ec.message());
-            }
-            return;
-        }
-
-        // Call the DNS answer provider to render the answer into
-        // wire format
-        (*answer_callback_)(*io_message_, query_message_, answer_message_,
-                            respbuf_);
-
-        // Set up the response, beginning with two length bytes.
-        lenbuf.writeUint16(respbuf_->getLength());
-        bufs[0] = buffer(lenbuf.getData(), lenbuf.getLength());
-        bufs[1] = buffer(respbuf_->getData(), respbuf_->getLength());
-
-        // Begin an asynchronous send, and then yield.  When the
-        // send completes, we will resume immediately after this point
-        // (though we have nothing further to do, so the coroutine
-        // will simply exit at that time).
-        CORO_YIELD async_write(*socket_, bufs, *this);
-        if (ec) {
-            LOG_DEBUG(logger, DBGLVL_TRACE_BASIC, ASIODNS_TCP_WRITE_FAIL).
-                arg(ec.message());
-        }
-
-        // All done, cancel the timeout timer. if it throws, consider it fatal.
-        timeout_->cancel();
-
-        // TODO: should we keep the connection open for a short time
-        // to see if new requests come in?
-        socket_->close(ec);
-        if (ec) {
-            // close() should be unlikely to fail, but we've seen it fail once,
-            // so we log the event (at the lowest level of debug).
-            LOG_DEBUG(logger, 0, ASIODNS_TCP_CLOSE_FAIL).arg(ec.message());
-        }
-    }
-}
-
-/// Call the DNS lookup provider.  (Expected to be called by the
-/// AsyncLookup<TCPServer> handler.)
-void
-TCPServer::asyncLookup() {
-    (*lookup_callback_)(*io_message_, query_message_,
-                        answer_message_, respbuf_, this);
-}
-
-void TCPServer::stop() {
-    asio::error_code ec;
-
-    /// we use close instead of cancel, with the same reason
-    /// with udp server stop, refer to the udp server code
-
-    acceptor_->close(ec);
-    if (ec) {
-        LOG_ERROR(logger, ASIODNS_TCP_CLOSE_ACCEPTOR_FAIL).arg(ec.message());
-    }
-
-    // User may stop the server even when it hasn't started to
-    // run, in that case socket_ is empty
-    if (socket_) {
-        socket_->close(ec);
-        if (ec) {
-            LOG_ERROR(logger, ASIODNS_TCP_CLEANUP_CLOSE_FAIL).arg(ec.message());
-        }
-    }
-}
-/// 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
-TCPServer::resume(const bool done) {
-    done_ = done;
-
-    // post() can throw due to memory allocation failure, but as like other
-    // cases of the entire Kea implementation, we consider it fatal and
-    // let the exception be propagated.
-    io_.post(*this);
-}
-
-} // namespace asiodns
-} // namespace isc

+ 0 - 146
src/lib/asiodns/tcp_server.h

@@ -1,146 +0,0 @@
-// Copyright (C) 2011  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 TCP_SERVER_H
-#define TCP_SERVER_H 1
-
-#ifndef ASIO_HPP
-#error "asio.hpp must be included before including this, see asiolink.h as to why"
-#endif
-
-#include <boost/shared_array.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <asiolink/asiolink.h>
-#include <coroutine.h>
-#include "dns_server.h"
-#include "dns_lookup.h"
-#include "dns_answer.h"
-
-namespace isc {
-namespace asiodns {
-
-/// \brief A TCP-specific \c DNSServer object.
-///
-/// This class inherits from both \c DNSServer and from \c coroutine,
-/// defined in coroutine.h.
-class TCPServer : public virtual DNSServer, public virtual coroutine {
-public:
-    /// \brief Constructor
-    /// \param io_service the asio::io_service to work with
-    /// \param fd the file descriptor of opened TCP socket
-    /// \param af address family of the socket, either AF_INET or AF_INET6
-    /// \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 or it can't be listened on.
-    TCPServer(asio::io_service& io_service, int fd, int af,
-              const DNSLookup* lookup = NULL, const DNSAnswer* answer = NULL);
-
-    void operator()(asio::error_code ec = asio::error_code(),
-                    size_t length = 0);
-    void asyncLookup();
-    void stop();
-    void resume(const bool done);
-    DNSServer* clone() {
-        TCPServer* s = new TCPServer(*this);
-        return (s);
-    }
-
-    /// \brief Set the read timeout
-    ///
-    /// If the client does not send (all) query data within this
-    /// timeframe, the connection is dropped
-    ///
-    /// \param timeout in milliseconds
-    virtual void setTCPRecvTimeout(size_t timeout) {
-        *tcp_recv_timeout_ = timeout;
-    }
-
-private:
-    enum { MAX_LENGTH = 65535 };
-    static const size_t TCP_MESSAGE_LENGTHSIZE = 2;
-
-    // The ASIO service object
-    asio::io_service& io_;
-
-    // Class member variables which are dynamic, and changes to which
-    // need to accessible from both sides of a coroutine fork or from
-    // outside of the coroutine (i.e., from an asynchronous I/O call),
-    // should be declared here as pointers and allocated in the
-    // constructor or in the coroutine.  This allows state information
-    // to persist when an individual copy of the coroutine falls out
-    // scope while waiting for an event, *so long as* there is another
-    // object that is referencing the same data.  As a side-benefit, using
-    // pointers also reduces copy overhead for coroutine objects.
-    //
-    // Note: Currently these objects are allocated by "new" in the
-    // constructor, or in the function operator while processing a query.
-    // Repeated allocations from the heap for every incoming query is
-    // clearly a performance issue; this must be optimized in the future.
-    // The plan is to have a structure pre-allocate several "server state"
-    // objects which can be pulled off a free list and placed on an in-use
-    // list whenever a query comes in.  This will serve the dual purpose
-    // of improving performance and guaranteeing that state information
-    // will *not* be destroyed when any one instance of the coroutine
-    // falls out of scope while waiting for an event.
-    //
-    // An ASIO acceptor object to handle new connections.  Created in
-    // the constructor.
-    boost::shared_ptr<asio::ip::tcp::acceptor> acceptor_;
-
-    // Socket used to for listen for queries.  Created in the
-    // constructor and stored in a shared_ptr because socket objects
-    // are not copyable.
-    boost::shared_ptr<asio::ip::tcp::socket> socket_;
-
-    // The buffer into which the response is written
-    boost::shared_ptr<isc::util::OutputBuffer> respbuf_;
-
-    // \c IOMessage and \c Message objects to be passed to the
-    // DNS lookup and answer providers
-    boost::shared_ptr<isc::asiolink::IOMessage> io_message_;
-    isc::dns::MessagePtr query_message_;
-    isc::dns::MessagePtr answer_message_;
-
-    // The buffer into which the query packet is written
-    boost::shared_array<char>data_;
-
-    // State information that is entirely internal to a given instance
-    // of the coroutine can be declared here.
-    bool done_;
-
-    // Callback functions provided by the caller
-    const DNSLookup* lookup_callback_;
-    const DNSAnswer* answer_callback_;
-
-    boost::shared_ptr<isc::asiolink::IOEndpoint> peer_;
-    boost::shared_ptr<isc::asiolink::IOSocket> iosock_;
-
-    // Timer used to timeout on tcp connections
-    // This is a shared pointer because we need to have something
-    // that outlives the operator() call and is copyable (for CORO_FORK)
-    // even though it is only set after fork
-    boost::shared_ptr<asio::deadline_timer> timeout_;
-
-    // Timeout value to use in the timer;
-    // this, too, is a pointer, so that it can be updated whithout restarting
-    // the server
-    boost::shared_ptr<size_t> tcp_recv_timeout_;
-};
-
-} // namespace asiodns
-} // namespace isc
-#endif // TCP_SERVER_H

+ 0 - 4
src/lib/asiodns/tests/Makefile.am

@@ -1,7 +1,5 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += $(BOOST_INCLUDES)
-AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/bin
-AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc  -I$(top_builddir)/src/lib/util
 
 AM_CXXFLAGS = $(KEA_CXXFLAGS)
 
@@ -18,8 +16,6 @@ TESTS =
 if HAVE_GTEST
 TESTS += run_unittests
 run_unittests_SOURCES  = run_unittests.cc
-run_unittests_SOURCES += dns_service_unittest.cc
-run_unittests_SOURCES += dns_server_unittest.cc
 run_unittests_SOURCES += io_fetch_unittest.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)

+ 0 - 782
src/lib/asiodns/tests/dns_server_unittest.cc

@@ -1,782 +0,0 @@
-// Copyright (C) 2011, 2015  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 <gtest/gtest.h>
-
-#include <asio.hpp>
-#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>
-#include <string>
-#include <cstring>
-#include <cerrno>
-#include <csignal>
-#include <unistd.h> //for alarm
-
-#include <boost/shared_ptr.hpp>
-#include <boost/bind.hpp>
-#include <boost/function.hpp>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-/// The following tests focus on stop interface for udp and
-/// tcp server, there are lots of things can be shared to test
-/// both tcp and udp server, so they are in the same unittest
-
-/// The general work flow for dns server, is that wait for user
-/// query, once get one query, we will check the data is valid or
-/// not, if it passed, we will try to loop up the question, then
-/// compose the answer and finally send it back to user. The server
-/// may be stopped at any point during this porcess, so the test strategy
-/// is that we define 5 stop point and stop the server at these
-/// 5 points, to check whether stop is successful
-/// The 5 test points are :
-///   Before the server start to run
-///   After we get the query and check whether it's valid
-///   After we lookup the query
-///   After we compose the answer
-///   After user gets the final result.
-
-/// The standard about whether we stop the server successfully or not
-/// is based on the fact that if the server is still running, the io
-/// service won't quit since it will wait for some asynchronized event for
-/// server. So if the io service block function run returns we assume
-/// that the server is stopped. To avoid stop interface failure which
-/// will block followed tests, using alarm signal to stop the blocking
-/// io service
-///
-/// The whole test context including one server and one client, and
-/// five stop checkpoints, we call them ServerStopper exclude the first
-/// stop point. Once the unittest fired, the client will send message
-/// to server, and the stopper may stop the server at the checkpoint, then
-/// we check the client get feedback or not. Since there is no DNS logic
-/// involved so the message sending between client and server is plain text
-/// And the valid checker, question lookup and answer composition are dummy.
-
-using namespace isc::asiolink;
-using namespace isc::asiodns;
-using namespace asio;
-
-namespace {
-const char* const server_ip = "::1";
-const int server_port = 5553;
-const char* const server_port_str = "5553";
-//message client send to udp server, which isn't dns package
-//just for simple testing
-const char* const query_message = "Kea is awesome";
-
-// \brief provide capacity to derived class the ability
-// to stop DNSServer at certain point
-class ServerStopper {
-    public:
-        ServerStopper() : server_to_stop_(NULL) {}
-        virtual ~ServerStopper(){}
-
-        void setServerToStop(DNSServer& server) {
-            server_to_stop_ = &server;
-        }
-
-        void stopServer() const {
-            if (server_to_stop_) {
-                server_to_stop_->stop();
-            }
-        }
-
-    private:
-        DNSServer* server_to_stop_;
-};
-
-// \brief no lookup logic at all,just provide a checkpoint to stop the server
-class DummyLookup : public DNSLookup, public ServerStopper {
-public:
-    DummyLookup() :
-        allow_resume_(true)
-    { }
-    virtual 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
-//  provide checkpoint to stop server
-class SimpleAnswer : public DNSAnswer, public ServerStopper {
-    public:
-        void operator()(const IOMessage& message,
-                isc::dns::MessagePtr query_message,
-                isc::dns::MessagePtr answer_message,
-                isc::util::OutputBufferPtr buffer) const
-        {
-            //copy what we get from user
-            buffer->writeData(message.getData(), message.getDataSize());
-            stopServer();
-        }
-
-};
-
-/// \brief Mixture of DummyLookup and SimpleAnswer: build the answer in the
-/// lookup callback.  Used with SyncUDPServer.
-class SyncDummyLookup : public DummyLookup {
-public:
-    virtual void operator()(const IOMessage& io_message,
-                            isc::dns::MessagePtr message,
-                            isc::dns::MessagePtr answer_message,
-                            isc::util::OutputBufferPtr buffer,
-                            DNSServer* server) const
-    {
-        buffer->writeData(io_message.getData(), io_message.getDataSize());
-        stopServer();
-        if (allow_resume_) {
-            server->resume(true);
-        }
-    }
-};
-
-// \brief simple client, send one string to server and wait for response
-//  in case, server stopped and client can't get response, there is a timer wait
-//  for specified seconds (the value is just a estimate since server process logic is quite
-//  simple, and all the intercommunication is local) then cancel the waiting.
-class SimpleClient : public ServerStopper {
-    public:
-    static const size_t MAX_DATA_LEN = 256;
-    SimpleClient(asio::io_service& service,
-                 unsigned int wait_server_time_out)
-    {
-        wait_for_response_timer_.reset(new deadline_timer(service));
-        received_data_ = new char[MAX_DATA_LEN];
-        received_data_len_ = 0;
-        wait_server_time_out_ = wait_server_time_out;
-    }
-
-    virtual ~SimpleClient() {
-        delete [] received_data_;
-    }
-
-    void setGetFeedbackCallback(boost::function<void()>& func) {
-        get_response_call_back_ = func;
-    }
-
-    virtual void sendDataThenWaitForFeedback(const std::string& data)  = 0;
-    virtual std::string getReceivedData() const = 0;
-
-    void startTimer() {
-        wait_for_response_timer_->cancel();
-        wait_for_response_timer_->
-            expires_from_now(boost::posix_time::
-                             seconds(wait_server_time_out_));
-        wait_for_response_timer_->
-            async_wait(boost::bind(&SimpleClient::stopWaitingforResponse,
-                                   this));
-    }
-
-    void cancelTimer() { wait_for_response_timer_->cancel(); }
-
-    void getResponseCallBack(const asio::error_code& error, size_t
-                             received_bytes)
-    {
-        cancelTimer();
-        if (!error)
-            received_data_len_ = received_bytes;
-        if (!get_response_call_back_.empty()) {
-            get_response_call_back_();
-        }
-        stopServer();
-    }
-
-
-    protected:
-    virtual void stopWaitingforResponse() = 0;
-
-    boost::shared_ptr<deadline_timer> wait_for_response_timer_;
-    char* received_data_;
-    size_t received_data_len_;
-    boost::function<void()> get_response_call_back_;
-    unsigned int wait_server_time_out_;
-};
-
-
-
-class UDPClient : public SimpleClient {
-    public:
-    //After 1 second without feedback client will stop wait
-    static const unsigned int SERVER_TIME_OUT = 1;
-
-    UDPClient(asio::io_service& service, const ip::udp::endpoint& server) :
-        SimpleClient(service, SERVER_TIME_OUT)
-    {
-        server_ = server;
-        socket_.reset(new ip::udp::socket(service));
-        socket_->open(ip::udp::v6());
-    }
-
-
-    void sendDataThenWaitForFeedback(const std::string& data) {
-        received_data_len_ = 0;
-        socket_->send_to(buffer(data.c_str(), data.size() + 1), server_);
-        socket_->async_receive_from(buffer(received_data_, MAX_DATA_LEN),
-                                    received_from_,
-                                    boost::bind(&SimpleClient::
-                                                getResponseCallBack, this, _1,
-                                                _2));
-        startTimer();
-    }
-
-    virtual std::string getReceivedData() const {
-        return (received_data_len_ == 0 ? std::string("") :
-                                std::string(received_data_));
-    }
-
-    private:
-    void stopWaitingforResponse() {
-        socket_->close();
-    }
-
-    boost::shared_ptr<ip::udp::socket> socket_;
-    ip::udp::endpoint server_;
-    ip::udp::endpoint received_from_;
-};
-
-
-class TCPClient : public SimpleClient {
-    public:
-    // after 2 seconds without feedback client will stop wait,
-    // this includes connect, send message and recevice message
-    static const unsigned int SERVER_TIME_OUT = 2;
-    TCPClient(asio::io_service& service, const ip::tcp::endpoint& server)
-        : SimpleClient(service, SERVER_TIME_OUT),
-          data_to_send_(""), data_to_send_len_(0),
-          send_data_delay_(0), send_data_len_delay_(0)
-    {
-        server_ = server;
-        socket_.reset(new ip::tcp::socket(service));
-        socket_->open(ip::tcp::v6());
-        send_delay_timer_.reset(new deadline_timer(service));
-    }
-
-
-    virtual void sendDataThenWaitForFeedback(const std::string &data) {
-        received_data_len_ = 0;
-        data_to_send_ = data;
-        data_to_send_len_ = data.size() + 1;
-        socket_->async_connect(server_, boost::bind(&TCPClient::connectHandler,
-                                                    this, _1));
-        startTimer();
-    }
-
-    virtual std::string getReceivedData() const {
-        return (received_data_len_ == 0 ? std::string("") :
-                                std::string(received_data_ + 2));
-    }
-
-    /// Set the delay before the data len is sent (in seconds)
-    /// If this is non-zero, the actual data is never sent
-    /// (it is used to test timeout, in which case the connection
-    /// should have been closed by the other side anyway)
-    void setSendDataLenDelay(size_t send_data_len_delay) {
-        send_data_len_delay_ = send_data_len_delay;
-    }
-
-    /// Set the delay before the packet data itself is sent
-    /// (in seconds)
-    void setSendDataDelay(size_t send_data_delay) {
-        send_data_delay_ = send_data_delay;
-    }
-
-    private:
-    void stopWaitingforResponse() {
-        socket_->close();
-    }
-
-    void connectHandler(const asio::error_code& error) {
-        if (!error) {
-            data_to_send_len_ = htons(data_to_send_len_);
-            sleep(send_data_len_delay_);
-            socket_->async_send(buffer(&data_to_send_len_, 2),
-                                boost::bind(&TCPClient::sendMessageBodyHandler,
-                                            this, _1, _2));
-        }
-    }
-
-    void sendMessageBodyHandler(const asio::error_code& error,
-                                size_t send_bytes)
-    {
-        if (!error && send_bytes == 2 && send_data_len_delay_ == 0) {
-            // We cannot block here (such as by sleep(3)) since otherwise
-            // the ASIO events may not reliably handled in the server side
-            // as the test expects.  So we use async_wait, and make sure the
-            // control will be given back to the IO service.
-            if (send_data_delay_ > 0) {
-                send_delay_timer_->expires_from_now(boost::posix_time::
-                                                    seconds(send_data_delay_));
-                send_delay_timer_->async_wait(
-                    boost::bind(&TCPClient::sendMessageData, this));
-                return;
-            }
-            sendMessageData();
-        }
-    }
-
-    void sendMessageData() {
-        socket_->async_send(buffer(data_to_send_.c_str(),
-                                   data_to_send_.size() + 1),
-                            boost::bind(&TCPClient::finishSendHandler, this,
-                                        _1, _2));
-    }
-
-    void finishSendHandler(const asio::error_code& error, size_t send_bytes) {
-        if (error) {
-            getResponseCallBack(error, 0);
-        } else if (send_bytes == data_to_send_.size() + 1) {
-            socket_->async_receive(buffer(received_data_, MAX_DATA_LEN),
-                   boost::bind(&SimpleClient::getResponseCallBack, this, _1,
-                               _2));
-        }
-    }
-
-    boost::shared_ptr<ip::tcp::socket> socket_;
-    ip::tcp::endpoint server_;
-    std::string data_to_send_;
-    uint16_t data_to_send_len_;
-    boost::shared_ptr<deadline_timer> send_delay_timer_;
-
-    size_t send_data_delay_;
-    size_t send_data_len_delay_;
-};
-
-// \brief provide the context which including two clients and
-// 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 four times, once
-// for each type of initialization (once when giving it the address and port,
-// 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() :
-            server_address_(ip::address::from_string(server_ip)),
-            lookup_(new DummyLookup()),
-            sync_lookup_(new SyncDummyLookup()),
-            answer_(new SimpleAnswer()),
-            udp_client_(new UDPClient(service,
-                                      ip::udp::endpoint(server_address_,
-                                                         server_port))),
-            tcp_client_(new TCPClient(service,
-                                      ip::tcp::endpoint(server_address_,
-                                                        server_port)))
-        {
-            current_service = &service;
-        }
-
-        ~ DNSServerTestBase() {
-            if (udp_server_) {
-                udp_server_->stop();
-            }
-            if (tcp_server_) {
-                tcp_server_->stop();
-            }
-            delete lookup_;
-            delete sync_lookup_;
-            delete answer_;
-            delete udp_client_;
-            delete tcp_client_;
-            // No delete here. The service is not allocated by new, but as our
-            // member. This only references it, so just cleaning the pointer.
-            current_service = NULL;
-        }
-
-        void testStopServerByStopper(DNSServer& server, SimpleClient* client,
-                                     ServerStopper* stopper)
-        {
-            static const unsigned int IO_SERVICE_TIME_OUT = 5;
-            io_service_is_time_out = false;
-            stopper->setServerToStop(server);
-            server();
-            client->sendDataThenWaitForFeedback(query_message);
-            // Since thread hasn't been introduced into the tool box, using
-            // signal to make sure run function will eventually return even
-            // server stop failed
-            void (*prev_handler)(int) =
-                std::signal(SIGALRM, DNSServerTestBase::stopIOService);
-            current_service = &service;
-            alarm(IO_SERVICE_TIME_OUT);
-            service.run();
-            service.reset();
-            //cancel scheduled alarm
-            alarm(0);
-            std::signal(SIGALRM, prev_handler);
-        }
-
-        static void stopIOService(int _no_use_parameter) {
-            io_service_is_time_out = true;
-            if (current_service != NULL) {
-                current_service->stop();
-            }
-        }
-
-        bool serverStopSucceed() const {
-            return (!io_service_is_time_out);
-        }
-
-        asio::io_service service;
-        const ip::address server_address_;
-        DummyLookup* lookup_;     // we need to replace it in some cases
-        SyncDummyLookup*  const sync_lookup_;
-        SimpleAnswer* const answer_;
-        UDPClient*    const udp_client_;
-        TCPClient*    const tcp_client_;
-        boost::shared_ptr<UDPServerClass> udp_server_;
-        boost::shared_ptr<TCPServer> tcp_server_;
-
-        // To access them in signal handle function, the following
-        // variables have to be static.
-        static asio::io_service* current_service;
-        static bool io_service_is_time_out;
-};
-
-// Initialization (by the file descriptor)
-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
-    // a raw file descriptor. It also is what the socket creator does and this
-    // API is aimed to it.
-    int getFd(int type) {
-        struct addrinfo hints;
-        memset(&hints, 0, sizeof(hints));
-        hints.ai_family = AF_UNSPEC;
-        hints.ai_socktype = type;
-        hints.ai_protocol = (type == SOCK_STREAM) ? IPPROTO_TCP : IPPROTO_UDP;
-        hints.ai_flags = AI_NUMERICSERV | AI_NUMERICHOST;
-
-        struct addrinfo* res;
-        const int error = getaddrinfo(server_ip, server_port_str,
-                                      &hints, &res);
-        if (error != 0) {
-            isc_throw(IOError, "getaddrinfo failed: " << gai_strerror(error));
-        }
-
-        int sock;
-        const int on(1);
-        // Go as far as you can and stop on failure
-        // Create the socket
-        // set the options
-        // and bind it
-        const bool failed((sock = socket(res->ai_family, res->ai_socktype,
-                                         res->ai_protocol)) == -1 ||
-                          setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,
-                                     sizeof(on)) == -1 ||
-                          bind(sock, res->ai_addr, res->ai_addrlen) == -1);
-        // No matter if it succeeded or not, free the address info
-        freeaddrinfo(res);
-        if (failed) {
-            if (sock != -1) {
-                close(sock);
-            }
-            return (-1);
-        } else {
-            return (sock);
-        }
-    }
-protected:
-    // Using SetUp here so we can ASSERT_*
-    void SetUp() {
-        const int fd_udp(getFd(SOCK_DGRAM));
-        ASSERT_NE(-1, fd_udp) << strerror(errno);
-        this->udp_server_ = createServer(fd_udp, AF_INET6);
-        const int fd_tcp(getFd(SOCK_STREAM));
-        ASSERT_NE(-1, fd_tcp) << strerror(errno);
-        this->tcp_server_ =
-            boost::shared_ptr<TCPServer>(new TCPServer(
-                                             this->service, fd_tcp, AF_INET6,
-                                             this->lookup_,
-                                             this->answer_));
-    }
-
-    // A helper factory of the tested UDP server class: allow customization
-    // by template specialization.
-    boost::shared_ptr<UDPServerClass> createServer(int fd, int af) {
-        return (boost::shared_ptr<UDPServerClass>(
-                    new UDPServerClass(this->service, fd, af,
-                                       this->lookup_,
-                                       this->answer_)));
-    }
-};
-
-// Specialization for SyncUDPServer.  It needs to use SyncDummyLookup.
-template<>
-boost::shared_ptr<SyncUDPServer>
-FdInit<SyncUDPServer>::createServer(int fd, int af) {
-    delete this->lookup_;
-    this->lookup_ = new SyncDummyLookup;
-    return (SyncUDPServer::create(this->service, fd, af, this->lookup_));
-}
-
-// This makes it the template as gtest wants it.
-template<class Parent>
-class DNSServerTest : public Parent { };
-
-typedef ::testing::Types<FdInit<UDPServer>, FdInit<SyncUDPServer> >
-    ServerTypes;
-TYPED_TEST_CASE(DNSServerTest, ServerTypes);
-
-// Some tests work only for SyncUDPServer, some others work only for
-// (non Sync)UDPServer.  We specialize these tests.
-typedef FdInit<UDPServer> AsyncServerTest;
-typedef FdInit<SyncUDPServer> SyncServerTest;
-
-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);
-
-// 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
-// if udp server doesn't stop successfully.
-TYPED_TEST(DNSServerTest, stopUDPServerAfterOneQuery) {
-    this->testStopServerByStopper(*this->udp_server_, this->udp_client_,
-                                  this->udp_client_);
-    EXPECT_EQ(query_message, this->udp_client_->getReceivedData());
-    EXPECT_TRUE(this->serverStopSucceed());
-}
-
-// Test whether udp server stopped successfully before server start to serve
-TYPED_TEST(DNSServerTest, stopUDPServerBeforeItStartServing) {
-    this->udp_server_->stop();
-    this->testStopServerByStopper(*this->udp_server_, this->udp_client_,
-                                  this->udp_client_);
-    EXPECT_EQ(std::string(""), this->udp_client_->getReceivedData());
-    EXPECT_TRUE(this->serverStopSucceed());
-}
-
-// Test whether udp server stopped successfully during query lookup
-TYPED_TEST(DNSServerTest, stopUDPServerDuringQueryLookup) {
-    this->testStopServerByStopper(*this->udp_server_, this->udp_client_,
-                                  this->lookup_);
-    EXPECT_EQ(std::string(""), this->udp_client_->getReceivedData());
-    EXPECT_TRUE(this->serverStopSucceed());
-}
-
-// Test whether UDP server stopped successfully during composing answer.
-// Only works for (non-sync) server because SyncUDPServer doesn't use answer
-// callback.
-TEST_F(AsyncServerTest, stopUDPServerDuringPrepareAnswer) {
-    testStopServerByStopper(*udp_server_, udp_client_, answer_);
-    EXPECT_EQ(std::string(""), udp_client_->getReceivedData());
-    EXPECT_TRUE(serverStopSucceed());
-}
-
-void
-stopServerManyTimes(DNSServer *server, unsigned int times) {
-    for (unsigned int i = 0; i < times; ++i) {
-        server->stop();
-    }
-}
-
-// Test whether udp server stop interface can be invoked several times without
-// throw any exception
-TYPED_TEST(DNSServerTest, stopUDPServerMoreThanOnce) {
-    ASSERT_NO_THROW({
-        boost::function<void()> stop_server_3_times
-            = boost::bind(stopServerManyTimes, this->udp_server_.get(), 3);
-        this->udp_client_->setGetFeedbackCallback(stop_server_3_times);
-        this->testStopServerByStopper(*this->udp_server_,
-                                      this->udp_client_, this->udp_client_);
-        EXPECT_EQ(query_message, this->udp_client_->getReceivedData());
-    });
-    EXPECT_TRUE(this->serverStopSucceed());
-}
-
-TYPED_TEST(DNSServerTest, stopTCPServerAfterOneQuery) {
-    this->testStopServerByStopper(*this->tcp_server_, this->tcp_client_,
-                                  this->tcp_client_);
-    EXPECT_EQ(query_message, this->tcp_client_->getReceivedData());
-    EXPECT_TRUE(this->serverStopSucceed());
-}
-
-TYPED_TEST(DNSServerTest, TCPTimeoutOnLen) {
-    this->tcp_server_->setTCPRecvTimeout(100);
-    this->tcp_client_->setSendDataLenDelay(2);
-    this->testStopServerByStopper(*this->tcp_server_, this->tcp_client_,
-                                  this->tcp_client_);
-    EXPECT_EQ("", this->tcp_client_->getReceivedData());
-    EXPECT_FALSE(this->serverStopSucceed());
-}
-
-TYPED_TEST(DNSServerTest, TCPTimeout) {
-    // set delay higher than timeout
-    this->tcp_server_->setTCPRecvTimeout(100);
-    this->tcp_client_->setSendDataDelay(2);
-    this->testStopServerByStopper(*this->tcp_server_, this->tcp_client_,
-                                  this->tcp_client_);
-    EXPECT_EQ("", this->tcp_client_->getReceivedData());
-    EXPECT_TRUE(this->serverStopSucceed());
-}
-
-TYPED_TEST(DNSServerTest, TCPNoTimeout) {
-    // set delay lower than timeout
-    this->tcp_server_->setTCPRecvTimeout(3000);
-    this->tcp_client_->setSendDataDelay(1);
-    this->testStopServerByStopper(*this->tcp_server_, this->tcp_client_,
-                                  this->tcp_client_);
-    EXPECT_EQ("Kea is awesome", this->tcp_client_->getReceivedData());
-    EXPECT_TRUE(this->serverStopSucceed());
-}
-
-// Test whether tcp server stopped successfully before server start to serve
-TYPED_TEST(DNSServerTest, stopTCPServerBeforeItStartServing) {
-    this->tcp_server_->stop();
-    this->testStopServerByStopper(*this->tcp_server_, this->tcp_client_,
-                                  this->tcp_client_);
-    EXPECT_EQ(std::string(""), this->tcp_client_->getReceivedData());
-    EXPECT_TRUE(this->serverStopSucceed());
-}
-
-
-// Test whether tcp server stopped successfully during query lookup
-TYPED_TEST(DNSServerTest, stopTCPServerDuringQueryLookup) {
-    this->testStopServerByStopper(*this->tcp_server_, this->tcp_client_,
-                                  this->lookup_);
-    EXPECT_EQ(std::string(""), this->tcp_client_->getReceivedData());
-    EXPECT_TRUE(this->serverStopSucceed());
-}
-
-// Test whether tcp server stopped successfully during composing answer
-TYPED_TEST(DNSServerTest, stopTCPServerDuringPrepareAnswer) {
-    this->testStopServerByStopper(*this->tcp_server_, this->tcp_client_,
-                                  this->answer_);
-    EXPECT_EQ(std::string(""), this->tcp_client_->getReceivedData());
-    EXPECT_TRUE(this->serverStopSucceed());
-}
-
-
-// Test whether tcp server stop interface can be invoked several times without
-// throw any exception
-TYPED_TEST(DNSServerTest, stopTCPServeMoreThanOnce) {
-    ASSERT_NO_THROW({
-        boost::function<void()> stop_server_3_times
-            = boost::bind(stopServerManyTimes, this->tcp_server_.get(), 3);
-        this->tcp_client_->setGetFeedbackCallback(stop_server_3_times);
-        this->testStopServerByStopper(*this->tcp_server_, this->tcp_client_,
-                                      this->tcp_client_);
-        EXPECT_EQ(query_message, this->tcp_client_->getReceivedData());
-    });
-    EXPECT_TRUE(this->serverStopSucceed());
-}
-
-// It raises an exception when invalid address family is passed
-// 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(TCPServer(this->service, 0, AF_UNIX,
-                           this->lookup_, this->answer_),
-                 isc::InvalidParameter);
-}
-
-TYPED_TEST(DNSServerTest, invalidFamilyUDP) {
-    EXPECT_THROW(this->createServer(0, AF_UNIX), isc::InvalidParameter);
-}
-
-// It raises an exception when invalid address family is passed
-TYPED_TEST(DNSServerTestBase, invalidTCPFD) {
-    // We abuse DNSServerTestBase for this test, as we don't need the
-    // initialization.
-    /*
-     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
-     asio backend does fail as it tries to insert it right away, but
-     not the others, maybe we could make it run this at last on epoll-based
-     systems).
-    EXPECT_THROW(UDPServer(service, -1, AF_INET, lookup_,
-                           answer_), isc::asiolink::IOError);
-    */
-    EXPECT_THROW(TCPServer(this->service, -1, AF_INET,
-                           this->lookup_, this->answer_),
-                 isc::asiolink::IOError);
-}
-
-TYPED_TEST(DNSServerTest, 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
-     asio backend does fail as it tries to insert it right away, but
-     not the others, maybe we could make it run this at least on epoll-based
-     systems).
-    */
-    EXPECT_THROW(this->createServer(-1, AF_INET), isc::asiolink::IOError);
-}
-
-// 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)
-TEST_F(SyncServerTest, mustResume) {
-    lookup_->allow_resume_ = false;
-    ASSERT_THROW(testStopServerByStopper(*udp_server_, udp_client_, lookup_),
-                 isc::Unexpected);
-}
-
-// SyncUDPServer doesn't allow NULL lookup callback.
-TEST_F(SyncServerTest, nullLookupCallback) {
-    EXPECT_THROW(SyncUDPServer::create(service, 0, AF_INET, NULL),
-                 isc::InvalidParameter);
-}
-
-TEST_F(SyncServerTest, resetUDPServerBeforeEvent) {
-    // Reset the UDP server object after starting and before it would get
-    // an event from io_service (in this case abort event).  The following
-    // sequence confirms it's shut down immediately, and without any
-    // disruption.
-
-    // Since we'll stop the server run() should immediately return, and
-    // it's very unlikely to cause hangup.  But we'll make very sure it
-    // doesn't happen.
-    const unsigned int IO_SERVICE_TIME_OUT = 5;
-    (*udp_server_)();
-    udp_server_->stop();
-    udp_server_.reset();
-    void (*prev_handler)(int) = std::signal(SIGALRM, stopIOService);
-    current_service = &service;
-    alarm(IO_SERVICE_TIME_OUT);
-    service.run();
-    alarm(0);
-    std::signal(SIGALRM, prev_handler);
-    EXPECT_FALSE(io_service_is_time_out);
-}
-
-}

+ 0 - 232
src/lib/asiodns/tests/dns_service_unittest.cc

@@ -1,232 +0,0 @@
-// Copyright (C) 2011  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 <gtest/gtest.h>
-
-#include <exceptions/exceptions.h>
-
-#include <asio.hpp>
-#include <asiolink/asiolink.h>
-#include <asiodns/asiodns.h>
-
-#include <boost/scoped_ptr.hpp>
-#include <boost/lexical_cast.hpp>
-
-#include <csignal>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <unistd.h>
-#include <netdb.h>
-
-using namespace isc::asiolink;
-using namespace isc::asiodns;
-using boost::scoped_ptr;
-using boost::lexical_cast;
-
-namespace {
-const char* const TEST_SERVER_PORT = "53535";
-const char* const TEST_IPV6_ADDR = "::1";
-
-// A simple lookup callback for DNS services.  It records the pointer value of
-// to given output buffer each time the callback is called (up to two times)
-// for the main tests.  At the end of the second callback it stops the server.
-// The sender of the data doesn't expect to get a response, so it simply
-// discards any received data.
-class TestLookup : public DNSLookup {
-public:
-    TestLookup(isc::util::OutputBuffer** b1, isc::util::OutputBuffer** b2,
-               IOService& io_service) :
-        first_buffer_(b1), second_buffer_(b2), io_service_(io_service)
-    {}
-    void operator()(const IOMessage&, isc::dns::MessagePtr,
-                    isc::dns::MessagePtr, isc::util::OutputBufferPtr buffer,
-                    DNSServer* server) const
-    {
-        server->resume(false);
-        if (*first_buffer_ == NULL) {
-            *first_buffer_ = buffer.get();
-        } else {
-            assert(*second_buffer_ == NULL);
-            *second_buffer_ = buffer.get();
-            server->stop();
-            io_service_.stop();
-        }
-    }
-    isc::util::OutputBuffer** first_buffer_;
-    isc::util::OutputBuffer** second_buffer_;
-    IOService& io_service_;
-};
-
-// A test fixture to check creation of UDP servers from a socket FD, changing
-// options.
-class UDPDNSServiceTest : public::testing::Test {
-private:
-    static const unsigned int IO_SERVICE_TIME_OUT = 5;
-
-protected:
-    UDPDNSServiceTest() :
-        first_buffer_(NULL), second_buffer_(NULL),
-        lookup(&first_buffer_, &second_buffer_, io_service),
-        dns_service(io_service, &lookup, NULL),
-        client_socket(io_service.get_io_service(), asio::ip::udp::v6()),
-        server_ep(asio::ip::address::from_string(TEST_IPV6_ADDR),
-                  lexical_cast<uint16_t>(TEST_SERVER_PORT)),
-        asio_service(io_service.get_io_service())
-    {
-        current_service = &io_service;
-        // Content shouldn't matter for the tests, but initialize anyway
-        memset(data, 1, sizeof(data));
-    }
-
-    ~UDPDNSServiceTest() {
-        current_service = NULL;
-    }
-
-    void runService() {
-        io_service_is_time_out = false;
-
-        // Send two UDP packets, which will be passed to the TestLookup
-        // callback.  They are not expected to be responded, so it simply
-        // closes the socket right after that.
-        client_socket.send_to(asio::buffer(data, sizeof(data)), server_ep);
-        client_socket.send_to(asio::buffer(data, sizeof(data)), server_ep);
-        client_socket.close();
-
-        // set a signal-based alarm to prevent the test from hanging up
-        // due to a bug.
-        void (*prev_handler)(int) =
-            std::signal(SIGALRM, UDPDNSServiceTest::stopIOService);
-        current_service = &io_service;
-        alarm(IO_SERVICE_TIME_OUT);
-        io_service.run();
-        io_service.get_io_service().reset();
-        //cancel scheduled alarm
-        alarm(0);
-        std::signal(SIGALRM, prev_handler);
-    }
-
-    // last resort service stopper by signal
-    static void stopIOService(int) {
-        io_service_is_time_out = true;
-        if (current_service != NULL) {
-            current_service->stop();
-        }
-    }
-
-    bool serverStopSucceed() const {
-        return (!io_service_is_time_out);
-    }
-
-    isc::util::OutputBuffer* first_buffer_;
-    isc::util::OutputBuffer* second_buffer_;
-    IOService io_service;
-    TestLookup lookup;
-    DNSService dns_service;
-private:
-    asio::ip::udp::socket client_socket;
-    const asio::ip::udp::endpoint server_ep;
-    char data[4];
-
-    // To access them in signal handle function, the following
-    // variables have to be static.
-    static IOService* current_service;
-    static bool io_service_is_time_out;
-
-    asio::io_service& asio_service;
-};
-
-// Need to define the non-const static members outside of the class
-// declaration
-IOService* UDPDNSServiceTest::current_service;
-bool UDPDNSServiceTest::io_service_is_time_out;
-
-// A helper socket FD creator for given address and port.  It's generally
-// expected to succeed; on failure it simply throws an exception to make
-// the test fail.
-int
-getSocketFD(int family, const char* const address, const char* const port) {
-    struct addrinfo hints, *res = NULL;
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = family;
-    hints.ai_socktype = SOCK_DGRAM;
-    hints.ai_protocol = IPPROTO_UDP;
-    hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
-    int s = -1;
-    int error = getaddrinfo(address, port, &hints, &res);
-    if (error == 0) {
-        // If getaddrinfo returns 0, res should be set to a non NULL valid
-        // pointer, but some variants of cppcheck reportedly complains about
-        // it, so we satisfy them here.
-        if (res != NULL) {
-            s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
-            if (s >= 0) {
-                error = bind(s, res->ai_addr, res->ai_addrlen);
-            }
-            freeaddrinfo(res);
-        }
-    }
-    if (error != 0) {
-        if (s >= 0) {
-            close(s);
-        }
-        isc_throw(isc::Unexpected, "failed to open test socket");
-    }
-    return (s);
-}
-
-TEST_F(UDPDNSServiceTest, defaultUDPServerFromFD) {
-    // If no option is explicitly specified, an asynchronous server should be
-    // created.  So the two output buffers should be different.
-    dns_service.addServerUDPFromFD(getSocketFD(AF_INET6, TEST_IPV6_ADDR,
-                                               TEST_SERVER_PORT), AF_INET6);
-    runService();
-    EXPECT_TRUE(serverStopSucceed());
-    EXPECT_NE(first_buffer_, second_buffer_);
-}
-
-TEST_F(UDPDNSServiceTest, explicitDefaultUDPServerFromFD) {
-    // If "default" option is explicitly specified, the effect should be the
-    // same as the previous case.
-    dns_service.addServerUDPFromFD(getSocketFD(AF_INET6, TEST_IPV6_ADDR,
-                                               TEST_SERVER_PORT),
-                                   AF_INET6, DNSService::SERVER_DEFAULT);
-    runService();
-    EXPECT_TRUE(serverStopSucceed());
-    EXPECT_NE(first_buffer_, second_buffer_);
-}
-
-TEST_F(UDPDNSServiceTest, syncUDPServerFromFD) {
-    // If "SYNC_OK" option is specified, a synchronous server should be
-    // created.  It will reuse the output buffer, so the recorded two pointer
-    // should be identical.
-    dns_service.addServerUDPFromFD(getSocketFD(AF_INET6, TEST_IPV6_ADDR,
-                                               TEST_SERVER_PORT),
-                                   AF_INET6, DNSService::SERVER_SYNC_OK);
-    runService();
-    EXPECT_TRUE(serverStopSucceed());
-    EXPECT_EQ(first_buffer_, second_buffer_);
-}
-
-TEST_F(UDPDNSServiceTest, addUDPServerFromFDWithUnknownOption) {
-    // Use of undefined/incompatible options should result in an exception.
-    EXPECT_THROW(dns_service.addServerUDPFromFD(
-                     getSocketFD(AF_INET6, TEST_IPV6_ADDR, TEST_SERVER_PORT),
-                     AF_INET6, static_cast<DNSService::ServerFlag>(2)),
-                 isc::InvalidParameter);
-}
-
-} // unnamed namespace

+ 0 - 346
src/lib/asiodns/udp_server.cc

@@ -1,346 +0,0 @@
-// Copyright (C) 2011, 2015  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 <unistd.h>             // for some IPC/network system calls
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <errno.h>
-
-#include <boost/shared_array.hpp>
-
-#include <asio.hpp>
-#include <asio/error.hpp>
-#include <asiolink/dummy_io_cb.h>
-#include <asiolink/udp_endpoint.h>
-#include <asiolink/udp_socket.h>
-#include "udp_server.h"
-#include "logger.h"
-
-#include <dns/opcode.h>
-
-// Avoid 'using namespace asio' (see tcp_server.cc)
-using asio::io_service;
-using asio::socket_base;
-using asio::buffer;
-using asio::ip::udp;
-using asio::ip::address;
-
-using namespace std;
-using namespace isc::dns;
-using namespace isc::util;
-using namespace isc::asiolink;
-
-namespace isc {
-namespace asiodns {
-
-/*
- * Some of the member variables here are shared_ptrs and some are
- * auto_ptrs. There will be one instance of Data for the lifetime
- * of packet. The variables that are state only for a single packet
- * use auto_ptr, as it is more lightweight. In the case of shared
- * configuration (eg. the callbacks, socket), we use shared_ptrs.
- */
-struct UDPServer::Data {
-    /*
-     * Constructors from parameters passed to UDPServer constructor.
-     * This instance will not be used to retrieve and answer the actual
-     * query, it will only hold parameters until we wait for the
-     * first packet. But we do initialize the socket in here.
-     */
-    Data(io_service& io_service, const address& addr, const uint16_t port,
-         DNSLookup* lookup, DNSAnswer* answer) :
-        io_(io_service), bytes_(0), done_(false),
-        lookup_callback_(lookup),
-        answer_callback_(answer)
-    {
-        // We must use different instantiations for v4 and v6;
-        // otherwise ASIO will bind to both
-        udp proto = addr.is_v4() ? udp::v4() : udp::v6();
-        socket_.reset(new udp::socket(io_service, proto));
-        socket_->set_option(socket_base::reuse_address(true));
-        if (addr.is_v6()) {
-            socket_->set_option(asio::ip::v6_only(true));
-        }
-        socket_->bind(udp::endpoint(addr, port));
-    }
-    Data(io_service& io_service, int fd, int af,
-         DNSLookup* lookup, DNSAnswer* answer) :
-         io_(io_service), bytes_(0), done_(false),
-         lookup_callback_(lookup),
-         answer_callback_(answer)
-    {
-        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 udp::socket(io_service));
-            socket_->assign(af == AF_INET6 ? udp::v6() : 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());
-        }
-    }
-
-    /*
-     * Copy constructor. Default one would probably do, but it is unnecessary
-     * to copy many of the member variables every time we fork to handle
-     * another packet.
-     *
-     * We also allocate data for receiving the packet here.
-     */
-    Data(const Data& other) :
-        io_(other.io_), socket_(other.socket_), bytes_(0), done_(false),
-        lookup_callback_(other.lookup_callback_),
-        answer_callback_(other.answer_callback_)
-    {
-        // Instantiate the data buffer and endpoint that will
-        // be used by the asynchronous receive call.
-        data_.reset(new char[MAX_LENGTH]);
-        sender_.reset(new udp::endpoint());
-    }
-
-    // The ASIO service object
-    asio::io_service& io_;
-
-    // Class member variables which are dynamic, and changes to which
-    // need to accessible from both sides of a coroutine fork or from
-    // outside of the coroutine (i.e., from an asynchronous I/O call),
-    // should be declared here as pointers and allocated in the
-    // constructor or in the coroutine.  This allows state information
-    // to persist when an individual copy of the coroutine falls out
-    // scope while waiting for an event, *so long as* there is another
-    // object that is referencing the same data.  As a side-benefit, using
-    // pointers also reduces copy overhead for coroutine objects.
-    //
-    // Note: Currently these objects are allocated by "new" in the
-    // constructor, or in the function operator while processing a query.
-    // Repeated allocations from the heap for every incoming query is
-    // clearly a performance issue; this must be optimized in the future.
-    // The plan is to have a structure pre-allocate several "Data"
-    // objects which can be pulled off a free list and placed on an in-use
-    // list whenever a query comes in.  This will serve the dual purpose
-    // of improving performance and guaranteeing that state information
-    // will *not* be destroyed when any one instance of the coroutine
-    // falls out of scope while waiting for an event.
-    //
-    // Socket used to for listen for queries.  Created in the
-    // constructor and stored in a shared_ptr because socket objects
-    // are not copyable.
-    boost::shared_ptr<asio::ip::udp::socket> socket_;
-
-    // The ASIO-internal endpoint object representing the client
-    std::auto_ptr<asio::ip::udp::endpoint> sender_;
-
-    // \c IOMessage and \c Message objects to be passed to the
-    // DNS lookup and answer providers
-    std::auto_ptr<asiolink::IOMessage> io_message_;
-
-    // The original query as sent by the client
-    isc::dns::MessagePtr query_message_;
-
-    // The response message we are building
-    isc::dns::MessagePtr answer_message_;
-
-    // The buffer into which the response is written
-    isc::util::OutputBufferPtr respbuf_;
-
-    // The buffer into which the query packet is written
-    boost::shared_array<char> data_;
-
-    // State information that is entirely internal to a given instance
-    // of the coroutine can be declared here.
-    size_t bytes_;
-    bool done_;
-
-    // Callback functions provided by the caller
-    const DNSLookup* lookup_callback_;
-    const DNSAnswer* answer_callback_;
-
-    std::auto_ptr<IOEndpoint> peer_;
-    std::auto_ptr<IOSocket> iosock_;
-};
-
-/// The following functions implement the \c UDPServer class.
-///
-/// The constructor. It just creates new internal state object
-/// and lets it handle the initialization.
-UDPServer::UDPServer(io_service& io_service, int fd, int af,
-                     DNSLookup* lookup,
-                     DNSAnswer* answer) :
-    data_(new Data(io_service, fd, af, lookup, answer))
-{ }
-
-/// The function operator is implemented with the "stackless coroutine"
-/// pattern; see internal/coroutine.h for details.
-void
-UDPServer::operator()(asio::error_code ec, size_t length) {
-    /// Because the coroutine reentry block is implemented as
-    /// a switch statement, inline variable declarations are not
-    /// permitted.  Certain variables used below can be declared here.
-
-    CORO_REENTER (this) {
-        do {
-            /*
-             * This is preparation for receiving a packet. We get a new
-             * state object for the lifetime of the next packet to come.
-             * It allocates the buffers to receive data into.
-             */
-            data_.reset(new Data(*data_));
-
-            do {
-                // Begin an asynchronous receive, then yield.
-                // When the receive event is posted, the coroutine
-                // will resume immediately after this point.
-                CORO_YIELD data_->socket_->async_receive_from(
-                    buffer(data_->data_.get(), MAX_LENGTH), *data_->sender_,
-                    *this);
-
-                // See TCPServer::operator() for details on error handling.
-                if (ec) {
-                    using namespace asio::error;
-                    const asio::error_code::value_type err_val = ec.value();
-                    if (err_val == operation_aborted ||
-                        err_val == bad_descriptor) {
-                        return;
-                    }
-                    if (err_val != would_block && err_val != try_again &&
-                        err_val != interrupted) {
-                        LOG_ERROR(logger, ASIODNS_UDP_RECEIVE_FAIL).
-                            arg(ec.message());
-                    }
-                }
-
-            } while (ec || length == 0);
-
-            data_->bytes_ = length;
-
-            /*
-             * We fork the coroutine now. One (the child) will keep
-             * the current state and handle the packet, then die and
-             * drop ownership of the state. The other (parent) will just
-             * go into the loop again and replace the current state with
-             * a new one for a new object.
-             *
-             * Actually, both of the coroutines will be a copy of this
-             * one, but that's just internal implementation detail.
-             */
-            CORO_FORK data_->io_.post(UDPServer(*this));
-        } while (is_parent());
-
-        // Create an \c IOMessage object to store the query.
-        //
-        // (XXX: It would be good to write a factory function
-        // that would quickly generate an IOMessage object without
-        // all these calls to "new".)
-        data_->peer_.reset(new UDPEndpoint(*data_->sender_));
-
-        // 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.
-        data_->iosock_.reset(
-            new UDPSocket<DummyIOCallback>(*data_->socket_));
-
-        data_->io_message_.reset(new IOMessage(data_->data_.get(),
-            data_->bytes_, *data_->iosock_, *data_->peer_));
-
-        // If we don't have a DNS Lookup provider, there's no point in
-        // continuing; we exit the coroutine permanently.
-        if (data_->lookup_callback_ == NULL) {
-            return;
-        }
-
-        // Instantiate objects that will be needed by the
-        // asynchronous DNS lookup and/or by the send call.
-        data_->respbuf_.reset(new OutputBuffer(0));
-        data_->query_message_.reset(new Message(Message::PARSE));
-        data_->answer_message_.reset(new Message(Message::RENDER));
-
-        // Schedule a DNS lookup, and yield.  When the lookup is
-        // finished, the coroutine will resume immediately after
-        // this point.
-        CORO_YIELD data_->io_.post(AsyncLookup<UDPServer>(*this));
-
-        // The 'done_' flag indicates whether we have an answer
-        // to send back.  If not, exit the coroutine permanently.
-        if (!data_->done_) {
-            return;
-        }
-
-        // Call the DNS answer provider to render the answer into
-        // wire format
-        (*data_->answer_callback_)(*data_->io_message_, data_->query_message_,
-            data_->answer_message_, data_->respbuf_);
-
-        // Begin an asynchronous send, and then yield.  When the
-        // send completes, we will resume immediately after this point
-        // (though we have nothing further to do, so the coroutine
-        // will simply exit at that time, after reporting an error if
-        // there was one).
-        CORO_YIELD data_->socket_->async_send_to(
-            buffer(data_->respbuf_->getData(), data_->respbuf_->getLength()),
-            *data_->sender_, *this);
-        if (ec) {
-            LOG_ERROR(logger, ASIODNS_UDP_ASYNC_SEND_FAIL).
-                      arg(data_->sender_->address().to_string()).
-                      arg(ec.message());
-        }
-    }
-}
-
-/// Call the DNS lookup provider.  (Expected to be called by the
-/// AsyncLookup<UDPServer> handler.)
-void
-UDPServer::asyncLookup() {
-    (*data_->lookup_callback_)(*data_->io_message_,
-        data_->query_message_, data_->answer_message_, data_->respbuf_, this);
-}
-
-/// Stop the UDPServer
-void
-UDPServer::stop() {
-    asio::error_code ec;
-
-    /// Using close instead of cancel, because cancel
-    /// will only cancel the asynchronized 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 closed, all the asynchronized event
-    /// for it won't be scheduled by io service not matter it is
-    /// submit to io service before or after close call. And we will
-    //  get bad_descriptor error.
-    data_->socket_->close(ec);
-    if (ec) {
-        LOG_ERROR(logger, ASIODNS_UDP_CLOSE_FAIL).arg(ec.message());
-    }
-}
-
-/// 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
-UDPServer::resume(const bool done) {
-    data_->done_ = done;
-    data_->io_.post(*this);  // this can throw, but can be considered fatal.
-}
-
-} // namespace asiodns
-} // namespace isc

+ 0 - 97
src/lib/asiodns/udp_server.h

@@ -1,97 +0,0 @@
-// Copyright (C) 2011  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 UDP_SERVER_H
-#define UDP_SERVER_H 1
-
-#ifndef ASIO_HPP
-#error "asio.hpp must be included before including this, see asiolink.h as to why"
-#endif
-
-#include <asiolink/simple_callback.h>
-#include <asiodns/dns_answer.h>
-#include <asiodns/dns_lookup.h>
-#include <asiodns/dns_server.h>
-
-#include <coroutine.h>
-
-namespace isc {
-namespace asiodns {
-
-//
-// Asynchronous UDP server coroutine
-//
-///
-/// \brief This class implements the coroutine to handle UDP
-///        DNS query event. As such, it is both a \c DNSServer and
-///        a \c coroutine
-///
-class UDPServer : public virtual DNSServer, public virtual coroutine {
-public:
-    /// \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 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.
-    UDPServer(asio::io_service& io_service, int fd, int af,
-              DNSLookup* lookup = NULL, DNSAnswer* answer = NULL);
-
-    /// \brief The function operator
-    void operator()(asio::error_code ec = asio::error_code(),
-                    size_t length = 0);
-
-    /// \brief Calls the lookup callback
-    void asyncLookup();
-
-    /// \brief Stop the running server
-    /// \note once the server stopped, it can't restart
-    void stop();
-
-    /// \brief Resume operation
-    ///
-    /// \param done Set this to true if the lookup action is done and
-    ///        we have an answer
-    void resume(const bool done);
-
-    /// \brief Clones the object
-    ///
-    /// \return a newly allocated copy of this object
-    DNSServer* clone() {
-        UDPServer* s = new UDPServer(*this);
-        return (s);
-    }
-
-private:
-    enum { MAX_LENGTH = 4096 };
-
-    /**
-     * \brief Internal state and data.
-     *
-     * We use the pimple design pattern, but not because we need to hide
-     * internal data. This class and whole header is for private use anyway.
-     * It turned out that UDPServer is copied a lot, because it is a coroutine.
-     * This way the overhead of copying is lower, we copy only one shared
-     * pointer instead of about 10 of them.
-     */
-    struct Data;
-    boost::shared_ptr<Data> data_;
-};
-
-} // namespace asiodns
-} // namespace isc
-#endif // UDP_SERVER_H