]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[3391] Fix distcheck issues.
authorMarcin Siodelski <marcin@isc.org>
Thu, 10 Apr 2014 14:10:23 +0000 (16:10 +0200)
committerMarcin Siodelski <marcin@isc.org>
Thu, 10 Apr 2014 14:10:23 +0000 (16:10 +0200)
33 files changed:
configure.ac
src/lib/asiodns/dns_service.h
src/lib/resolve/.gitignore [deleted file]
src/lib/resolve/Makefile.am [deleted file]
src/lib/resolve/recursive_query.cc [deleted file]
src/lib/resolve/recursive_query.h [deleted file]
src/lib/resolve/resolve.cc [deleted file]
src/lib/resolve/resolve.h [deleted file]
src/lib/resolve/resolve_log.cc [deleted file]
src/lib/resolve/resolve_log.h [deleted file]
src/lib/resolve/resolve_messages.mes [deleted file]
src/lib/resolve/resolver_callback.cc [deleted file]
src/lib/resolve/resolver_callback.h [deleted file]
src/lib/resolve/resolver_interface.h [deleted file]
src/lib/resolve/response_classifier.cc [deleted file]
src/lib/resolve/response_classifier.h [deleted file]
src/lib/resolve/tests/.gitignore [deleted file]
src/lib/resolve/tests/Makefile.am [deleted file]
src/lib/resolve/tests/recursive_query_unittest.cc [deleted file]
src/lib/resolve/tests/recursive_query_unittest_2.cc [deleted file]
src/lib/resolve/tests/recursive_query_unittest_3.cc [deleted file]
src/lib/resolve/tests/resolve_unittest.cc [deleted file]
src/lib/resolve/tests/resolver_callback_unittest.cc [deleted file]
src/lib/resolve/tests/response_classifier_unittest.cc [deleted file]
src/lib/resolve/tests/run_unittests.cc [deleted file]
src/lib/testutils/mockups.h
src/lib/xfr/Makefile.am [deleted file]
src/lib/xfr/tests/.gitignore [deleted file]
src/lib/xfr/tests/Makefile.am [deleted file]
src/lib/xfr/tests/client_test.cc [deleted file]
src/lib/xfr/tests/run_unittests.cc [deleted file]
src/lib/xfr/xfrout_client.cc [deleted file]
src/lib/xfr/xfrout_client.h [deleted file]

index 92c35d446647d9ce05e88d8d306c68f07d5afb0f..a8d6745cead85b45e091a5b23fcf52f99076f369 100644 (file)
@@ -1469,7 +1469,6 @@ AC_CONFIG_FILES([compatcheck/Makefile
                  src/lib/dhcpsrv/tests/Makefile
                  src/lib/dhcpsrv/tests/test_libraries.h
                  src/lib/dhcp/tests/Makefile
-                 src/lib/dns/benchmarks/Makefile
                  src/lib/dns/gen-rdatacode.py
                  src/lib/dns/Makefile
                  src/lib/dns/python/Makefile
@@ -1668,11 +1667,6 @@ fi
 
 cat >> config.report << END
 
-Components:
-  DHCP: $want_dhcp
-  DNS: $want_dns
-  Experimental resolver: $want_experimental_resolver
-
 Features:
   $enable_features
 
index 00d7158befe91a6613c4356abbc1fe1c888864bc..4ce25d00c7757c07559b9cbb0aea052dfcf58846 100644 (file)
@@ -15,7 +15,9 @@
 #ifndef ASIOLINK_DNS_SERVICE_H
 #define ASIOLINK_DNS_SERVICE_H 1
 
-#include <resolve/resolver_interface.h>
+// 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>
diff --git a/src/lib/resolve/.gitignore b/src/lib/resolve/.gitignore
deleted file mode 100644 (file)
index 87dc694..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/resolve_messages.cc
-/resolve_messages.h
-/s-messages
diff --git a/src/lib/resolve/Makefile.am b/src/lib/resolve/Makefile.am
deleted file mode 100644 (file)
index dde08f2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-SUBDIRS = . tests
-
-AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
-AM_CPPFLAGS += $(BOOST_INCLUDES)
-
-AM_CXXFLAGS = $(B10_CXXFLAGS)
-
-# Define rule to build logging source files from message file
-resolve_messages.h resolve_messages.cc: s-messages
-
-s-messages: resolve_messages.mes
-       $(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/resolve/resolve_messages.mes
-       touch $@
-
-# Tell Automake that the nsasdef.{cc,h} source files are created in the build
-# process, so it must create these before doing anything else.  Although they
-# are a dependency of the library (so will be created from the message file
-# anyway), there is no guarantee as to exactly _when_ in the build they will be
-# created.  As the .h file is included in other sources file (so must be
-# present when they are compiled), the safest option is to create it first.
-BUILT_SOURCES = resolve_messages.h resolve_messages.cc
-
-CLEANFILES = *.gcno *.gcda resolve_messages.cc resolve_messages.h s-messages
-
-lib_LTLIBRARIES = libb10-resolve.la
-libb10_resolve_la_SOURCES = resolve.h resolve.cc
-libb10_resolve_la_SOURCES += resolve_log.h resolve_log.cc
-libb10_resolve_la_SOURCES += resolver_interface.h
-libb10_resolve_la_SOURCES += resolver_callback.h resolver_callback.cc
-libb10_resolve_la_SOURCES += response_classifier.cc response_classifier.h
-libb10_resolve_la_SOURCES += recursive_query.cc recursive_query.h
-
-nodist_libb10_resolve_la_SOURCES = resolve_messages.h resolve_messages.cc
-
-libb10_resolve_la_LIBADD = $(top_builddir)/src/lib/dns/libb10-dns++.la
-libb10_resolve_la_LIBADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
-libb10_resolve_la_LIBADD += $(top_builddir)/src/lib/log/libb10-log.la
-libb10_resolve_la_LIBADD += $(top_builddir)/src/lib/asiodns/libb10-asiodns.la
-libb10_resolve_la_LIBADD += $(top_builddir)/src/lib/nsas/libb10-nsas.la
-
-# The message file should be in the distribution.
-EXTRA_DIST = resolve_messages.mes
-
-# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
-# B10_CXXFLAGS)
-libb10_resolve_la_CXXFLAGS = $(AM_CXXFLAGS)
-libb10_resolve_la_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/src/lib/resolve/recursive_query.cc b/src/lib/resolve/recursive_query.cc
deleted file mode 100644 (file)
index e0c5a30..0000000
+++ /dev/null
@@ -1,1225 +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 <stdlib.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <unistd.h>             // for some IPC/network system calls
-#include <string>
-
-#include <boost/lexical_cast.hpp>
-#include <boost/bind.hpp>
-
-#include <dns/question.h>
-#include <dns/message.h>
-#include <dns/opcode.h>
-#include <dns/exceptions.h>
-#include <dns/rdataclass.h>
-#include <resolve/resolve.h>
-#include <resolve/resolve_log.h>
-#include <resolve/resolve_messages.h>
-#include <cache/resolver_cache.h>
-#include <nsas/address_request_callback.h>
-#include <nsas/nameserver_address.h>
-
-#include <asio.hpp>
-#include <asiodns/dns_service.h>
-#include <asiodns/io_fetch.h>
-#include <asiolink/io_service.h>
-#include <resolve/response_classifier.h>
-#include <resolve/recursive_query.h>
-
-using namespace isc::dns;
-using namespace isc::nsas;
-using namespace isc::util;
-using namespace isc::asiolink;
-using namespace isc::resolve;
-
-namespace isc {
-namespace asiodns {
-
-namespace {
-// Function to check if the given name/class has any address in the cache
-bool
-hasAddress(const Name& name, const RRClass& rrClass,
-      const isc::cache::ResolverCache& cache)
-{
-    // FIXME: If we are single-stack and we get only the other type of
-    // address, what should we do? In that case, it will be considered
-    // unreachable, which is most probably true, because A and AAAA will
-    // usually have the same RTT, so we should have both or none from the
-    // glue.
-    return (cache.lookup(name, RRType::A(), rrClass) != RRsetPtr() ||
-            cache.lookup(name, RRType::AAAA(), rrClass) != RRsetPtr());
-}
-
-// Convenience function for debug messages.  Question::toText() includes
-// a trailing newline in its output, which makes it awkward to embed in a
-// message.  This just strips that newline from it.
-std::string
-questionText(const isc::dns::Question& question) {
-    std::string text = question.toText();
-    if (!text.empty()) {
-        text.erase(text.size() - 1);
-    }
-    return (text);
-}
-
-} // anonymous namespace
-
-/// \brief Find deepest usable delegation in the cache
-///
-/// This finds the deepest delegation we have in cache and is safe to use.
-/// It is not public function, therefore it's not in header. But it's not
-/// in anonymous namespace, so we can call it from unittests.
-/// \param name The name we want to delegate to.
-/// \param rrclass The class.
-/// \param cache The place too look for known delegations.
-std::string
-deepestDelegation(Name name, RRClass rrclass,
-                  isc::cache::ResolverCache& cache)
-{
-    RRsetPtr cachedNS;
-    // Look for delegation point from bottom, until we find one with
-    // IP address or get to root.
-    //
-    // We need delegation with IP address so we can ask it right away.
-    // If we don't have the IP address, we would need to ask above it
-    // anyway in the best case, and the NS could be inside the zone,
-    // and we could get all loopy with the NSAS in the worst case.
-    while (name.getLabelCount() > 1 &&
-           (cachedNS = cache.lookupDeepestNS(name, rrclass)) != RRsetPtr()) {
-        // Look if we have an IP address for the NS
-        for (RdataIteratorPtr ns(cachedNS->getRdataIterator());
-             !ns->isLast(); ns->next()) {
-            // Do we have IP for this specific NS?
-            if (hasAddress(dynamic_cast<const rdata::generic::NS&>(
-                               ns->getCurrent()).getNSName(), rrclass,
-                           cache)) {
-                // Found one, stop checking and use this zone
-                // (there may be more addresses, that's only better)
-                return (cachedNS->getName().toText());
-            }
-        }
-        // We don't have anything for this one, so try something higher
-        if (name.getLabelCount() > 1) {
-            name = name.split(1);
-        }
-    }
-    // Fallback, nothing found, start at root
-    return (".");
-}
-
-// Here we do not use the typedef above, as the SunStudio compiler
-// mishandles this in its name mangling, and wouldn't compile.
-// We can probably use a typedef, but need to move it to a central
-// location and use it consistently.
-RecursiveQuery::RecursiveQuery(DNSServiceBase& dns_service,
-    isc::nsas::NameserverAddressStore& nsas,
-    isc::cache::ResolverCache& cache,
-    const std::vector<std::pair<std::string, uint16_t> >& upstream,
-    const std::vector<std::pair<std::string, uint16_t> >& upstream_root,
-    int query_timeout, int client_timeout, int lookup_timeout,
-    unsigned retries)
-    :
-    dns_service_(dns_service),
-    nsas_(nsas), cache_(cache),
-    upstream_(new AddressVector(upstream)),
-    upstream_root_(new AddressVector(upstream_root)),
-    test_server_("", 0),
-    query_timeout_(query_timeout), client_timeout_(client_timeout),
-    lookup_timeout_(lookup_timeout), retries_(retries), rtt_recorder_()
-{
-}
-
-// Set the test server - only used for unit testing.
-void
-RecursiveQuery::setTestServer(const std::string& address, uint16_t port) {
-    LOG_WARN(isc::resolve::logger, RESLIB_TEST_SERVER).arg(address).arg(port);
-    test_server_.first = address;
-    test_server_.second = port;
-}
-
-// Set the RTT recorder - only used for testing
-void
-RecursiveQuery::setRttRecorder(boost::shared_ptr<RttRecorder>& recorder) {
-    rtt_recorder_ = recorder;
-}
-
-namespace {
-typedef std::pair<std::string, uint16_t> addr_t;
-
-/*
- * This is a query in progress. When a new query is made, this one holds
- * the context information about it, like how many times we are allowed
- * to retry on failure, what to do when we succeed, etc.
- *
- * Used by RecursiveQuery::sendQuery.
- */
-class RunningQuery : public IOFetch::Callback, public AbstractRunningQuery {
-
-class ResolverNSASCallback : public isc::nsas::AddressRequestCallback {
-public:
-    ResolverNSASCallback(RunningQuery* rq) : rq_(rq) {}
-
-    void success(const isc::nsas::NameserverAddress& address) {
-        // Success callback, send query to found namesever
-        LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CB, RESLIB_RUNQ_SUCCESS)
-                  .arg(address.getAddress().toText());
-        rq_->nsasCallbackCalled();
-        rq_->sendTo(address);
-    }
-
-    void unreachable() {
-        // Nameservers unreachable: drop query or send servfail?
-        LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CB, RESLIB_RUNQ_FAIL);
-        rq_->nsasCallbackCalled();
-        rq_->makeSERVFAIL();
-        rq_->callCallback(true);
-        rq_->stop();
-    }
-
-private:
-    RunningQuery* rq_;
-};
-
-
-private:
-    // The io service to handle async calls
-    IOService& io_;
-
-    // Info for (re)sending the query (the question and destination)
-    Question question_;
-
-    // This is the query message got from client
-    ConstMessagePtr query_message_;
-
-    // This is where we build and store our final answer
-    MessagePtr answer_message_;
-
-    // Test server - only used for testing.  This takes precedence over all
-    // other servers if the port is non-zero.
-    std::pair<std::string, uint16_t> test_server_;
-
-    // Buffer to store the intermediate results.
-    OutputBufferPtr buffer_;
-
-    // The callback will be called when we have either decided we
-    // are done, or when we give up
-    isc::resolve::ResolverInterface::CallbackPtr resolvercallback_;
-
-    // Protocol used for the last query.  This is set to IOFetch::UDP when a
-    // new upstream query is initiated, and changed to IOFetch::TCP if a
-    // packet is returned with the TC bit set.  It is stored here to detect the
-    // case of a TCP packet being returned with the TC bit set.
-    IOFetch::Protocol protocol_;
-
-    // EDNS flag
-    bool edns_;
-
-    // To prevent both unreasonably long cname chains and cname loops,
-    // we simply keep a counter of the number of CNAMEs we have
-    // followed so far (and error if it exceeds RESOLVER_MAX_CNAME_CHAIN
-    // from lib/resolve/response_classifier.h)
-    unsigned cname_count_;
-
-    /*
-     * TODO Do something more clever with timeouts. In the long term, some
-     *     computation of average RTT, increase with each retry, etc.
-     */
-    // Timeout information for outgoing queries
-    int query_timeout_;
-    unsigned retries_;
-
-    // normal query state
-
-    // TODO: replace by our wrapper
-    asio::deadline_timer client_timer;
-    asio::deadline_timer lookup_timer;
-
-    // If we timed out ourselves (lookup timeout), stop issuing queries
-    bool done_;
-
-    // If we have a client timeout, we call back with a failure message,
-    // but we do not stop yet. We use this variable to make sure we
-    // don't call back a second time later
-    bool callback_called_;
-
-    // Reference to our NSAS
-    isc::nsas::NameserverAddressStore& nsas_;
-
-    // Reference to our cache
-    isc::cache::ResolverCache& cache_;
-
-    // the 'current' zone we are in (i.e.) we start out at the root,
-    // and for each delegation this gets updated with the zone the
-    // delegation points to.
-    // TODO: make this a Name (it is a string right now because most
-    // of the call we use it in take a string, we need update those
-    // too).
-    std::string cur_zone_;
-
-    // This is the handler we pass on to the NSAS; it is called when
-    // the NSAS has an address for us to query
-    boost::shared_ptr<ResolverNSASCallback> nsas_callback_;
-
-    // this is set to true if we have asked the nsas to give us
-    // an address and we are waiting for it to call us back.
-    // We use is to cancel the outstanding callback in case we
-    // have a lookup timeout and decide to give up
-    bool nsas_callback_out_;
-
-    // This is the nameserver we have an outstanding query to.
-    // It is used to update the RTT once the query returns
-    isc::nsas::NameserverAddress current_ns_address;
-
-    // The moment in time we sent a query to the nameserver above.
-    struct timeval current_ns_qsent_time;
-
-    // RunningQuery deletes itself when it is done. In order for us
-    // to do this safely, we must make sure that there are no events
-    // that might call back to it. There are two types of events in
-    // this sense; the timers we set ourselves (lookup and client),
-    // and outstanding queries to nameservers. When each of these is
-    // started, we increase this value. When they fire, it is decreased
-    // again. We cannot delete ourselves until this value is back to 0.
-    //
-    // Note that the NSAS callback is *not* seen as an outstanding
-    // event; we can cancel the NSAS callback safely.
-    size_t outstanding_events_;
-
-    // RTT Recorder.  Used for testing, the RTTs of queries are
-    // sent to this object as well as being used to update the NSAS.
-    boost::shared_ptr<RttRecorder> rtt_recorder_;
-
-    // perform a single lookup; first we check the cache to see
-    // if we have a response for our query stored already. if
-    // so, call handlerecursiveresponse(), if not, we call send()
-    void doLookup() {
-        LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CACHE, RESLIB_RUNQ_CACHE_LOOKUP)
-                  .arg(questionText(question_));
-
-        Message cached_message(Message::RENDER);
-        isc::resolve::initResponseMessage(question_, cached_message);
-        if (cache_.lookup(question_.getName(), question_.getType(),
-                          question_.getClass(), cached_message)) {
-
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CACHE, RESLIB_RUNQ_CACHE_FIND)
-                      .arg(questionText(question_));
-            // Should these be set by the cache too?
-            cached_message.setOpcode(Opcode::QUERY());
-            cached_message.setRcode(Rcode::NOERROR());
-            cached_message.setHeaderFlag(Message::HEADERFLAG_QR);
-            if (handleRecursiveAnswer(cached_message)) {
-                callCallback(true);
-                stop();
-            }
-        } else {
-            cur_zone_ = deepestDelegation(question_.getName(),
-                                          question_.getClass(), cache_);
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CACHE, RESLIB_DEEPEST)
-                      .arg(questionText(question_)).arg(cur_zone_);
-            send();
-        }
-
-    }
-
-    // Send the current question to the given nameserver address
-    void sendTo(const isc::nsas::NameserverAddress& address) {
-        // We need to keep track of the Address, so that we can update
-        // the RTT
-        current_ns_address = address;
-        gettimeofday(&current_ns_qsent_time, NULL);
-        ++outstanding_events_;
-        if (test_server_.second != 0) {
-            IOFetch query(protocol_, io_, question_,
-                test_server_.first,
-                test_server_.second, buffer_, this,
-                query_timeout_, edns_);
-            io_.get_io_service().post(query);
-        } else {
-            IOFetch query(protocol_, io_, question_,
-                current_ns_address.getAddress(),
-                53, buffer_, this,
-                query_timeout_, edns_);
-            io_.get_io_service().post(query);
-        }
-    }
-
-    // 'general' send, ask the NSAS to give us an address.
-    void send(IOFetch::Protocol protocol = IOFetch::UDP, bool edns = true) {
-        protocol_ = protocol;   // Store protocol being used for this
-        edns_ = edns;
-        if (test_server_.second != 0) {
-            // Send query to test server
-            LOG_DEBUG(isc::resolve::logger,
-                      RESLIB_DBG_TRACE, RESLIB_TEST_UPSTREAM)
-                .arg(questionText(question_)).arg(test_server_.first);
-            gettimeofday(&current_ns_qsent_time, NULL);
-            ++outstanding_events_;
-            IOFetch query(protocol, io_, question_,
-                test_server_.first,
-                test_server_.second, buffer_, this,
-                query_timeout_, edns_);
-            io_.get_io_service().post(query);
-
-        } else {
-            // Ask the NSAS for an address for the current zone,
-            // the callback will call the actual sendTo()
-            LOG_DEBUG(isc::resolve::logger,
-                      RESLIB_DBG_TRACE, RESLIB_NSAS_LOOKUP)
-                .arg(cur_zone_);
-
-            // Can we have multiple calls to nsas_out? Let's assume not
-            // for now
-            assert(!nsas_callback_out_);
-            nsas_callback_out_ = true;
-            nsas_.lookup(cur_zone_, question_.getClass(), nsas_callback_);
-        }
-    }
-
-    // Called by our NSAS callback handler so we know we do not have
-    // an outstanding NSAS call anymore.
-    void nsasCallbackCalled() {
-        nsas_callback_out_ = false;
-    }
-
-    // This function is called by operator() and lookup();
-    // We have an answer either from a nameserver or the cache, and
-    // we do not know yet if this is a final answer we can send back or
-    // that more recursive processing needs to be done.
-    // Depending on the content, we go on recursing or return
-    //
-    // This method also updates the cache, depending on the content
-    // of the message
-    //
-    // returns true if we are done (either we have an answer or an
-    //              error message)
-    // returns false if we are not done
-    bool handleRecursiveAnswer(const Message& incoming) {
-
-        // In case we get a CNAME, we store the target
-        // here (classify() will set it when it walks through
-        // the cname chain to verify it).
-        Name cname_target(question_.getName());
-
-        isc::resolve::ResponseClassifier::Category category =
-            isc::resolve::ResponseClassifier::classify(
-                question_, incoming, cname_target, cname_count_);
-
-        bool found_ns = false;
-
-        switch (category) {
-        case isc::resolve::ResponseClassifier::ANSWER:
-        case isc::resolve::ResponseClassifier::ANSWERCNAME:
-            // Answer received - copy and return.
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_ANSWER)
-                      .arg(questionText(question_));
-            isc::resolve::copyResponseMessage(incoming, answer_message_);
-            cache_.update(*answer_message_);
-            return (true);
-            break;
-
-        case isc::resolve::ResponseClassifier::CNAME:
-            // CNAME received.
-
-            // (unfinished) CNAME. We set our question_ to the CNAME
-            // target, then start over at the beginning (for now, that
-            // is, we reset our 'current servers' to the root servers).
-            if (cname_count_ >= RESOLVER_MAX_CNAME_CHAIN) {
-                // CNAME chain too long - just give up
-                LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_LONG_CHAIN)
-                          .arg(questionText(question_));
-                makeSERVFAIL();
-                return (true);
-            }
-
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_CNAME)
-                      .arg(questionText(question_));
-
-            answer_message_->appendSection(Message::SECTION_ANSWER,
-                                           incoming);
-
-            question_ = Question(cname_target, question_.getClass(),
-                                 question_.getType());
-
-            // Follow CNAME chain.
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_FOLLOW_CNAME)
-                      .arg(questionText(question_));
-            doLookup();
-            return (false);
-            break;
-
-        case isc::resolve::ResponseClassifier::NXDOMAIN:
-        case isc::resolve::ResponseClassifier::NXRRSET:
-            // Received NXDOMAIN or NXRRSET, just copy and return
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_NXDOM_NXRR)
-                      .arg(questionText(question_));
-            isc::resolve::copyResponseMessage(incoming, answer_message_);
-            // no negcache yet
-            //cache_.update(*answer_message_);
-            return (true);
-            break;
-
-        case isc::resolve::ResponseClassifier::REFERRAL:
-            // Response is a referral
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_REFERRAL)
-                      .arg(questionText(question_));
-
-            cache_.update(incoming);
-            // Referral. For now we just take the first glue address
-            // we find and continue with that
-
-            // auth section should have at least one RRset
-            // and one of them should be an NS (otherwise
-            // classifier should have error'd) to a subdomain
-            for (RRsetIterator rrsi = incoming.beginSection(Message::SECTION_AUTHORITY);
-                 rrsi != incoming.endSection(Message::SECTION_AUTHORITY) && !found_ns;
-                 ++rrsi) {
-                ConstRRsetPtr rrs = *rrsi;
-                if (rrs->getType() == RRType::NS()) {
-                    NameComparisonResult compare(Name(cur_zone_).compare(rrs->getName()));
-                    if (compare.getRelation() == NameComparisonResult::SUPERDOMAIN) {
-                        // TODO: make cur_zone_ a Name instead of a string
-                        // (this requires a few API changes in related
-                        // libraries, so as not to need many conversions)
-                        cur_zone_ = rrs->getName().toText();
-                        LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_REFER_ZONE)
-                                  .arg(cur_zone_);
-                        found_ns = true;
-                        break;
-                    }
-                }
-            }
-
-            if (found_ns) {
-                // next resolver round
-                // we do NOT use doLookup() here, but send() (i.e. we
-                // skip the cache), since if we had the final answer
-                // instead of a delegation cached, we would have been
-                // there by now.
-                GlueHints glue_hints(cur_zone_, incoming);
-
-                // Ask the NSAS for an address, or glue.
-                // This will eventually result in either sendTo()
-                // or stop() being called by nsas_callback_
-                assert(!nsas_callback_out_);
-                nsas_callback_out_ = true;
-                nsas_.lookup(cur_zone_, question_.getClass(),
-                             nsas_callback_, ANY_OK, glue_hints);
-                return (false);
-            } else {
-                // Referral was received but did not contain an NS RRset.
-                LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_NO_NS_RRSET)
-                          .arg(questionText(question_));
-
-                // TODO this will result in answering with the delegation. oh well
-                isc::resolve::copyResponseMessage(incoming, answer_message_);
-                return (true);
-            }
-            break;
-
-        case isc::resolve::ResponseClassifier::TRUNCATED:
-            // Truncated packet.  If the protocol we used for the last one is
-            // UDP, re-query using TCP.  Otherwise regard it as an error.
-            if (protocol_ == IOFetch::UDP) {
-                LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS,
-                          RESLIB_TRUNCATED).arg(questionText(question_));
-                send(IOFetch::TCP);
-                return (false);
-            }
-
-            // Was a TCP query so we have received a packet over TCP with the
-            // TC bit set: report an error by going to the common
-            // error code.
-            goto SERVFAIL;
-
-        case isc::resolve::ResponseClassifier::RCODE:
-            // see if it's a FORMERR and a potential EDNS problem
-            if (incoming.getRcode() == Rcode::FORMERR()) {
-                if (protocol_ == IOFetch::UDP && edns_) {
-                    // TODO: in case we absolutely need EDNS (i.e. for DNSSEC
-                    // aware queries), we might want to try TCP before we give
-                    // up. For now, just try UDP, no EDNS
-                    send(IOFetch::UDP, false);
-                    return (false);
-                }
-
-                // TC should take care of non-EDNS over UDP, fall through to
-                // SERVFAIL if we get FORMERR instead
-            }
-            goto SERVFAIL;
-
-        default:
-SERVFAIL:
-            // Some error in received packet it.  Report it and return SERVFAIL
-            // to the caller.
-            if (logger.isDebugEnabled()) {
-                reportResponseClassifierError(category, incoming.getRcode());
-            }
-            makeSERVFAIL();
-            return (true);
-        }
-
-        // If we get here, there is some serious logic error (or a missing
-        // "return").
-        assert(false);
-        return (true);  // To keep the compiler happy
-    }
-
-    /// \brief Report classification-detected error
-    ///
-    /// When the response classifier has detected an error in the response from
-    /// an upstream query, this method is called to log a debug message giving
-    /// information about the problem.
-    ///
-    /// \param category Classification code for the packet
-    /// \param rcode RCODE value in the packet
-    void reportResponseClassifierError(ResponseClassifier::Category category,
-                                       const Rcode& rcode)
-    {
-        // We could set up a table of response classifications to message
-        // IDs here and index into that table.  But given that (a) C++ does
-        // not have C's named initializers, (b) the codes for the
-        // response classifier are in another module and (c) not all messages
-        // have the same number of arguments, the setup of the table would be
-        // almost as long as the code here: it would need to include a number
-        // of assertions to ensure that any change to the the response
-        // classifier codes was detected, and the checking logic would need to
-        // check that the numeric value of the code lay within the defined
-        // limits of the table.
-
-        if (category == ResponseClassifier::RCODE) {
-
-            // Special case as this message takes two arguments.
-            LOG_DEBUG(logger, RESLIB_DBG_RESULTS, RESLIB_RCODE_RETURNED).
-                      arg(questionText(question_)).arg(rcode);
-
-        } else {
-
-            isc::log::MessageID message_id;
-            switch (category) {
-            case ResponseClassifier::TRUNCATED:
-                message_id = RESLIB_TCP_TRUNCATED;
-                break;
-
-            case ResponseClassifier::EMPTY:
-                message_id = RESLIB_EMPTY_RESPONSE;
-                break;
-
-            case ResponseClassifier::EXTRADATA:
-                message_id = RESLIB_EXTRADATA_RESPONSE;
-                break;
-
-            case ResponseClassifier::INVNAMCLASS:
-                message_id = RESLIB_INVALID_NAMECLASS_RESPONSE;
-                break;
-
-            case ResponseClassifier::INVTYPE:
-                message_id = RESLIB_INVALID_TYPE_RESPONSE;
-                break;
-
-            case ResponseClassifier::MISMATQUEST:
-                message_id = RESLIB_INVALID_QNAME_RESPONSE;
-                break;
-
-            case ResponseClassifier::MULTICLASS:
-                message_id = RESLIB_MULTIPLE_CLASS_RESPONSE;
-                break;
-
-            case ResponseClassifier::NOTONEQUEST:
-                message_id = RESLIB_NOT_ONE_QNAME_RESPONSE;
-                break;
-
-            case ResponseClassifier::NOTRESPONSE:
-                message_id = RESLIB_NOT_RESPONSE;
-                break;
-
-            case ResponseClassifier::NOTSINGLE:
-                message_id = RESLIB_NOTSINGLE_RESPONSE;
-                break;
-
-            case ResponseClassifier::OPCODE:
-                message_id = RESLIB_OPCODE_RESPONSE;
-                break;
-
-            default:
-                message_id = RESLIB_ERROR_RESPONSE;
-                break;
-            }
-            LOG_DEBUG(logger, RESLIB_DBG_RESULTS, message_id).
-                      arg(questionText(question_));
-        }
-    }
-
-public:
-    RunningQuery(IOService& io,
-        const Question& question,
-        MessagePtr answer_message,
-        std::pair<std::string, uint16_t>& test_server,
-        OutputBufferPtr buffer,
-        isc::resolve::ResolverInterface::CallbackPtr cb,
-        int query_timeout, int client_timeout, int lookup_timeout,
-        unsigned retries,
-        isc::nsas::NameserverAddressStore& nsas,
-        isc::cache::ResolverCache& cache,
-        boost::shared_ptr<RttRecorder>& recorder)
-        :
-        io_(io),
-        question_(question),
-        query_message_(),
-        answer_message_(answer_message),
-        test_server_(test_server),
-        buffer_(buffer),
-        resolvercallback_(cb),
-        protocol_(IOFetch::UDP),
-        cname_count_(0),
-        query_timeout_(query_timeout),
-        retries_(retries),
-        client_timer(io.get_io_service()),
-        lookup_timer(io.get_io_service()),
-        done_(false),
-        callback_called_(false),
-        nsas_(nsas),
-        cache_(cache),
-        cur_zone_("."),
-        nsas_callback_(),
-        nsas_callback_out_(false),
-        outstanding_events_(0),
-        rtt_recorder_(recorder)
-    {
-        // Set here to avoid using "this" in initializer list.
-        nsas_callback_.reset(new ResolverNSASCallback(this));
-
-        // Setup the timer to stop trying (lookup_timeout)
-        if (lookup_timeout >= 0) {
-            lookup_timer.expires_from_now(
-                boost::posix_time::milliseconds(lookup_timeout));
-            ++outstanding_events_;
-            lookup_timer.async_wait(boost::bind(&RunningQuery::lookupTimeout, this));
-        }
-
-        // Setup the timer to send an answer (client_timeout)
-        if (client_timeout >= 0) {
-            client_timer.expires_from_now(
-                boost::posix_time::milliseconds(client_timeout));
-            ++outstanding_events_;
-            client_timer.async_wait(boost::bind(&RunningQuery::clientTimeout, this));
-        }
-
-        doLookup();
-    }
-
-    virtual ~RunningQuery() {};
-
-    // called if we have a lookup timeout; if our callback has
-    // not been called, call it now. Then stop.
-    void lookupTimeout() {
-        if (!callback_called_) {
-            makeSERVFAIL();
-            callCallback(true);
-        }
-        assert(outstanding_events_ > 0);
-        --outstanding_events_;
-        stop();
-    }
-
-    // called if we have a client timeout; if our callback has
-    // not been called, call it now. But do not stop.
-    void clientTimeout() {
-        if (!callback_called_) {
-            makeSERVFAIL();
-            callCallback(true);
-        }
-        assert(outstanding_events_ > 0);
-        --outstanding_events_;
-        if (outstanding_events_ == 0) {
-            stop();
-        }
-    }
-
-    // If the callback has not been called yet, call it now
-    // If success is true, we call 'success' with our answer_message
-    // If it is false, we call failure()
-    void callCallback(bool success) {
-        if (!callback_called_) {
-            callback_called_ = true;
-
-            // There are two types of messages we could store in the
-            // cache;
-            // 1. answers to our fetches from authoritative servers,
-            //    exactly as we receive them, and
-            // 2. answers to queries we received from clients, which
-            //    have received additional processing (following CNAME
-            //    chains, for instance)
-            //
-            // Doing only the first would mean we would have to re-do
-            // processing when we get data from our cache, and doing
-            // only the second would miss out on the side-effect of
-            // having nameserver data in our cache.
-            //
-            // So right now we do both. Since the cache (currently)
-            // stores Messages on their question section only, this
-            // does mean that we overwrite the messages we stored in
-            // the previous iteration if we are following a delegation.
-            if (success) {
-                resolvercallback_->success(answer_message_);
-            } else {
-                resolvercallback_->failure();
-            }
-        }
-    }
-
-    // We are done. If there are no more outstanding events, we delete
-    // ourselves. If there are any, we do not.
-    void stop() {
-        done_ = true;
-        if (nsas_callback_out_) {
-            nsas_.cancel(cur_zone_, question_.getClass(), nsas_callback_);
-            nsas_callback_out_ = false;
-        }
-        client_timer.cancel();
-        lookup_timer.cancel();
-        if (outstanding_events_ > 0) {
-            return;
-        } else {
-            delete this;
-        }
-    }
-
-    // This function is used as callback from DNSQuery.
-    virtual void operator()(IOFetch::Result result) {
-        // XXX is this the place for TCP retry?
-        assert(outstanding_events_ > 0);
-        --outstanding_events_;
-
-        if (!done_ && result != IOFetch::TIME_OUT) {
-            // we got an answer
-
-            // Update the NSAS with the time it took
-            struct timeval cur_time;
-            gettimeofday(&cur_time, NULL);
-            uint32_t rtt = 0;
-
-            // Only calculate RTT if it is positive
-            if (cur_time.tv_sec > current_ns_qsent_time.tv_sec ||
-                (cur_time.tv_sec == current_ns_qsent_time.tv_sec &&
-                 cur_time.tv_usec > current_ns_qsent_time.tv_usec)) {
-                rtt = 1000 * (cur_time.tv_sec - current_ns_qsent_time.tv_sec);
-                rtt += (cur_time.tv_usec - current_ns_qsent_time.tv_usec) / 1000;
-            }
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_RTT).arg(rtt);
-            current_ns_address.updateRTT(rtt);
-            if (rtt_recorder_) {
-                rtt_recorder_->addRtt(rtt);
-            }
-
-            try {
-                Message incoming(Message::PARSE);
-                InputBuffer ibuf(buffer_->getData(), buffer_->getLength());
-
-                incoming.fromWire(ibuf);
-
-                buffer_->clear();
-                done_ = handleRecursiveAnswer(incoming);
-                if (done_) {
-                    callCallback(true);
-                    stop();
-                }
-            } catch (const isc::dns::DNSProtocolError& dpe) {
-                // Right now, we treat this similar to timeouts
-                // (except we don't store RTT)
-                // We probably want to make this an integral part
-                // of the fetch data process. (TODO)
-                if (retries_--) {
-                    // Retry
-                    LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS,
-                              RESLIB_PROTOCOL_RETRY)
-                              .arg(questionText(question_)).arg(dpe.what())
-                              .arg(retries_);
-                    send();
-                } else {
-                    // Give up
-                    LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS,
-                              RESLIB_PROTOCOL)
-                              .arg(questionText(question_)).arg(dpe.what());
-                    if (!callback_called_) {
-                        makeSERVFAIL();
-                        callCallback(true);
-                    }
-                    stop();
-                }
-            }
-        } else if (!done_ && retries_--) {
-            // Query timed out, but we have some retries, so send again
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_TIMEOUT_RETRY)
-                      .arg(questionText(question_))
-                      .arg(current_ns_address.getAddress().toText()).arg(retries_);
-            current_ns_address.updateRTT(isc::nsas::AddressEntry::UNREACHABLE);
-            send();
-        } else {
-            // We are either already done, or out of retries
-            if (result == IOFetch::TIME_OUT) {
-                LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_RESULTS, RESLIB_TIMEOUT)
-                          .arg(questionText(question_))
-                          .arg(current_ns_address.getAddress().toText());
-                current_ns_address.updateRTT(isc::nsas::AddressEntry::UNREACHABLE);
-            }
-            if (!callback_called_) {
-                makeSERVFAIL();
-                callCallback(true);
-            }
-            stop();
-        }
-    }
-
-    // Clear the answer parts of answer_message, and set the rcode
-    // to servfail
-    void makeSERVFAIL() {
-        if (answer_message_) {
-            isc::resolve::makeErrorMessage(answer_message_, Rcode::SERVFAIL());
-        }
-    }
-};
-
-class ForwardQuery : public IOFetch::Callback, public AbstractRunningQuery {
-private:
-    // The io service to handle async calls
-    IOService& io_;
-
-    // This is the query message got from client
-    ConstMessagePtr query_message_;
-
-    // This is where we build and store our final answer
-    MessagePtr answer_message_;
-
-    // List of nameservers to forward to
-    boost::shared_ptr<AddressVector> upstream_;
-
-    // Buffer to store the result.
-    OutputBufferPtr buffer_;
-
-    // This will be notified when we succeed or fail
-    isc::resolve::ResolverInterface::CallbackPtr resolvercallback_;
-
-    /*
-     * TODO Do something more clever with timeouts. In the long term, some
-     *     computation of average RTT, increase with each retry, etc.
-     */
-    // Timeout information
-    int query_timeout_;
-
-    // TODO: replace by our wrapper
-    asio::deadline_timer client_timer;
-    asio::deadline_timer lookup_timer;
-
-    // Make ForwardQuery deletes itself safely. for more information see
-    // the comments of outstanding_events in RunningQuery.
-    size_t outstanding_events_;
-
-    // If we have a client timeout, we call back with a failure message,
-    // but we do not stop yet. We use this variable to make sure we
-    // don't call back a second time later
-    bool callback_called_;
-
-    // send the query to the server.
-    void send(IOFetch::Protocol protocol = IOFetch::UDP) {
-        const int uc = upstream_->size();
-        buffer_->clear();
-        int serverIndex = rand() % uc;
-        ConstQuestionPtr question = *(query_message_->beginQuestion());
-        LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_TRACE, RESLIB_UPSTREAM)
-            .arg(questionText(*question))
-            .arg(upstream_->at(serverIndex).first);
-
-        ++outstanding_events_;
-        // Forward the query, create the IOFetch with
-        // query message, so that query flags can be forwarded
-        // together.
-        IOFetch query(protocol, io_, query_message_,
-            upstream_->at(serverIndex).first,
-            upstream_->at(serverIndex).second,
-            buffer_, this, query_timeout_);
-
-        io_.get_io_service().post(query);
-    }
-
-public:
-    ForwardQuery(IOService& io,
-        ConstMessagePtr query_message,
-        MessagePtr answer_message,
-        boost::shared_ptr<AddressVector> upstream,
-        OutputBufferPtr buffer,
-        isc::resolve::ResolverInterface::CallbackPtr cb,
-        int query_timeout, int client_timeout, int lookup_timeout) :
-        io_(io),
-        query_message_(query_message),
-        answer_message_(answer_message),
-        upstream_(upstream),
-        buffer_(buffer),
-        resolvercallback_(cb),
-        query_timeout_(query_timeout),
-        client_timer(io.get_io_service()),
-        lookup_timer(io.get_io_service()),
-        outstanding_events_(0),
-        callback_called_(false)
-    {
-        // Setup the timer to stop trying (lookup_timeout)
-        if (lookup_timeout >= 0) {
-            lookup_timer.expires_from_now(
-                boost::posix_time::milliseconds(lookup_timeout));
-            ++outstanding_events_;
-            lookup_timer.async_wait(boost::bind(&ForwardQuery::lookupTimeout, this));
-        }
-
-        // Setup the timer to send an answer (client_timeout)
-        if (client_timeout >= 0) {
-            client_timer.expires_from_now(
-                boost::posix_time::milliseconds(client_timeout));
-            ++outstanding_events_;
-            client_timer.async_wait(boost::bind(&ForwardQuery::clientTimeout, this));
-        }
-
-        send();
-    }
-
-    virtual ~ForwardQuery() {};
-
-    virtual void lookupTimeout() {
-        if (!callback_called_) {
-            makeSERVFAIL();
-            callCallback(false);
-        }
-        assert(outstanding_events_ > 0);
-        --outstanding_events_;
-        stop();
-    }
-
-    virtual void clientTimeout() {
-        if (!callback_called_) {
-            makeSERVFAIL();
-            callCallback(false);
-        }
-        assert(outstanding_events_ > 0);
-        --outstanding_events_;
-        stop();
-    }
-
-    // If the callback has not been called yet, call it now
-    // If success is true, we call 'success' with our answer_message
-    // If it is false, we call failure()
-    void callCallback(bool success) {
-        if (!callback_called_) {
-            callback_called_ = true;
-            if (success) {
-                resolvercallback_->success(answer_message_);
-            } else {
-                resolvercallback_->failure();
-            }
-        }
-    }
-
-    virtual void stop() {
-        // if we cancel our timers, we will still get an event for
-        // that, so we cannot delete ourselves just yet (those events
-        // would be bound to a deleted object)
-        // cancel them one by one, both cancels should get us back
-        // here again.
-        // same goes if we have an outstanding query (can't delete
-        // until that one comes back to us)
-        lookup_timer.cancel();
-        client_timer.cancel();
-        if (outstanding_events_ > 0) {
-            return;
-        } else {
-            delete this;
-        }
-    }
-
-    // This function is used as callback from DNSQuery.
-    virtual void operator()(IOFetch::Result result) {
-        // XXX is this the place for TCP retry?
-        assert(outstanding_events_ > 0);
-        --outstanding_events_;
-        if (result != IOFetch::TIME_OUT) {
-            // we got an answer
-            Message incoming(Message::PARSE);
-            InputBuffer ibuf(buffer_->getData(), buffer_->getLength());
-            incoming.fromWire(ibuf);
-            isc::resolve::copyResponseMessage(incoming, answer_message_);
-            callCallback(true);
-        }
-
-        stop();
-    }
-
-    // Clear the answer parts of answer_message, and set the rcode
-    // to servfail
-    void makeSERVFAIL() {
-        isc::resolve::makeErrorMessage(answer_message_, Rcode::SERVFAIL());
-    }
-};
-
-}
-
-AbstractRunningQuery*
-RecursiveQuery::resolve(const QuestionPtr& question,
-    const isc::resolve::ResolverInterface::CallbackPtr callback)
-{
-    IOService& io = dns_service_.getIOService();
-
-    MessagePtr answer_message(new Message(Message::RENDER));
-    isc::resolve::initResponseMessage(*question, *answer_message);
-
-    OutputBufferPtr buffer(new OutputBuffer(0));
-
-    // First try to see if we have something cached in the messagecache
-    LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_TRACE, RESLIB_RESOLVE)
-              .arg(questionText(*question)).arg(1);
-    if (cache_.lookup(question->getName(), question->getType(),
-                      question->getClass(), *answer_message) &&
-        answer_message->getRRCount(Message::SECTION_ANSWER) > 0) {
-        // Message found, return that
-        LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CACHE, RESLIB_RECQ_CACHE_FIND)
-                  .arg(questionText(*question)).arg(1);
-
-        // TODO: err, should cache set rcode as well?
-        answer_message->setRcode(Rcode::NOERROR());
-        callback->success(answer_message);
-    } else {
-        // Perhaps we only have the one RRset?
-        // TODO: can we do this? should we check for specific types only?
-        RRsetPtr cached_rrset = cache_.lookup(question->getName(),
-                                              question->getType(),
-                                              question->getClass());
-        if (cached_rrset) {
-            // Found single RRset in cache
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CACHE, RESLIB_RRSET_FOUND)
-                      .arg(questionText(*question)).arg(1);
-            answer_message->addRRset(Message::SECTION_ANSWER,
-                                     cached_rrset);
-            answer_message->setRcode(Rcode::NOERROR());
-            callback->success(answer_message);
-        } else {
-            // Message not found in cache, start recursive query.  It will
-            // delete itself when it is done
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_TRACE, RESLIB_RECQ_CACHE_NO_FIND)
-                      .arg(questionText(*question)).arg(1);
-            return (new RunningQuery(io, *question, answer_message,
-                                     test_server_, buffer, callback,
-                                     query_timeout_, client_timeout_,
-                                     lookup_timeout_, retries_, nsas_,
-                                     cache_, rtt_recorder_));
-        }
-    }
-    return (NULL);
-}
-
-AbstractRunningQuery*
-RecursiveQuery::resolve(const Question& question,
-                        MessagePtr answer_message,
-                        OutputBufferPtr buffer,
-                        DNSServer* server)
-{
-    // XXX: eventually we will need to be able to determine whether
-    // the message should be sent via TCP or UDP, or sent initially via
-    // UDP and then fall back to TCP on failure, but for the moment
-    // we're only going to handle UDP.
-    IOService& io = dns_service_.getIOService();
-
-    isc::resolve::ResolverInterface::CallbackPtr crs(
-        new isc::resolve::ResolverCallbackServer(server));
-
-    // TODO: general 'prepareinitialanswer'
-    answer_message->setOpcode(isc::dns::Opcode::QUERY());
-    answer_message->addQuestion(question);
-
-    // First try to see if we have something cached in the messagecache
-    LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_TRACE, RESLIB_RESOLVE)
-              .arg(questionText(question)).arg(2);
-
-    if (cache_.lookup(question.getName(), question.getType(),
-                      question.getClass(), *answer_message) &&
-        answer_message->getRRCount(Message::SECTION_ANSWER) > 0) {
-
-        // Message found, return that
-        LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CACHE, RESLIB_RECQ_CACHE_FIND)
-                  .arg(questionText(question)).arg(2);
-        // TODO: err, should cache set rcode as well?
-        answer_message->setRcode(Rcode::NOERROR());
-        crs->success(answer_message);
-    } else {
-        // Perhaps we only have the one RRset?
-        // TODO: can we do this? should we check for specific types only?
-        RRsetPtr cached_rrset = cache_.lookup(question.getName(),
-                                              question.getType(),
-                                              question.getClass());
-        if (cached_rrset) {
-            // Found single RRset in cache
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_CACHE, RESLIB_RRSET_FOUND)
-                      .arg(questionText(question)).arg(2);
-            answer_message->addRRset(Message::SECTION_ANSWER,
-                                     cached_rrset);
-            answer_message->setRcode(Rcode::NOERROR());
-            crs->success(answer_message);
-
-        } else {
-            // Message not found in cache, start recursive query.  It will
-            // delete itself when it is done
-            LOG_DEBUG(isc::resolve::logger, RESLIB_DBG_TRACE, RESLIB_RECQ_CACHE_NO_FIND)
-                      .arg(questionText(question)).arg(2);
-            return (new RunningQuery(io, question, answer_message,
-                                     test_server_, buffer, crs, query_timeout_,
-                                     client_timeout_, lookup_timeout_, retries_,
-                                     nsas_, cache_, rtt_recorder_));
-        }
-    }
-    return (NULL);
-}
-
-AbstractRunningQuery*
-RecursiveQuery::forward(ConstMessagePtr query_message,
-    MessagePtr answer_message,
-    OutputBufferPtr buffer,
-    DNSServer* server,
-    isc::resolve::ResolverInterface::CallbackPtr callback)
-{
-    // XXX: eventually we will need to be able to determine whether
-    // the message should be sent via TCP or UDP, or sent initially via
-    // UDP and then fall back to TCP on failure, but for the moment
-    // we're only going to handle UDP.
-    IOService& io = dns_service_.getIOService();
-
-    if (!callback) {
-        callback.reset(new isc::resolve::ResolverCallbackServer(server));
-    }
-
-    // TODO: general 'prepareinitialanswer'
-    answer_message->setOpcode(isc::dns::Opcode::QUERY());
-    ConstQuestionPtr question = *query_message->beginQuestion();
-    answer_message->addQuestion(*question);
-
-    // implement the simplest forwarder, which will pass
-    // everything throught without interpretation, except
-    // QID, port number. The response will not be cached.
-    // It will delete itself when it is done
-    return (new ForwardQuery(io, query_message, answer_message,
-                             upstream_, buffer, callback, query_timeout_,
-                             client_timeout_, lookup_timeout_));
-}
-
-} // namespace asiodns
-} // namespace isc
diff --git a/src/lib/resolve/recursive_query.h b/src/lib/resolve/recursive_query.h
deleted file mode 100644 (file)
index 2875441..0000000
+++ /dev/null
@@ -1,229 +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 RECURSIVE_QUERY_H
-#define RECURSIVE_QUERY_H 1
-
-#include <util/buffer.h>
-#include <asiodns/dns_service.h>
-#include <asiodns/dns_server.h>
-#include <nsas/nameserver_address_store.h>
-#include <cache/resolver_cache.h>
-
-namespace isc {
-namespace asiodns {
-
-/// \brief RTT Recorder
-///
-/// Used for testing, this class will hold the set of round-trip times to
-/// nameservers for the current recursive query.
-///
-/// A pointer to an object of this class is passed to RecursiveQuery which in
-/// turn passes it to the created RunningQuery class.  When a running query
-/// completes, its RTT is passed to the RTT Recorder object.
-class RttRecorder {
-public:
-    /// \brief Record Time
-    ///
-    /// Adds a round-trip time to the internal vector of times.
-    ///
-    /// \param rtt RTT to record.
-    void addRtt(uint32_t rtt) {
-        rtt_.push_back(rtt);
-    }
-
-    /// \brief Return RTT Vector
-    std::vector<uint32_t> getRtt() const {
-        return rtt_;
-    }
-
-private:
-    std::vector<uint32_t>   rtt_;   ///< Stored round-trip times
-};
-
-typedef std::vector<std::pair<std::string, uint16_t> > AddressVector;
-
-/// \brief A Running query
-///
-/// This base class represents an active running query object;
-/// i.e. an outstanding query to an authoritative name server or
-/// upstream server (when running in forwarder mode).
-///
-/// It can not be instantiated directly, but is created by
-/// RecursiveQuery::resolve() and RecursiveQuery::forward().
-///
-/// Its only public method is its destructor, and that should in theory
-/// not be called either except in some unit tests. Instances should
-/// delete themselves when the query is finished.
-class AbstractRunningQuery {
-protected:
-    AbstractRunningQuery() {};
-public:
-    virtual ~AbstractRunningQuery() {};
-};
-
-/// \brief Recursive Query
-///
-/// The \c RecursiveQuery class provides a layer of abstraction around
-/// the ASIO code that carries out an upstream query.
-
-class RecursiveQuery {
-    ///
-    /// \name Constructors
-    ///
-    //@{
-public:
-    /// \brief Constructor
-    ///
-    /// This is currently the only way to construct \c RecursiveQuery
-    /// object. If the addresses of the forward nameservers is specified,
-    /// and every upstream query will be sent to one random address, and
-    /// the result sent back directly. If not, it will do full resolving.
-    ///
-    /// \param dns_service The DNS Service to perform the recursive
-    ///        query on.
-    /// \param nsas Nameserver address store, used to hold information about zone
-    ///        nameservers.
-    /// \param cache Resolver cache object, used to hold information about retrieved
-    ///        records.
-    /// \param upstream Addresses and ports of the upstream servers
-    ///        to forward queries to.
-    /// \param upstream_root Addresses and ports of the root servers
-    ///        to use when resolving.
-    /// \param query_timeout Timeout value for queries we sent, in ms
-    /// \param client_timeout Timeout value for when we send back an
-    ///        error, in ms
-    /// \param lookup_timeout Timeout value for when we give up, in ms
-    /// \param retries how many times we try again (0 means just send and
-    ///     and return if it returs).
-    RecursiveQuery(DNSServiceBase& dns_service,
-                   isc::nsas::NameserverAddressStore& nsas,
-                   isc::cache::ResolverCache& cache,
-                   const std::vector<std::pair<std::string, uint16_t> >&
-                   upstream,
-                   const std::vector<std::pair<std::string, uint16_t> >&
-                   upstream_root,
-                   int query_timeout = 2000,
-                   int client_timeout = 4000,
-                   int lookup_timeout = 30000,
-                   unsigned retries = 3);
-    //@}
-
-    /// \brief Set Round-Trip Time Recorder
-    ///
-    /// Sets the RTT recorder object.  This is not accessed directly, instead
-    /// it is passed to created RunningQuery objects.
-    ///
-    /// \param recorder Pointer to the RTT recorder object used to hold RTTs.
-    void setRttRecorder(boost::shared_ptr<RttRecorder>& recorder);
-
-    /// \brief Initiate resolving
-    ///
-    /// When sendQuery() is called, a (set of) message(s) is sent
-    /// asynchronously. If upstream servers are set, one is chosen
-    /// and the response (if any) from that server will be returned.
-    ///
-    /// If not upstream is set, a root server is chosen from the
-    /// root_servers, and the RunningQuery shall do a full resolve
-    /// (i.e. if the answer is a delegation, it will be followed, etc.)
-    /// until there is an answer or an error.
-    ///
-    /// When there is a response or an error and we give up, the given
-    /// CallbackPtr object shall be called (with either success() or
-    /// failure(). See ResolverInterface::Callback for more information.
-    ///
-    /// \param question The question being answered <qname/qclass/qtype>
-    /// \param callback Callback object. See
-    ///        \c ResolverInterface::Callback for more information
-    AbstractRunningQuery* resolve(const isc::dns::QuestionPtr& question,
-        const isc::resolve::ResolverInterface::CallbackPtr callback);
-
-
-    /// \brief Initiates resolving for the given question.
-    ///
-    /// This actually calls the previous sendQuery() with a default
-    /// callback object, which calls resume() on the given DNSServer
-    /// object.
-    ///
-    /// \param question The question being answered <qname/qclass/qtype>
-    /// \param answer_message An output Message into which the final response will
-    ///        be copied.
-    /// \param buffer An output buffer into which the intermediate responses will
-    ///        be copied.
-    /// \param server A pointer to the \c DNSServer object handling the client
-    /// \return A pointer to the active AbstractRunningQuery object
-    ///         created by this call (if any); this object should delete
-    ///         itself in normal circumstances, and can normally be ignored
-    ///         by the caller, but a pointer is returned for use-cases
-    ///         such as unit tests.
-    ///         Returns NULL if the data was found internally and no actual
-    ///         query was sent.
-    AbstractRunningQuery* resolve(const isc::dns::Question& question,
-                          isc::dns::MessagePtr answer_message,
-                          isc::util::OutputBufferPtr buffer,
-                          DNSServer* server);
-
-    /// \brief Initiates forwarding for the given query.
-    ///
-    ///  Others parameters are same with the parameters of
-    ///  function resolve().
-    ///
-    /// \param query_message the full query got from client.
-    /// \param answer_message the full answer received from other server.
-    /// \param buffer Output buffer into which the responses will be copied.
-    /// \param server Server object that handles receipt and processing of the
-    ///               received messages.
-    /// \param callback callback object
-    /// \return A pointer to the active ForwardQuery created by this call;
-    ///         this object should delete itself in normal circumstances,
-    ///         and can normally be ignored by the caller, but a pointer
-    ///         is returned for use-cases such as unit tests.
-    AbstractRunningQuery* forward(isc::dns::ConstMessagePtr query_message,
-                 isc::dns::MessagePtr answer_message,
-                 isc::util::OutputBufferPtr buffer,
-                 DNSServer* server,
-                 isc::resolve::ResolverInterface::CallbackPtr callback =
-                     isc::resolve::ResolverInterface::CallbackPtr());
-
-    /// \brief Set Test Server
-    ///
-    /// This method is *only* for unit testing the class.  If set, it enables
-    /// recursive behaviour but, regardless of responses received, sends every
-    /// query to the test server.
-    ///
-    /// The test server is enabled by setting a non-zero port number.
-    ///
-    /// \param address IP address of the test server.
-    /// \param port Port number of the test server
-    void setTestServer(const std::string& address, uint16_t port);
-
-private:
-    DNSServiceBase& dns_service_;
-    isc::nsas::NameserverAddressStore& nsas_;
-    isc::cache::ResolverCache& cache_;
-    boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
-        upstream_;
-    boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
-        upstream_root_;
-    std::pair<std::string, uint16_t> test_server_;
-    int query_timeout_;
-    int client_timeout_;
-    int lookup_timeout_;
-    unsigned retries_;
-    boost::shared_ptr<RttRecorder>  rtt_recorder_;  ///< Round-trip time recorder
-};
-
-}      // namespace asiodns
-}      // namespace isc
-#endif // RECURSIVE_QUERY_H
diff --git a/src/lib/resolve/resolve.cc b/src/lib/resolve/resolve.cc
deleted file mode 100644 (file)
index cfd6217..0000000
+++ /dev/null
@@ -1,78 +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 <resolve/resolve.h>
-
-#include <dns/message.h>
-#include <dns/opcode.h>
-
-using namespace isc::dns;
-
-namespace {
-    class SectionInserter {
-    public:
-        SectionInserter(MessagePtr message, const Message::Section sect) :
-            message_(message), section_(sect)
-        {}
-        void operator()(const RRsetPtr rrset) {
-            message_->addRRset(section_, rrset);
-        }
-        MessagePtr message_;
-        const Message::Section section_;
-    };
-}
-
-namespace isc {
-namespace resolve {
-
-void
-makeErrorMessage(MessagePtr answer_message,
-                 const Rcode& error_code)
-{
-    answer_message->clearSection(Message::SECTION_ANSWER);
-    answer_message->clearSection(Message::SECTION_AUTHORITY);
-    answer_message->clearSection(Message::SECTION_ADDITIONAL);
-
-    answer_message->setRcode(error_code);
-}
-
-void initResponseMessage(const isc::dns::Message& query_message,
-                         isc::dns::Message& response_message)
-{
-    response_message.setOpcode(query_message.getOpcode());
-    response_message.setQid(query_message.getQid());
-    assert(response_message.getRRCount(Message::SECTION_QUESTION) == 0);
-    response_message.appendSection(Message::SECTION_QUESTION,
-        query_message);
-}
-
-void initResponseMessage(const isc::dns::Question& question,
-                         isc::dns::Message& response_message)
-{
-    response_message.setOpcode(isc::dns::Opcode::QUERY());
-    response_message.addQuestion(question);
-}
-
-void copyResponseMessage(const Message& source, MessagePtr target) {
-    target->setRcode(source.getRcode());
-
-    target->appendSection(Message::SECTION_ANSWER, source);
-    target->appendSection(Message::SECTION_AUTHORITY, source);
-    target->appendSection(Message::SECTION_ADDITIONAL, source);
-}
-
-
-} // namespace resolve
-} // namespace isc
-
diff --git a/src/lib/resolve/resolve.h b/src/lib/resolve/resolve.h
deleted file mode 100644 (file)
index c7ff195..0000000
+++ /dev/null
@@ -1,95 +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 ISC_RESOLVE_H
-#define ISC_RESOLVE_H 1
-
-/// This file includes all other libresolve headers, and provides
-/// several helper functions used in resolving.
-
-#include <resolve/resolver_interface.h>
-#include <resolve/resolver_callback.h>
-#include <resolve/response_classifier.h>
-
-#include <dns/rcode.h>
-
-namespace isc {
-namespace resolve {
-
-/// \brief Create an error response
-///
-/// Clears the answer, authority, and additional section of the
-/// given MessagePtr and sets the given error code
-///
-/// Notes: Assuming you have already done initial preparations
-/// on the given answer message (copy the opcode, qid and question
-/// section), you can simply use this to create an error response.
-///
-/// \param answer_message The message to clear and place the error in
-/// \param error_code The error Rcode
-void makeErrorMessage(isc::dns::MessagePtr answer_message,
-                      const isc::dns::Rcode& error_code);
-
-
-/// \brief Initialize a response message
-///
-/// Based on the given query message, this fills in the very
-/// first details of the response (i.e. the Question section and
-/// the Opcode). This allows for direct usage of makeErrorMessage(),
-/// as well as ResolveCache.lookup().
-///
-/// Raises an isc::dns::InvalidMessageOperation if reponse_message is
-/// not in RENDER mode.
-///
-/// \param query_message The query message to take the Question, Qid,
-///                      and Opcode from.
-/// \param response_message The fresh response message to initialize
-///                         (must be in RENDER mode)
-void initResponseMessage(const isc::dns::Message& query_message,
-                         isc::dns::Message& response_message);
-
-
-/// \brief Initialize a response message
-///
-/// Based on the given question, this fills in the very
-/// first details of the response (i.e. the Question section and the
-/// Opcode Query). This allows for direct usage of makeErrorMessage(),
-/// as well as ResolveCache.lookup().
-///
-/// Raises an isc::dns::InvalidMessageOperation if reponse_message is
-/// not in RENDER mode.
-///
-/// \param question The question to place in the Question section
-/// \param response_message The fresh response message to initialize
-///                         (must be in RENDER mode)
-void initResponseMessage(const isc::dns::Question& question,
-                         isc::dns::Message& response_message);
-
-
-/// \brief Copies the parts relevant for a DNS response to the
-/// target message
-///
-/// This adds all the RRsets in the answer, authority and
-/// additional sections to the target, as well as the response
-/// code
-/// \param source The Message to copy the data from
-/// \param target The Message to copy the data to
-void copyResponseMessage(const isc::dns::Message& source,
-                         isc::dns::MessagePtr target);
-
-
-} // namespace resolve
-} // namespace isc
-
-#endif // ISC_RESOLVE_H_
diff --git a/src/lib/resolve/resolve_log.cc b/src/lib/resolve/resolve_log.cc
deleted file mode 100644 (file)
index e41d8d2..0000000
+++ /dev/null
@@ -1,26 +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.
-
-/// Defines the logger used by the NSAS
-
-#include <resolve/resolve_log.h>
-
-namespace isc {
-namespace resolve {
-
-isc::log::Logger logger("reslib");  // Distinct from "resolver"
-
-} // namespace resolve
-} // namespace isc
-
diff --git a/src/lib/resolve/resolve_log.h b/src/lib/resolve/resolve_log.h
deleted file mode 100644 (file)
index 15a7a72..0000000
+++ /dev/null
@@ -1,53 +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 RESOLVE_LOG_H
-#define RESOLVE_LOG_H
-
-#include <log/macros.h>
-#include "resolve_messages.h"
-
-namespace isc {
-namespace resolve {
-
-/// \brief Resolver Library Logging
-///
-/// Defines the levels used to output debug messages in the resolver library.
-/// Note that higher numbers equate to more verbose (and detailed) output.
-
-// The first level traces normal operations
-const int RESLIB_DBG_TRACE = DBGLVL_TRACE_BASIC;
-
-// The next level extends the normal operations and records the results of the
-// lookups.
-const int RESLIB_DBG_RESULTS = DBGLVL_TRACE_BASIC_DATA;
-
-// Report cache lookups and results
-const int RESLIB_DBG_CACHE = DBGLVL_TRACE_DETAIL_DATA;
-
-// Indicate when callbacks are called
-const int RESLIB_DBG_CB = DBGLVL_TRACE_DETAIL_DATA + 10;
-
-
-/// \brief Resolver Library Logger
-///
-/// Define the logger used to log messages.  We could define it in multiple
-/// modules, but defining in a single module and linking to it saves time and
-/// space.
-extern isc::log::Logger logger;
-
-} // namespace resolve
-} // namespace isc
-
-#endif // RESOLVE_LOG_H
diff --git a/src/lib/resolve/resolve_messages.mes b/src/lib/resolve/resolve_messages.mes
deleted file mode 100644 (file)
index c89dedb..0000000
+++ /dev/null
@@ -1,229 +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.
-
-$NAMESPACE isc::resolve
-
-% RESLIB_ANSWER answer received in response to query for <%1>
-A debug message reporting that an answer has been received to an upstream
-query for the specified question.  Previous debug messages will have
-indicated the server to which the question was sent.
-
-% RESLIB_CNAME CNAME received in response to query for <%1>
-A debug message recording that CNAME response has been received to an
-upstream query for the specified question.  Previous debug messages will
-have indicated the server to which the question was sent.
-
-% RESLIB_DEEPEST did not find <%1> in cache, deepest delegation found is %2
-A debug message, a cache lookup did not find the specified <name,
-class, type> tuple in the cache; instead, the deepest delegation found
-is indicated.
-
-% RESLIB_EMPTY_RESPONSE empty response received to query for <%1>
-A debug message, the response to the specified query from an upstream
-nameserver did not contain anything in the answer or authority sections,
-although in all other respects it was a valid response.  A SERVFAIL will
-be returned to the system making the original query.
-
-% RESLIB_ERROR_RESPONSE unspecified error received in response to query for <%1>
-A debug message, the response to the specified query to an upstream
-nameserver indicated that the response was classified as an erroneous
-response, but that the nature of the error cannot be identified.
-A SERVFAIL will be returned to the system making the original query.
-
-% RESLIB_EXTRADATA_RESPONSE extra data in response to query for <%1>
-A debug message indicating that the response to the specified query
-from an upstream nameserver contained too much data.  This can happen if
-an ANY query was sent and the answer section in the response contained
-multiple RRs with different names.  A SERVFAIL will be returned to the
-system making the original query.
-
-% RESLIB_FOLLOW_CNAME following CNAME chain to <%1>
-A debug message, a CNAME response was received and another query is
-being issued for the <name, class, type> tuple.
-
-% RESLIB_INVALID_NAMECLASS_RESPONSE invalid name or class in response to query for <%1>
-A debug message, the response to the specified query from an upstream
-nameserver (as identified by the ID of the response) contained either
-an answer not matching the query name or an answer having a different
-class to that queried for.  A SERVFAIL will be returned to the system
-making the original query.
-
-% RESLIB_INVALID_QNAME_RESPONSE invalid name or class in response to query for <%1>
-A debug message, the response to the specified query from an upstream
-nameserver (as identified by the ID of the response) contained a name
-in the question section that did not match that of the query. A SERVFAIL
-will be returned to the system making the original query.
-
-% RESLIB_INVALID_TYPE_RESPONSE invalid name or class in response to query for <%1>
-A debug message, the response to the specified query from an upstream
-nameserver (as identified by the ID of the response) contained an
-invalid type field. A SERVFAIL will be returned to the system making
-the original query.
-
-% RESLIB_LONG_CHAIN CNAME received in response to query for <%1>: CNAME chain length exceeded
-A debug message recording that a CNAME response has been received to an upstream
-query for the specified question (Previous debug messages will have indicated
-the server to which the question was sent).  However, receipt of this CNAME
-has meant that the resolver has exceeded the CNAME chain limit (a CNAME chain
-is where on CNAME points to another) and so an error is being returned.
-
-% RESLIB_MULTIPLE_CLASS_RESPONSE response to query for <%1> contained multiple RRsets with different classes
-A debug message reporting that the response to an upstream query for
-the specified name contained multiple RRsets in the answer and not all
-were of the same class.  This is a violation of the standard and so a
-SERVFAIL will be returned.
-
-% RESLIB_NOTSINGLE_RESPONSE response to query for <%1> was not a response
-A debug message, the response to the specified query from an upstream
-nameserver was a CNAME that had multiple RRs in the RRset.  This is
-an invalid response according to the standards so a SERVFAIL will be
-returned to the system making the original query.
-
-% RESLIB_NOT_ONE_QNAME_RESPONSE not one question in response to query for <%1>
-A debug message, the response to the specified query from an upstream
-nameserver (as identified by the ID of the response) did not contain
-one name in the question section as required by the standard. A SERVFAIL
-will be returned to the system making the original query.
-
-% RESLIB_NOT_RESPONSE response to query for <%1> was not a response
-A debug message, the response to the specified query from an upstream
-nameserver (as identified by the ID of the response) did not have the QR
-bit set (thus indicating that the packet was a query, not a response).
-A SERVFAIL will be returned to the system making the original query.
-
-% RESLIB_NO_NS_RRSET no NS RRSet in referral response received to query for <%1>
-A debug message, this indicates that a response was received for the specified
-query and was categorized as a referral.  However, the received message did
-not contain any NS RRsets.  This may indicate a programming error in the
-response classification code.
-
-% RESLIB_NSAS_LOOKUP looking up nameserver for zone %1 in the NSAS
-A debug message, the RunningQuery object is querying the NSAS for the
-nameservers for the specified zone.
-
-% RESLIB_NXDOM_NXRR NXDOMAIN/NXRRSET received in response to query for <%1>
-A debug message recording that either a NXDOMAIN or an NXRRSET response has
-been received to an upstream query for the specified question.  Previous debug
-messages will have indicated the server to which the question was sent.
-
-% RESLIB_OPCODE_RESPONSE response to query for <%1> did not have query opcode
-A debug message, the response to the specified query from an upstream
-nameserver was a response that did not have the opcode set to that of
-a query.  According to the standards, this is an invalid response to
-the query that was made, so a SERVFAIL will be returned to the system
-making the original query.
-
-% RESLIB_PROTOCOL protocol error in answer for %1:  %3
-A debug message indicating that a protocol error was received.  As there
-are no retries left, an error will be reported.
-
-% RESLIB_PROTOCOL_RETRY protocol error in answer for %1: %2 (retries left: %3)
-A debug message indicating that a protocol error was received and that
-the resolver is repeating the query to the same nameserver.  After this
-repeated query, there will be the indicated number of retries left.
-
-% RESLIB_RCODE_RETURNED response to query for <%1> returns RCODE of %2
-A debug message, the response to the specified query indicated an error
-that is not covered by a specific code path.  A SERVFAIL will be returned.
-
-% RESLIB_RECQ_CACHE_FIND found <%1> in the cache (resolve() instance %2)
-This is a debug message and indicates that a RecursiveQuery object found
-the specified <name, class, type> tuple in the cache.  The instance number
-at the end of the message indicates which of the two resolve() methods has
-been called.
-
-% RESLIB_RECQ_CACHE_NO_FIND did not find <%1> in the cache, starting RunningQuery (resolve() instance %2)
-This is a debug message and indicates that the look in the cache made by the
-RecursiveQuery::resolve() method did not find an answer, so a new RunningQuery
-object has been created to resolve the question.  The instance number at
-the end of the message indicates which of the two resolve() methods has
-been called.
-
-% RESLIB_REFERRAL referral received in response to query for <%1>
-A debug message recording that a referral response has been received to an
-upstream query for the specified question.  Previous debug messages will
-have indicated the server to which the question was sent.
-
-% RESLIB_REFER_ZONE referred to zone %1
-A debug message indicating that the last referral message was to the specified
-zone.
-
-% RESLIB_RESOLVE asked to resolve <%1> (resolve() instance %2)
-A debug message, the RecursiveQuery::resolve method has been called to resolve
-the specified <name, class, type> tuple.  The first action will be to lookup
-the specified tuple in the cache.  The instance number at the end of the
-message indicates which of the two resolve() methods has been called.
-
-% RESLIB_RRSET_FOUND found single RRset in the cache when querying for <%1> (resolve() instance %2)
-A debug message, indicating that when RecursiveQuery::resolve queried the
-cache, a single RRset was found which was put in the answer.  The instance
-number at the end of the message indicates which of the two resolve()
-methods has been called.
-
-% RESLIB_RTT round-trip time of last query calculated as %1 ms
-A debug message giving the round-trip time of the last query and response.
-
-% RESLIB_RUNQ_CACHE_FIND found <%1> in the cache
-This is a debug message and indicates that a RunningQuery object found
-the specified <name, class, type> tuple in the cache.
-
-% RESLIB_RUNQ_CACHE_LOOKUP looking up <%1> in the cache
-This is a debug message and indicates that a RunningQuery object has made
-a call to its doLookup() method to look up the specified <name, class, type>
-tuple, the first action of which will be to examine the cache.
-
-% RESLIB_RUNQ_FAIL failure callback - nameservers are unreachable
-A debug message indicating that a RunningQuery's failure callback has been
-called because all nameservers for the zone in question are unreachable.
-
-% RESLIB_RUNQ_SUCCESS success callback - sending query to %1
-A debug message indicating that a RunningQuery's success callback has been
-called because a nameserver has been found, and that a query is being sent
-to the specified nameserver.
-
-% RESLIB_TCP_TRUNCATED TCP response to query for %1 was truncated
-This is a debug message logged when a response to the specified  query to an
-upstream nameserver returned a response with the TC (truncation) bit set.  This
-is treated as an error by the code.
-
-% RESLIB_TEST_SERVER setting test server to %1(%2)
-This is a warning message only generated in unit tests.  It indicates
-that all upstream queries from the resolver are being routed to the
-specified server, regardless of the address of the nameserver to which
-the query would normally be routed.  If seen during normal operation,
-please submit a bug report.
-
-% RESLIB_TEST_UPSTREAM sending upstream query for <%1> to test server at %2
-This is a debug message and should only be seen in unit tests.  A query for
-the specified <name, class, type> tuple is being sent to a test nameserver
-whose address is given in the message.
-
-% RESLIB_TIMEOUT query <%1> to %2 timed out
-A debug message indicating that the specified upstream query has timed out and
-there are no retries left.
-
-% RESLIB_TIMEOUT_RETRY query <%1> to %2 timed out, re-trying (retries left: %3)
-A debug message indicating that the specified query has timed out and that
-the resolver is repeating the query to the same nameserver.  After this
-repeated query, there will be the indicated number of retries left.
-
-% RESLIB_TRUNCATED response to query for <%1> was truncated, re-querying over TCP
-A debug message, this indicates that the response to the specified query was
-truncated and that the resolver will be re-querying over TCP.  There are
-various reasons why responses may be truncated, so this message is normal and
-gives no cause for concern.
-
-% RESLIB_UPSTREAM sending upstream query for <%1> to %2
-A debug message indicating that a query for the specified <name, class, type>
-tuple is being sent to a nameserver whose address is given in the message.
diff --git a/src/lib/resolve/resolver_callback.cc b/src/lib/resolve/resolver_callback.cc
deleted file mode 100644 (file)
index c0db55e..0000000
+++ /dev/null
@@ -1,36 +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 <resolve/resolver_callback.h>
-
-namespace isc {
-namespace resolve {
-
-void
-ResolverCallbackServer::success(const isc::dns::MessagePtr response)
-{
-    // ignore our response here
-    (void)response;
-    
-    server_->resume(true);
-}
-
-void
-ResolverCallbackServer::failure()
-{
-    server_->resume(false);
-}
-
-} // namespace resolve
-} // namespace isc
diff --git a/src/lib/resolve/resolver_callback.h b/src/lib/resolve/resolver_callback.h
deleted file mode 100644 (file)
index 9a24501..0000000
+++ /dev/null
@@ -1,50 +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 ISC_RESOLVER_CALLBACK_H
-#define ISC_RESOLVER_CALLBACK_H 1
-
-#include <asiodns/dns_server.h>
-#include <dns/message.h>
-
-#include <resolve/resolver_interface.h>
-
-namespace isc {
-namespace resolve {
-
-/// \short Standard Callback for sendQuery for DNSServer instances
-///
-/// This is a standard ResolverInterface::Callback implementation
-/// that is used by Resolver; when RunningQuery finishes and has either
-/// some data or an error, DNSServer::resume() will be called.
-///
-/// This class will ignore the response MessagePtr in the callback,
-/// as the server itself should also have a reference.
-class ResolverCallbackServer : public ResolverInterface::Callback {
-public:
-    ResolverCallbackServer(asiodns::DNSServer* server) :
-        server_(server->clone()) {}
-    ~ResolverCallbackServer() { delete server_; };
-    
-    void success(const isc::dns::MessagePtr response);
-    void failure();
-
-private:
-    asiodns::DNSServer* server_;
-};
-
-} //namespace resolve
-} //namespace isc
-
-#endif // ISC_RESOLVER_CALLBACK_H_
diff --git a/src/lib/resolve/resolver_interface.h b/src/lib/resolve/resolver_interface.h
deleted file mode 100644 (file)
index 5002c80..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (C) 2010  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 RESOLVER_INTERFACE_H
-#define RESOLVER_INTERFACE_H
-
-#include <dns/message.h>
-
-///
-/// \file resolver_interface.h
-/// \short Interface to resolver.
-///
-/// This file contains an interface for the resolver. By subclassing
-/// this abstract interface, other parts of the system can ask the
-/// resolver to do some resolving too.
-///
-/// This is done by creating a subclass of ResolverInterface::Callback,
-/// which defines what to do with the result, and then calling resolve()
-/// on the ResolverInterface implementation.
-///
-/// One default Callback subclass is provided right now, in
-/// resolver_callback.[h|cc], which calls resumse() on a given DNSServer
-///
-
-namespace isc {
-namespace resolve {
-
-///
-/// \short Abstract interface to the resolver.
-///
-/// Abstract interface to the resolver. The NameserverAddressStore uses this
-/// to ask for addresses. It is here because resolver does not yet exist.
-///
-/// It is abstract to allow tests pass dummy resolvers.
-///
-class ResolverInterface {
-    public:
-        /// \short An abstract callback for when the resolver is done.
-        ///
-        /// You can pass an instance of a subclass of this (as a
-        /// CallbackPtr) to RecursiveQuery::sendQuery(), and when it
-        /// is done, it will either call success() if there is an
-        /// answer MessagePtr, or failure(), if the resolver was not
-        /// able to find anything.
-        ///
-        /// Note that a result Message does not necessarily contain
-        /// the actual answer (it could be a noerror/nodata response).
-        class Callback {
-            public:
-                /// \short Some data arrived.
-                virtual void success(const isc::dns::MessagePtr response) = 0;
-                
-                ///
-                ///\short No data available.
-                ///
-                ///\todo Provide error reason (result of the
-                ///      classification call, for instance? We'd also
-                ///      need some way to say 'everything times out')
-                ///
-                virtual void failure() = 0;
-
-                /// \short Virtual destructor, so descendants are cleaned up
-                virtual ~Callback() {};
-        };
-
-        typedef boost::shared_ptr<Callback> CallbackPtr;
-
-        ///
-        ///\short Ask a question.
-        ///
-        /// Asks the resolver a question. Once the answer is ready
-        /// the callback is called.
-        ///
-        /// \param question What to ask. The resolver will decide who.
-        /// \param callback What should happen when the answer is ready.
-        ///
-        virtual void resolve(const isc::dns::QuestionPtr& question,
-            const CallbackPtr& callback) = 0;
-
-        /// \short Virtual destructor, so descendants are properly cleaned up
-        virtual ~ ResolverInterface() {}
-};
-
-} // namespace nsas
-} // namespace isc
-
-#endif //RESOLVER_INTERFACE_H
diff --git a/src/lib/resolve/response_classifier.cc b/src/lib/resolve/response_classifier.cc
deleted file mode 100644 (file)
index 27c5cfc..0000000
+++ /dev/null
@@ -1,279 +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.
-
-// $Id$
-
-#include <cstddef>
-#include <vector>
-
-#include <resolve/response_classifier.h>
-#include <dns/name.h>
-#include <dns/opcode.h>
-#include <dns/rcode.h>
-#include <dns/rrset.h>
-
-using namespace isc::dns;
-using namespace std;
-
-namespace isc {
-namespace resolve {
-
-// Classify the response in the "message" object.
-
-ResponseClassifier::Category ResponseClassifier::classify(
-    const Question& question, const Message& message, 
-    Name& cname_target, unsigned int& cname_count, bool tcignore
-    )
-{
-    // Check header bits
-    if (!message.getHeaderFlag(Message::HEADERFLAG_QR)) {
-        return (NOTRESPONSE);   // Query-response bit not set in the response
-    }
-
-    // We only recognise responses to queries here
-    if (message.getOpcode() != Opcode::QUERY()) {
-        return (OPCODE);
-    }
-
-    // Apparently have a response.  There must be a single question in it...
-    const vector<QuestionPtr> msgquestion(message.beginQuestion(),
-            message.endQuestion());
-    if (msgquestion.size() != 1) {
-        return (NOTONEQUEST); // Not one question in response question section
-    }
-
-    // ... and the question should be equal to the question given.
-    // XXX: This means that "question" may not be the question sent by the
-    // client.  In the case of a CNAME response, the qname of subsequent
-    // questions needs to be altered.
-    if (question != *(msgquestion[0])) {
-        return (MISMATQUEST);
-    }
-
-    // Check for Rcode-related errors.
-    const Rcode& rcode = message.getRcode();
-    if (rcode != Rcode::NOERROR()) {
-        if (rcode == Rcode::NXDOMAIN()) {
-
-            // No such domain.  According to RFC2308, the domain referred to by
-            // the QNAME does not exist, although there may be a CNAME in the
-            // answer section and there may be an SOA and/or NS RRs in the
-            // authority section (ignoring any DNSSEC RRs for now).
-            //
-            // Note the "may".  There may not be anything.  Also, note that if
-            // there is a CNAME in the answer section, the authoritative server
-            // has verified that the name given in the CNAME's RDATA field does
-            // not exist. And that if a CNAME is returned in the answer, then
-            // the QNAME of the RRs in the authority section will refer to the
-            // authority for the CNAME's RDATA and not to the original question.
-            //
-            // Without doing further classification, it is sufficient to say
-            // that if an NXDOMAIN is received, there was no translation of the
-            // QNAME available.
-            return (NXDOMAIN);  // Received NXDOMAIN from parent.
-
-        } else {
-
-            // Not NXDOMAIN but not NOERROR either.  Must be an RCODE-related
-            // error.
-            return (RCODE);
-        }
-    }
-
-    // All seems OK and we can start looking at the content.  However, one
-    // more header check remains - was the response truncated?  If so, we'll
-    // probably want to re-query over TCP.  However, in some circumstances we
-    // might want to go with what we have.  So give the caller the option of
-    // ignoring the TC bit.
-    if (message.getHeaderFlag(Message::HEADERFLAG_TC) && (!tcignore)) {
-        return (TRUNCATED);
-    }
-
-    // By the time we get here, we're assured that the packet format is correct.
-    // We now need to decide as to whether it is an answer, a CNAME, or a
-    // referral.  For this, we need to inspect the contents of the answer
-    // and authority sections.
-    const vector<RRsetPtr> answer(
-            message.beginSection(Message::SECTION_ANSWER),
-            message.endSection(Message::SECTION_ANSWER)
-            );
-    const vector<RRsetPtr> authority(
-            message.beginSection(Message::SECTION_AUTHORITY),
-            message.endSection(Message::SECTION_AUTHORITY)
-            );
-
-    // If there is nothing in the answer section, it is a referral - unless
-    // there is no NS in the authority section
-    if (answer.empty()) {
-        if (authority.empty()) {
-            return (EMPTY);
-        }
-        for (vector<RRsetPtr>::size_type i = 0; i < authority.size(); ++i) {
-            if (authority[i]->getType() == RRType::NS()) {
-                return (REFERRAL);
-            }
-        }
-        return (NXRRSET);
-    }
-
-    // Look at two cases - one RRset in the answer and multiple RRsets in
-    // the answer.
-    if (answer.size() == 1) {
-
-        // Does the name and class of the answer match that of the question?
-        if ((answer[0]->getName() == question.getName()) &&
-            (answer[0]->getClass() == question.getClass())) {
-
-            // It does.  How about the type of the response?  The response
-            // is an answer if the type matches that of the question, or if the
-            // question was for type ANY.  It is a CNAME reply if the answer
-            // type is CNAME.  And it is an error for anything else.
-            if ((answer[0]->getType() == question.getType()) ||
-                (question.getType() == RRType::ANY())) {
-                return (ANSWER);
-            } else if (answer[0]->getType() == RRType::CNAME()) {
-                RdataIteratorPtr it = answer[0]->getRdataIterator();
-                cname_target = Name(it->getCurrent().toText());
-                ++cname_count;
-                return (CNAME);
-            } else {
-                return (INVTYPE);
-            }
-        }
-        else {
-
-            // Either the name and/or class of the reply don't match that of
-            // the question.
-            return (INVNAMCLASS);
-        }
-    }
-
-    // There are multiple RRsets in the answer. They should all have the same
-    // QCLASS, else there is some error in the response.
-    for (vector<RRsetPtr>::size_type i = 1; i < answer.size(); ++i) {
-        if (answer[0]->getClass() != answer[i]->getClass()) {
-            return (MULTICLASS);
-        }
-    }
-
-    // If the request type was ANY and they all have the same QNAME, we have
-    // an answer.  But if they don't have the same QNAME, we must have an error;
-    // the only way we could get different QNAMES in an answer is if one were a
-    // CNAME - in which case there should no other record types at that QNAME.
-    if (question.getType() == RRType::ANY()) {
-        bool all_same = true;
-        for (vector<RRsetPtr>::size_type i = 1; (i < answer.size()) && all_same;
-             ++i) {
-            all_same = (answer[0]->getName() == answer[i]->getName());
-        }
-        if (all_same) {
-            return (ANSWER);
-        } else {
-            return (EXTRADATA);
-        }
-    }
-
-    // Multiple RRs in the answer, and not all the same QNAME.  This
-    // is either an answer, a CNAME (in either case, there could be multiple
-    // CNAMEs in the chain) or an error.
-    //
-    // So we need to follow the CNAME chain to resolve this.  For this to work:
-    //
-    // a) There must be one RR that matches the name, class and type of
-    //    the question, and this is a CNAME.
-    // b) The CNAME chain is followed until the end of the chain does not
-    //    exist (answer is a CNAME) or it is not of type CNAME (ANSWER).
-    //
-    // In the latter case, if there are additional RRs, it must be an error.
-
-    vector<RRsetPtr> ansrrset(answer);
-    vector<int> present(ansrrset.size(), 1);
-    return cnameChase(question.getName(), question.getType(),
-        cname_target, cname_count,
-        ansrrset, present, ansrrset.size());
-}
-
-// Search the CNAME chain.
-ResponseClassifier::Category ResponseClassifier::cnameChase(
-    const Name& qname, const RRType& qtype,
-    Name& cname_target, unsigned int& cname_count,
-    vector<RRsetPtr>& ansrrset, vector<int>& present, size_t size)
-{
-    // Search through the vector of RRset pointers until we find one with the
-    // right QNAME.
-    for (vector<RRsetPtr>::size_type i = 0; i < ansrrset.size(); ++i) {
-        if (present[i]) {
-
-            // This entry has not been logically removed, so look at it.
-            if (ansrrset[i]->getName() == qname) {
-
-                // QNAME match.  If this RRset is a CNAME, remove it from
-                // further consideration.  If nothing is left, the end of the
-                // chain is a CNAME so this is a CNAME.  Otherwise replace
-                // the name with the RDATA of the CNAME and call ourself
-                // recursively.
-                if (ansrrset[i]->getType() == RRType::CNAME()) {
-
-                    // Don't consider it in the next iteration (although we
-                    // can still access it for now).
-                    present[i] = 0;
-                    --size;
-                    if (size == 0) {
-                        RdataIteratorPtr it = ansrrset[i]->getRdataIterator();
-                        cname_target = Name(it->getCurrent().toText());
-                        return (CNAME);
-                    } else {
-                        if (ansrrset[i]->getRdataCount() != 1) {
-
-                            // Multiple RDATA for a CNAME?  This is invalid.
-
-                            return (NOTSINGLE);
-                        }
-                        RdataIteratorPtr it = ansrrset[i]->getRdataIterator();
-                        Name newname(it->getCurrent().toText());
-
-                        // Increase CNAME count, and continue
-                        return cnameChase(newname, qtype, cname_target,
-                            ++cname_count, ansrrset, present, size);
-                    }
-
-                } else {
-
-                    // We've got here because the element is not a CNAME.  If
-                    // this is the last element and the type is the one we are
-                    // after, we've found the answer, or it is an error.  If
-                    // there is more than one RRset left in the list we are
-                    // searching, we have extra data in the answer.
-                    if (ansrrset[i]->getType() == qtype) {
-                        if (size == 1) {
-                            return (ANSWERCNAME);
-                        } else {
-                            return (EXTRADATA);
-                        }
-                    }
-                    return (INVTYPE);
-                }
-            }
-        }
-    }
-
-    // We get here if we've dropped off the end of the list without finding the
-    // QNAME we are looking for.  This means that the CNAME chain has ended
-    // but there are additional RRsets in the data.
-
-    return (EXTRADATA);
-}
-
-} // namespace resolve
-} // namespace isc
diff --git a/src/lib/resolve/response_classifier.h b/src/lib/resolve/response_classifier.h
deleted file mode 100644 (file)
index ce99bf0..0000000
+++ /dev/null
@@ -1,157 +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.
-
-// $Id$
-
-#ifndef RESPONSE_CLASSIFIER_H
-#define RESPONSE_CLASSIFIER_H
-
-#include <cstddef>
-
-#include <dns/question.h>
-#include <dns/message.h>
-#include <dns/question.h>
-
-#define RESOLVER_MAX_CNAME_CHAIN    16
-
-namespace isc {
-namespace resolve {
-
-/// \brief Classify Server Response
-///
-/// This class is used in the recursive server.  It is passed an answer received
-/// from an upstream server and categorises it.
-///
-/// TODO: The code here does not take into account any EDNS0 fields.
-
-class ResponseClassifier {
-public:
-
-    /// \brief Category of Answer
-    ///
-    /// In the valid answers, not the distinction between REFERRAL and CNAME.
-    /// A REFERRAL answer means that the answer section of the message is
-    /// empty, but there is something in the authority section.  A CNAME means
-    /// that the answer section contains one or more CNAMES in a chain that
-    /// do not end with a non-CNAME RRset.
-    enum Category {
-
-        // Codes indicating that a message is valid.
-
-        ANSWER,             ///< Response contains the answer
-        ANSWERCNAME,        ///< Response was a CNAME chain ending in an answer
-        CNAME,              ///< Response was a CNAME
-        NXDOMAIN,           ///< Response was an NXDOMAIN
-        NXRRSET,            ///< Response was name exists, but type does not
-        REFERRAL,           ///< Response contains a referral
-
-        // Codes indicating that a message is invalid.  Note that the error()
-        // method relies on these appearing after the "message valid" codes.
-
-        EMPTY,              ///< No answer or authority sections
-        EXTRADATA,          ///< Answer section contains more RRsets than needed
-        INVNAMCLASS,        ///< Invalid name or class in answer
-        INVTYPE,            ///< Name/class of answer correct, type is wrong
-        MISMATQUEST,        ///< Response question section != question
-        MULTICLASS,         ///< Multiple classes in multi-RR answer
-        NOTONEQUEST,        ///< Not one question in response question section
-        NOTRESPONSE,        ///< Response has the Query/Response bit clear
-        NOTSINGLE,          ///< CNAME has multiple RDATA elements.
-        OPCODE,             ///< Opcode field does not indicate a query
-        RCODE,              ///< RCODE indicated an error
-        TRUNCATED           ///< Response was truncated
-    };
-
-    /// \brief Check Error
-    ///
-    /// An inline routine to quickly classify whether the return category is
-    /// an error or not.  This makes use of internal knowledge of the order of
-    /// codes in the Category enum.
-    ///
-    /// \param code Return category from classify()
-    ///
-    /// \return true if the category is an error, false if not.
-    static bool error(Category code) {
-        return (code > REFERRAL);
-    }
-
-    /// \brief Classify
-    ///
-    /// Classify the response in the "message" object.
-    ///
-    /// \param question Question that was sent to the server
-    /// \param message Pointer to the associated response from the server.
-    /// \param cname_target If the message contains an (unfinished) CNAME
-    /// chain, this Name will be replaced by the target of the last CNAME
-    /// in the chain
-    /// \param cname_count This unsigned int will be incremented with
-    /// the number of CNAMEs followed
-    /// \param tcignore If set, the TC bit in a response packet is
-    /// ignored.  Otherwise the error code TRUNCATED will be returned.  The
-    /// only time this is likely to be used is in development where we are not
-    /// going to fail over to TCP and will want to use what is returned, even
-    /// if some of the response was lost.
-    static Category classify(const isc::dns::Question& question,
-            const isc::dns::Message& message, 
-            isc::dns::Name& cname_target, unsigned int& cname_count,
-            bool tcignore = false);
-
-private:
-    /// \brief Follow CNAMEs
-    ///
-    /// Given a QNAME and an answer section that contains CNAMEs, assume that
-    /// they form a CNAME chain and search through them.  Possible outcomes
-    /// are:
-    ///
-    /// a) All CNAMES and they form a chain.  The result is a referral.
-    /// b) All but one are CNAMES and they form a chain.  The other is pointed
-    ///    to by the last element of the chain and is the correct QTYPE.  The
-    ///    result is an answer.
-    /// c) Having followed the CNAME chain as far as we can, there is one
-    ///    remaining RRset that is of the wrong type, or there are multiple
-    ///    RRsets remaining.  return the EXTRADATA code.
-    ///
-    /// \param qname Question name we are searching for
-    /// \param qtype Question type we are search for.  (This is assumed not
-    /// to be "ANY".)
-    /// \param ansrrset Vector of RRsetPtr pointing to the RRsets we are
-    /// considering.
-    /// \param present Array of "int" the same size of ansrrset, with each
-    /// element set to "1" to allow the corresponding element of ansrrset to
-    /// be checked, and "0" to skip it.  This might be premature optimisation,
-    /// but the algorithm would otherwise involve duplicating the RRset
-    /// vector then removing elements from random positions one by one.  As
-    /// each removal involves the destruction of an "xxxPtr" element (which
-    /// presently is implemented by boost::shared_ptr), the overhad of memory
-    /// management seemed high.  This solution imposes some additional loop
-    /// cycles, but that should be minimal compared with the overhead of the
-    /// memory management.
-    /// \param cname_target If the message contains an (unfinished) CNAME
-    /// chain, this Name will be replaced by the target of the last CNAME
-    /// in the chain
-    /// \param cname_count This unsigned int will be incremented with
-    /// the number of CNAMEs followed
-    /// \param size Number of elements to check.  See description of \c present
-    /// for details.
-    static Category cnameChase(const isc::dns::Name& qname,
-        const isc::dns::RRType& qtype,
-        isc::dns::Name& cname_target, unsigned int& cname_count,
-        std::vector<isc::dns::RRsetPtr>& ansrrset, std::vector<int>& present,
-        size_t size);
-};
-
-} // namespace resolve
-} // namespace isc
-
-#endif // RESPONSE_CLASSIFIER_H
diff --git a/src/lib/resolve/tests/.gitignore b/src/lib/resolve/tests/.gitignore
deleted file mode 100644 (file)
index d6d1ec8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/run_unittests
diff --git a/src/lib/resolve/tests/Makefile.am b/src/lib/resolve/tests/Makefile.am
deleted file mode 100644 (file)
index 84f603b..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
-AM_CPPFLAGS += $(BOOST_INCLUDES)
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
-
-if USE_STATIC_LINK
-AM_LDFLAGS = -static
-endif
-
-CLEANFILES = *.gcno *.gcda
-
-TESTS_ENVIRONMENT = \
-        $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
-
-TESTS =
-if HAVE_GTEST
-TESTS += run_unittests
-
-run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
-
-run_unittests_SOURCES  = run_unittests.cc
-run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.h
-run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
-run_unittests_SOURCES += resolve_unittest.cc
-run_unittests_SOURCES += resolver_callback_unittest.cc
-run_unittests_SOURCES += response_classifier_unittest.cc
-run_unittests_SOURCES += recursive_query_unittest.cc
-run_unittests_SOURCES += recursive_query_unittest_2.cc
-run_unittests_SOURCES += recursive_query_unittest_3.cc
-
-run_unittests_LDADD = $(GTEST_LDADD)
-run_unittests_LDADD +=  $(top_builddir)/src/lib/nsas/libb10-nsas.la
-run_unittests_LDADD +=  $(top_builddir)/src/lib/cache/libb10-cache.la
-run_unittests_LDADD +=  $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
-run_unittests_LDADD +=  $(top_builddir)/src/lib/asiodns/libb10-asiodns.la
-run_unittests_LDADD +=  $(top_builddir)/src/lib/resolve/libb10-resolve.la
-run_unittests_LDADD +=  $(top_builddir)/src/lib/dns/libb10-dns++.la
-run_unittests_LDADD +=  $(top_builddir)/src/lib/util/libb10-util.la
-run_unittests_LDADD +=  $(top_builddir)/src/lib/log/libb10-log.la
-run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
-run_unittests_LDADD +=  $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
-
-endif
-
-noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/resolve/tests/recursive_query_unittest.cc b/src/lib/resolve/tests/recursive_query_unittest.cc
deleted file mode 100644 (file)
index dddfab3..0000000
+++ /dev/null
@@ -1,1006 +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 <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#include <cstring>
-
-#include <boost/noncopyable.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/bind.hpp>
-#include <boost/scoped_ptr.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-
-#include <gtest/gtest.h>
-
-#include <exceptions/exceptions.h>
-
-#include <dns/tests/unittest_util.h>
-#include <util/unittests/wiredata.h>
-#include <dns/rcode.h>
-
-#include <util/buffer.h>
-#include <util/unittests/resolver.h>
-#include <dns/message.h>
-#include <dns/rdataclass.h>
-
-#include <nsas/nameserver_address_store.h>
-#include <cache/resolver_cache.h>
-#include <resolve/resolve.h>
-
-// IMPORTANT: We shouldn't directly use ASIO definitions in this test.
-// In particular, we must not include asio.hpp in this file.
-// The asiolink module is primarily intended to be a wrapper that hide the
-// details of the underlying implementations.  We need to test the wrapper
-// level behaviors.  In addition, some compilers reject to compile this file
-// if we include asio.hpp unless we specify a special compiler option.
-// If we need to test something at the level of underlying ASIO and need
-// their definition, that test should go to asiolink/internal/tests.
-#include <resolve/recursive_query.h>
-#include <asiodns/dns_lookup.h>
-#include <asiolink/io_socket.h>
-#include <asiolink/io_service.h>
-#include <asiolink/io_message.h>
-#include <asiolink/io_error.h>
-
-using namespace std;
-using namespace isc::asiodns;
-using namespace isc::asiolink;
-using namespace isc::dns;
-using namespace isc::util;
-using isc::UnitTestUtil;
-using isc::util::unittests::matchWireData;
-using boost::scoped_ptr;
-
-namespace isc {
-namespace asiodns {
-
-// This is defined in recursive_query.cc, but not in header (it's not public
-// function). So bring it in to be tested.
-std::string
-deepestDelegation(Name name, RRClass rrclass,
-                  isc::cache::ResolverCache& cache);
-
-}
-}
-
-namespace {
-const char* const TEST_SERVER_PORT = "53535";
-const char* const TEST_CLIENT_PORT = "53536";
-const char* const TEST_IPV6_ADDR = "::1";
-const char* const TEST_IPV4_ADDR = "127.0.0.1";
-// This data is intended to be valid as a DNS/TCP-like message: the first
-// two octets encode the length of the rest of the data.  This is crucial
-// for the tests below.
-const uint8_t test_data[] = {0, 4, 1, 2, 3, 4};
-
-// This function returns an addrinfo structure for use by tests.
-struct addrinfo*
-resolveAddress(const int protocol, const char* const addr,
-               const char* const port)
-{
-    struct addrinfo hints;
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = AF_UNSPEC; // let the address decide it.
-    hints.ai_socktype = (protocol == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
-    hints.ai_protocol = protocol;
-    hints.ai_flags = AI_NUMERICSERV;
-
-    struct addrinfo* res;
-    const int error = getaddrinfo(addr, port, &hints, &res);
-    if (error != 0) {
-        isc_throw(IOError, "getaddrinfo failed: " << gai_strerror(error));
-    }
-
-    return (res);
-}
-
-// convenience shortcut of the other version using different addresses and
-// ports depending on whether we're testing IPv4 or v6, TCP or UDP, and
-// client or server operation.
-struct addrinfo*
-resolveAddress(const int family, const int protocol, const bool client) {
-    return (resolveAddress(protocol,
-                           (family == AF_INET6) ? TEST_IPV6_ADDR :
-                           TEST_IPV4_ADDR,
-                           client ? TEST_CLIENT_PORT : TEST_SERVER_PORT));
-}
-
-// A helper holder of addrinfo so we can safely release the resource
-// either when leaving the defined scope either normally or due to exception.
-struct ScopedAddrInfo {
-    ScopedAddrInfo(struct addrinfo* res) : res_(res) {}
-    ~ScopedAddrInfo() { freeaddrinfo(res_); }
-    struct addrinfo* res_;
-};
-
-// Similar to ScopedAddrInfo but for socket FD.  It also supports the "release"
-// operation so it can release the ownership of the FD.
-// This is made non copyable to avoid making an accidental copy, which could
-// result in duplicate close.
-struct ScopedSocket : private boost::noncopyable {
-    ScopedSocket() : s_(-1) {}
-    ScopedSocket(int s) : s_(s) {}
-    ~ScopedSocket() {
-        if (s_ >= 0) {
-            close(s_);
-        }
-    }
-    void reset(int new_s) {
-        if (s_ >= 0) {
-            close(s_);
-        }
-        s_ = new_s;
-    }
-    int release() {
-        int s = s_;
-        s_ = -1;
-        return (s);
-    }
-    int s_;
-};
-
-// This fixture is a framework for various types of network operations
-// using the ASIO interfaces.  Each test case creates an IOService object,
-// opens a local "client" socket for testing, sends data via the local socket
-// to the service that would run in the IOService object.
-// A mock callback function (an ASIOCallBack object) is registered with the
-// IOService object, so the test code should be able to examine the data
-// received on the server side.  It then checks the received data matches
-// expected parameters.
-// If initialization parameters of the IOService should be modified, the test
-// case can do it using the setDNSService() method.
-// Note: the set of tests in RecursiveQueryTest use actual network services and may
-// involve undesirable side effects such as blocking.
-class RecursiveQueryTest : public ::testing::Test {
-protected:
-    RecursiveQueryTest();
-    ~RecursiveQueryTest() {
-        // It would delete itself, but after the io_service_, which could
-        // segfailt in case there were unhandled requests
-        resolver_.reset();
-        // In a similar note, we wait until the resolver has been cleaned up
-        // until deleting and active test running_query_
-        delete running_query_;
-    }
-
-    void SetUp() {
-        callback_.reset(new ASIOCallBack(this));
-    }
-
-    // Send a test UDP packet to a mock server
-    void sendUDP(const int family) {
-        ScopedAddrInfo sai(resolveAddress(family, IPPROTO_UDP, false));
-        struct addrinfo* res = sai.res_;
-
-        sock_.reset(socket(res->ai_family, res->ai_socktype,
-                           res->ai_protocol));
-        if (sock_.s_ < 0) {
-            isc_throw(IOError, "failed to open test socket");
-        }
-        const int cc = sendto(sock_.s_, test_data, sizeof(test_data), 0,
-                              res->ai_addr, res->ai_addrlen);
-        if (cc != sizeof(test_data)) {
-            isc_throw(IOError, "unexpected sendto result: " << cc);
-        }
-        io_service_.run();
-    }
-
-    // Send a test TCP packet to a mock server
-    void sendTCP(const int family) {
-        ScopedAddrInfo sai(resolveAddress(family, IPPROTO_TCP, false));
-        struct addrinfo* res = sai.res_;
-
-        sock_.reset(socket(res->ai_family, res->ai_socktype,
-                           res->ai_protocol));
-        if (sock_.s_ < 0) {
-            isc_throw(IOError, "failed to open test socket");
-        }
-        if (connect(sock_.s_, res->ai_addr, res->ai_addrlen) < 0) {
-            isc_throw(IOError, "failed to connect to the test server");
-        }
-        const int cc = send(sock_.s_, test_data, sizeof(test_data), 0);
-        if (cc != sizeof(test_data)) {
-            isc_throw(IOError, "unexpected send result: " << cc);
-        }
-        io_service_.run();
-    }
-
-    // Receive a UDP packet from a mock server; used for testing
-    // recursive lookup.  The caller must place a RecursiveQuery
-    // on the IO Service queue before running this routine.
-    void recvUDP(const int family, void* buffer, size_t& size) {
-        ScopedAddrInfo sai(resolveAddress(family, IPPROTO_UDP, true));
-        struct addrinfo* res = sai.res_;
-
-        sock_.reset(socket(res->ai_family, res->ai_socktype,
-                           res->ai_protocol));
-        if (sock_.s_ < 0) {
-            isc_throw(IOError, "failed to open test socket");
-        }
-
-        if (bind(sock_.s_, res->ai_addr, res->ai_addrlen) < 0) {
-            isc_throw(IOError, "bind failed: " << strerror(errno));
-        }
-
-        // The IO service queue should have a RecursiveQuery object scheduled
-        // to run at this point.  This call will cause it to begin an
-        // async send, then return.
-        io_service_.run_one();
-
-        // ... and this one will block until the send has completed
-        io_service_.run_one();
-
-        // Now we attempt to recv() whatever was sent.
-        // XXX: there's no guarantee the receiving socket can immediately get
-        // the packet.  Normally we can perform blocking recv to wait for it,
-        // but in theory it's even possible that the packet is lost.
-        // In order to prevent the test from hanging in such a worst case
-        // we add an ad hoc timeout.
-        const struct timeval timeo = { 10, 0 };
-        int recv_options = 0;
-        if (setsockopt(sock_.s_, SOL_SOCKET, SO_RCVTIMEO, &timeo,
-                       sizeof(timeo))) {
-            if (errno == ENOPROTOOPT) {
-                // Workaround for Solaris: it doesn't accept SO_RCVTIMEO
-                // with the error of ENOPROTOOPT.  Since this is a workaround
-                // for rare error cases anyway, we simply switch to the
-                // "don't wait" mode.  If we still find an error in recv()
-                // can happen often we'll consider a more complete solution.
-                recv_options = MSG_DONTWAIT;
-            } else {
-                isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
-            }
-        }
-        const int ret = recv(sock_.s_, buffer, size, recv_options);
-        if (ret < 0) {
-            isc_throw(IOError, "recvfrom failed: " << strerror(errno));
-        }
-
-        // Pass the message size back via the size parameter
-        size = ret;
-    }
-
-    void
-    addServer(const string& address, const char* const port, int protocol) {
-        ScopedAddrInfo sai(resolveAddress(protocol, address.c_str(), port));
-        struct addrinfo* res = sai.res_;
-        const int family = res->ai_family;
-
-        ScopedSocket sock(socket(res->ai_family, res->ai_socktype,
-                                 res->ai_protocol));
-        const int s = sock.s_;
-        if (s < 0) {
-            isc_throw(isc::Unexpected, "failed to open a test socket");
-        }
-        const int on = 1;
-        if (family == AF_INET6) {
-            if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) ==
-                -1) {
-                isc_throw(isc::Unexpected,
-                          "failed to set socket option(IPV6_V6ONLY)");
-            }
-        }
-        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
-            isc_throw(isc::Unexpected,
-                      "failed to set socket option(SO_REUSEADDR)");
-        }
-        if (bind(s, res->ai_addr, res->ai_addrlen) != 0) {
-            isc_throw(isc::Unexpected, "failed to bind a test socket");
-        }
-        if (protocol == IPPROTO_TCP) {
-            dns_service_->addServerTCPFromFD(sock.release(), family);
-        } else {
-            dns_service_->addServerUDPFromFD(sock.release(), family);
-        }
-    }
-
-    // Set up an IO Service queue using the specified address
-    void setDNSService(const string& address) {
-        setDNSService();
-        addServer(address, TEST_SERVER_PORT, IPPROTO_TCP);
-        addServer(address, TEST_SERVER_PORT, IPPROTO_UDP);
-    }
-
-    // Set up an IO Service queue using the "any" address, on IPv4 if
-    // 'use_ipv4' is true and on IPv6 if 'use_ipv6' is true.
-    void setDNSService(const bool use_ipv4, const bool use_ipv6) {
-        setDNSService();
-        if (use_ipv6) {
-            addServer("::", TEST_SERVER_PORT, IPPROTO_TCP);
-            addServer("::", TEST_SERVER_PORT, IPPROTO_UDP);
-        }
-        if (use_ipv4) {
-            addServer("0.0.0.0", TEST_SERVER_PORT, IPPROTO_TCP);
-            addServer("0.0.0.0", TEST_SERVER_PORT, IPPROTO_UDP);
-        }
-    }
-
-    // Set up empty DNS Service
-    // Set up an IO Service queue without any addresses
-    void setDNSService() {
-        dns_service_.reset(new DNSService(io_service_, callback_.get(), NULL));
-    }
-
-    // Run a simple server test, on either IPv4 or IPv6, and over either
-    // UDP or TCP.  Calls the sendUDP() or sendTCP() methods, which will
-    // start the IO Service queue.  The UDPServer or TCPServer that was
-    // created by setIOService() will receive the test packet and issue a
-    // callback, which enables us to check that the data it received
-    // matches what we sent.
-    void doTest(const int family, const int protocol) {
-        if (protocol == IPPROTO_UDP) {
-            sendUDP(family);
-        } else {
-            sendTCP(family);
-        }
-
-        // There doesn't seem to be an effective test for the validity of
-        // 'native'.
-        // One thing we are sure is it must be different from our local socket.
-        EXPECT_NE(sock_.s_, callback_native_);
-        EXPECT_EQ(protocol, callback_protocol_);
-        EXPECT_EQ(family == AF_INET6 ? TEST_IPV6_ADDR : TEST_IPV4_ADDR,
-                  callback_address_);
-
-        const uint8_t* expected_data =
-            protocol == IPPROTO_UDP ? test_data : test_data + 2;
-        const size_t expected_datasize =
-            protocol == IPPROTO_UDP ? sizeof(test_data) :
-            sizeof(test_data) - 2;
-        matchWireData(expected_data, expected_datasize,
-                      &callback_data_[0], callback_data_.size());
-    }
-
-protected:
-    // This is a nonfunctional mockup of a DNSServer object.  Its purpose
-    // is to resume after a recursive query or other asynchronous call
-    // has completed.
-    class MockServer : public DNSServer {
-    public:
-        explicit MockServer(IOService& io_service,
-                            SimpleCallback* checkin = NULL,
-                            DNSLookup* lookup = NULL,
-                            DNSAnswer* answer = NULL) :
-            io_(io_service),
-            message_(new Message(Message::PARSE)),
-            answer_message_(new Message(Message::RENDER)),
-            respbuf_(new OutputBuffer(0)),
-            checkin_(checkin), lookup_(lookup), answer_(answer)
-        {}
-
-        void operator()(asio::error_code ec = asio::error_code(),
-                        size_t length = 0)
-        {}
-
-        void resume(const bool) {
-          // should never be called in our tests
-        }
-
-        DNSServer* clone() {
-            MockServer* s = new MockServer(*this);
-            return (s);
-        }
-
-        inline void asyncLookup() {
-            if (lookup_) {
-                (*lookup_)(*io_message_, message_, answer_message_,
-                           respbuf_, this);
-            }
-        }
-
-    protected:
-        IOService& io_;
-
-    private:
-        // Currently unused; these will be used for testing
-        // asynchronous lookup calls via the asyncLookup() method
-        boost::shared_ptr<isc::asiolink::IOMessage> io_message_;
-        isc::dns::MessagePtr message_;
-        isc::dns::MessagePtr answer_message_;
-        isc::util::OutputBufferPtr respbuf_;
-
-        // Callback functions provided by the caller
-        const SimpleCallback* checkin_;
-        const DNSLookup* lookup_;
-        const DNSAnswer* answer_;
-    };
-
-    // This version of mock server just stops the io_service when it is resumed
-    class MockServerStop : public MockServer {
-        public:
-            explicit MockServerStop(IOService& io_service, bool* done) :
-                MockServer(io_service),
-                done_(done)
-            {}
-
-            void resume(const bool done) {
-                *done_ = done;
-                io_.stop();
-            }
-
-            DNSServer* clone() {
-                return (new MockServerStop(*this));
-            }
-        private:
-            bool* done_;
-    };
-
-    // This version of mock server just stops the io_service when it is resumed
-    // the second time. (Used in the clientTimeout test, where resume
-    // is called initially with the error answer, and later when the
-    // lookup times out, it is called without an answer to send back)
-    class MockServerStop2 : public MockServer {
-        public:
-            explicit MockServerStop2(IOService& io_service,
-                                     bool* done1, bool* done2) :
-                MockServer(io_service),
-                done1_(done1),
-                done2_(done2),
-                stopped_once_(false)
-            {}
-
-            void resume(const bool done) {
-                if (stopped_once_) {
-                    *done2_ = done;
-                    io_.stop();
-                } else {
-                    *done1_ = done;
-                    stopped_once_ = true;
-                }
-            }
-
-            DNSServer* clone() {
-                return (new MockServerStop2(*this));
-            }
-        private:
-            bool* done1_;
-            bool* done2_;
-            bool stopped_once_;
-    };
-
-private:
-    class ASIOCallBack : public DNSLookup {
-    public:
-        ASIOCallBack(RecursiveQueryTest* test_obj) : test_obj_(test_obj) {}
-        void operator()(const IOMessage& io_message,
-                        isc::dns::MessagePtr, isc::dns::MessagePtr,
-                        isc::util::OutputBufferPtr, DNSServer*) const {
-            test_obj_->callBack(io_message);
-        }
-    private:
-        RecursiveQueryTest* test_obj_;
-    };
-    void callBack(const IOMessage& io_message) {
-        callback_protocol_ = io_message.getSocket().getProtocol();
-        callback_native_ = io_message.getSocket().getNative();
-        callback_address_ =
-            io_message.getRemoteEndpoint().getAddress().toText();
-        callback_data_.assign(
-            static_cast<const uint8_t*>(io_message.getData()),
-            static_cast<const uint8_t*>(io_message.getData()) +
-            io_message.getDataSize());
-        io_service_.stop();
-    }
-protected:
-    IOService io_service_;
-    scoped_ptr<DNSService> dns_service_;
-    scoped_ptr<isc::nsas::NameserverAddressStore> nsas_;
-    isc::cache::ResolverCache cache_;
-    scoped_ptr<ASIOCallBack> callback_;
-    int callback_protocol_;
-    int callback_native_;
-    string callback_address_;
-    vector<uint8_t> callback_data_;
-    ScopedSocket sock_;
-    boost::shared_ptr<isc::util::unittests::TestResolver> resolver_;
-    AbstractRunningQuery* running_query_;
-};
-
-RecursiveQueryTest::RecursiveQueryTest() :
-    dns_service_(NULL), callback_(NULL), callback_protocol_(0),
-    callback_native_(-1), resolver_(new isc::util::unittests::TestResolver()),
-    running_query_(NULL)
-{
-    nsas_.reset(new isc::nsas::NameserverAddressStore(resolver_));
-}
-
-TEST_F(RecursiveQueryTest, v6UDPSend) {
-    setDNSService(true, true);
-    doTest(AF_INET6, IPPROTO_UDP);
-}
-
-TEST_F(RecursiveQueryTest, v6TCPSend) {
-    setDNSService(true, true);
-    doTest(AF_INET6, IPPROTO_TCP);
-}
-
-TEST_F(RecursiveQueryTest, v4UDPSend) {
-    setDNSService(true, true);
-    doTest(AF_INET, IPPROTO_UDP);
-}
-
-TEST_F(RecursiveQueryTest, v4TCPSend) {
-    setDNSService(true, true);
-    doTest(AF_INET, IPPROTO_TCP);
-}
-
-TEST_F(RecursiveQueryTest, v6UDPSendSpecific) {
-    // Explicitly set a specific address to be bound to the socket.
-    // The subsequent test does not directly ensures the underlying socket
-    // is bound to the expected address, but the success of the tests should
-    // reasonably suggest it works as intended.
-    // Specifying an address also implicitly means the service runs in a
-    // single address-family mode.  In tests using TCP we can confirm that
-    // by trying to make a connection and seeing a failure.  In UDP, it'd be
-    // more complicated because we need to use a connected socket and catch
-    // an error on a subsequent read operation.  We could do it, but for
-    // simplicity we only tests the easier cases for now.
-
-    setDNSService(TEST_IPV6_ADDR);
-    doTest(AF_INET6, IPPROTO_UDP);
-}
-
-TEST_F(RecursiveQueryTest, v6TCPSendSpecific) {
-    setDNSService(TEST_IPV6_ADDR);
-    doTest(AF_INET6, IPPROTO_TCP);
-
-    EXPECT_THROW(sendTCP(AF_INET), IOError);
-}
-
-TEST_F(RecursiveQueryTest, v4UDPSendSpecific) {
-    setDNSService(TEST_IPV4_ADDR);
-    doTest(AF_INET, IPPROTO_UDP);
-}
-
-TEST_F(RecursiveQueryTest, v4TCPSendSpecific) {
-    setDNSService(TEST_IPV4_ADDR);
-    doTest(AF_INET, IPPROTO_TCP);
-
-    EXPECT_THROW(sendTCP(AF_INET6), IOError);
-}
-
-TEST_F(RecursiveQueryTest, v6AddServer) {
-    setDNSService();
-    addServer(TEST_IPV6_ADDR, TEST_SERVER_PORT, IPPROTO_TCP);
-    doTest(AF_INET6, IPPROTO_TCP);
-
-    EXPECT_THROW(sendTCP(AF_INET), IOError);
-}
-
-TEST_F(RecursiveQueryTest, v4AddServer) {
-    setDNSService();
-    addServer(TEST_IPV4_ADDR, TEST_SERVER_PORT, IPPROTO_TCP);
-    doTest(AF_INET, IPPROTO_TCP);
-
-    EXPECT_THROW(sendTCP(AF_INET6), IOError);
-}
-
-TEST_F(RecursiveQueryTest, clearServers) {
-    setDNSService();
-    dns_service_->clearServers();
-
-    EXPECT_THROW(sendTCP(AF_INET), IOError);
-    EXPECT_THROW(sendTCP(AF_INET6), IOError);
-}
-
-TEST_F(RecursiveQueryTest, v6TCPOnly) {
-    // Open only IPv6 TCP socket.  A subsequent attempt of establishing an
-    // IPv4/TCP connection should fail.  See above for why we only test this
-    // for TCP.
-    setDNSService(false, true);
-    EXPECT_THROW(sendTCP(AF_INET), IOError);
-}
-
-TEST_F(RecursiveQueryTest, v4TCPOnly) {
-    setDNSService(true, false);
-    EXPECT_THROW(sendTCP(AF_INET6), IOError);
-}
-
-vector<pair<string, uint16_t> >
-singleAddress(const string &address, uint16_t port) {
-    vector<pair<string, uint16_t> > result;
-    result.push_back(pair<string, uint16_t>(address, port));
-    return (result);
-}
-
-TEST_F(RecursiveQueryTest, recursiveSetupV4) {
-    setDNSService(true, false);
-    uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    EXPECT_NO_THROW(RecursiveQuery(*dns_service_,
-                                   *nsas_, cache_,
-                                   singleAddress(TEST_IPV4_ADDR, port),
-                                   singleAddress(TEST_IPV4_ADDR, port)));
-}
-
-TEST_F(RecursiveQueryTest, recursiveSetupV6) {
-    setDNSService(false, true);
-    uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    EXPECT_NO_THROW(RecursiveQuery(*dns_service_,
-                                   *nsas_, cache_,
-                                   singleAddress(TEST_IPV6_ADDR, port),
-                                   singleAddress(TEST_IPV6_ADDR,port)));
-}
-
-// XXX:
-// This is very inadequate unit testing.  It should be generalized into
-// a routine that can do this with variable address family, address, and
-// port, and with the various callbacks defined in such a way as to ensure
-// full code coverage including error cases.
-TEST_F(RecursiveQueryTest, forwarderSend) {
-    setDNSService(true, false);
-
-    // Note: We use the test prot plus one to ensure we aren't binding
-    // to the same port as the actual server
-    uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-
-    MockServer server(io_service_);
-    RecursiveQuery rq(*dns_service_,
-                      *nsas_, cache_,
-                      singleAddress(TEST_IPV4_ADDR, port),
-                      singleAddress(TEST_IPV4_ADDR, port));
-
-    Question q(Name("example.com"), RRClass::IN(), RRType::TXT());
-    MessagePtr query_message(new Message(Message::RENDER));
-    isc::resolve::initResponseMessage(q, *query_message);
-
-    OutputBufferPtr buffer(new OutputBuffer(0));
-    MessagePtr answer(new Message(Message::RENDER));
-    running_query_ = rq.forward(query_message, answer, buffer, &server);
-
-    char data[4096];
-    size_t size = sizeof(data);
-    ASSERT_NO_THROW(recvUDP(AF_INET, data, size));
-
-    Message m(Message::PARSE);
-    InputBuffer ibuf(data, size);
-
-    // Make sure we can parse the message that was sent
-    EXPECT_NO_THROW(m.parseHeader(ibuf));
-    EXPECT_NO_THROW(m.fromWire(ibuf));
-
-    // Check that the question sent matches the one we wanted
-    QuestionPtr q2 = *m.beginQuestion();
-    EXPECT_EQ(q.getName(), q2->getName());
-    EXPECT_EQ(q.getType(), q2->getType());
-    EXPECT_EQ(q.getClass(), q2->getClass());
-}
-
-int
-createTestSocket() {
-    ScopedAddrInfo sai(resolveAddress(AF_INET, IPPROTO_UDP, true));
-    struct addrinfo* res = sai.res_;
-
-    ScopedSocket sock(socket(res->ai_family, res->ai_socktype,
-                             res->ai_protocol));
-    if (sock.s_ < 0) {
-        isc_throw(IOError, "failed to open test socket");
-    }
-    if (bind(sock.s_, res->ai_addr, res->ai_addrlen) < 0) {
-        isc_throw(IOError, "failed to bind test socket");
-    }
-    return (sock.release());
-}
-
-// Mock resolver callback for testing forward query.
-class MockResolverCallback : public isc::resolve::ResolverInterface::Callback {
-public:
-    enum ResultValue {
-        DEFAULT = 0,
-        SUCCESS = 1,
-        FAILURE = 2
-    };
-
-    MockResolverCallback(DNSServer* server):
-        result(DEFAULT),
-        server_(server->clone())
-    {}
-
-    ~MockResolverCallback() {
-        delete server_;
-    }
-
-    void success(const isc::dns::MessagePtr response) {
-        result = SUCCESS;
-        server_->resume(true);
-    }
-
-    void failure() {
-        result = FAILURE;
-        server_->resume(false);
-    }
-
-    uint32_t result;
-private:
-    DNSServer* server_;
-};
-
-// Test query timeout, set query timeout is lower than client timeout
-// and lookup timeout.
-TEST_F(RecursiveQueryTest, forwardQueryTimeout) {
-    // Prepare the service (we do not use the common setup, we do not answer
-    setDNSService();
-
-    // Prepare the socket
-    sock_.reset(createTestSocket());
-
-    // Prepare the server
-    bool done(true);
-    MockServerStop server(io_service_, &done);
-
-    // Do the answer
-    const uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    RecursiveQuery query(*dns_service_,
-                         *nsas_, cache_,
-                         singleAddress(TEST_IPV4_ADDR, port),
-                         singleAddress(TEST_IPV4_ADDR, port),
-                         10, 4000, 3000, 2);
-    Question question(Name("example.net"), RRClass::IN(), RRType::A());
-    OutputBufferPtr buffer(new OutputBuffer(0));
-    MessagePtr answer(new Message(Message::RENDER));
-    MessagePtr query_message(new Message(Message::RENDER));
-    isc::resolve::initResponseMessage(question, *query_message);
-
-    boost::shared_ptr<MockResolverCallback> callback(new MockResolverCallback(&server));
-    running_query_ = query.forward(query_message, answer, buffer, &server, callback);
-    // Run the test
-    io_service_.run();
-    EXPECT_EQ(callback->result, MockResolverCallback::FAILURE);
-}
-
-// If we set client timeout to lower than querytimeout, we should
-// get a failure answer
-// (no actual answer is given here yet. TODO the returned error message
-// should be tested)
-TEST_F(RecursiveQueryTest, forwardClientTimeout) {
-    // Prepare the service (we do not use the common setup, we do not answer
-    setDNSService();
-
-    sock_.reset(createTestSocket());
-
-    // Prepare the server
-    bool done1(true);
-    MockServerStop server(io_service_, &done1);
-
-    MessagePtr answer(new Message(Message::RENDER));
-
-    // Do the answer
-    const uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    RecursiveQuery query(*dns_service_,
-                         *nsas_, cache_,
-                         singleAddress(TEST_IPV4_ADDR, port),
-                         singleAddress(TEST_IPV4_ADDR, port),
-                         1000, 10, 4000, 4);
-    Question q(Name("example.net"), RRClass::IN(), RRType::A());
-    OutputBufferPtr buffer(new OutputBuffer(0));
-    MessagePtr query_message(new Message(Message::RENDER));
-    isc::resolve::initResponseMessage(q, *query_message);
-
-    boost::shared_ptr<MockResolverCallback> callback(new MockResolverCallback(&server));
-    running_query_ = query.forward(query_message, answer, buffer, &server, callback);
-    // Run the test
-    io_service_.run();
-    EXPECT_EQ(callback->result, MockResolverCallback::FAILURE);
-}
-
-// If we set lookup timeout to lower than querytimeout, the lookup
-// will fail.
-TEST_F(RecursiveQueryTest, forwardLookupTimeout) {
-    // Prepare the service (we do not use the common setup, we do not answer
-    setDNSService();
-
-    // Prepare the socket
-    sock_.reset(createTestSocket());
-
-    // Prepare the server
-    bool done(true);
-    MockServerStop server(io_service_, &done);
-
-    MessagePtr answer(new Message(Message::RENDER));
-
-    // Do the answer
-    const uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    RecursiveQuery query(*dns_service_,
-                         *nsas_, cache_,
-                         singleAddress(TEST_IPV4_ADDR, port),
-                         singleAddress(TEST_IPV4_ADDR, port),
-                         1000, 4000, 10, 5);
-    Question question(Name("example.net"), RRClass::IN(), RRType::A());
-    OutputBufferPtr buffer(new OutputBuffer(0));
-
-    //Message query_message(Message::RENDER);
-    MessagePtr query_message(new Message(Message::RENDER));
-    isc::resolve::initResponseMessage(question, *query_message);
-
-    boost::shared_ptr<MockResolverCallback> callback(new MockResolverCallback(&server));
-    running_query_ = query.forward(query_message, answer, buffer, &server, callback);
-    // Run the test
-    io_service_.run();
-    EXPECT_EQ(callback->result, MockResolverCallback::FAILURE);
-}
-
-// Set everything very low and see if this doesn't cause weird
-// behaviour
-TEST_F(RecursiveQueryTest, lowtimeouts) {
-    // Prepare the service (we do not use the common setup, we do not answer
-    setDNSService();
-
-    // Prepare the socket
-    sock_.reset(createTestSocket());
-
-    // Prepare the server
-    bool done(true);
-    MockServerStop server(io_service_, &done);
-
-    MessagePtr answer(new Message(Message::RENDER));
-
-    // Do the answer
-    const uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    RecursiveQuery query(*dns_service_,
-                         *nsas_, cache_,
-                         singleAddress(TEST_IPV4_ADDR, port),
-                         singleAddress(TEST_IPV4_ADDR, port),
-                         1, 1, 1, 1);
-    Question question(Name("example.net"), RRClass::IN(), RRType::A());
-    OutputBufferPtr buffer(new OutputBuffer(0));
-
-    MessagePtr query_message(new Message(Message::RENDER));
-    isc::resolve::initResponseMessage(question, *query_message);
-
-    boost::shared_ptr<MockResolverCallback> callback(new MockResolverCallback(&server));
-    running_query_ = query.forward(query_message, answer, buffer, &server, callback);
-    // Run the test
-    io_service_.run();
-    EXPECT_EQ(callback->result, MockResolverCallback::FAILURE);
-}
-
-// as mentioned above, we need a more better framework for this,
-// in addition to that, this sends out queries into the world
-// (which we should catch somehow and fake replies for)
-// for the skeleton code, it shouldn't be too much of a problem
-// Ok so even we don't all have access to the DNS world right now,
-// so disabling these tests too.
-TEST_F(RecursiveQueryTest, DISABLED_recursiveSendOk) {
-    setDNSService(true, false);
-    bool done;
-
-    MockServerStop server(io_service_, &done);
-    vector<pair<string, uint16_t> > empty_vector;
-    RecursiveQuery rq(*dns_service_, *nsas_, cache_, empty_vector,
-                      empty_vector, 10000, 0);
-
-    Question q(Name("www.isc.org"), RRClass::IN(), RRType::A());
-    OutputBufferPtr buffer(new OutputBuffer(0));
-    MessagePtr answer(new Message(Message::RENDER));
-    running_query_ = rq.resolve(q, answer, buffer, &server);
-    io_service_.run();
-
-    // Check that the answer we got matches the one we wanted
-    EXPECT_EQ(Rcode::NOERROR(), answer->getRcode());
-    ASSERT_EQ(1, answer->getRRCount(Message::SECTION_ANSWER));
-    RRsetPtr a = *answer->beginSection(Message::SECTION_ANSWER);
-    EXPECT_EQ(q.getName(), a->getName());
-    EXPECT_EQ(q.getType(), a->getType());
-    EXPECT_EQ(q.getClass(), a->getClass());
-    EXPECT_EQ(1, a->getRdataCount());
-}
-
-// see comments at previous test
-TEST_F(RecursiveQueryTest, DISABLED_recursiveSendNXDOMAIN) {
-    setDNSService(true, false);
-    bool done;
-
-    MockServerStop server(io_service_, &done);
-    vector<pair<string, uint16_t> > empty_vector;
-    RecursiveQuery rq(*dns_service_, *nsas_, cache_, empty_vector,
-                      empty_vector, 10000, 0);
-
-    Question q(Name("wwwdoesnotexist.isc.org"), RRClass::IN(), RRType::A());
-    OutputBufferPtr buffer(new OutputBuffer(0));
-    MessagePtr answer(new Message(Message::RENDER));
-    running_query_ = rq.resolve(q, answer, buffer, &server);
-    io_service_.run();
-
-    // Check that the answer we got matches the one we wanted
-    EXPECT_EQ(Rcode::NXDOMAIN(), answer->getRcode());
-    EXPECT_EQ(0, answer->getRRCount(Message::SECTION_ANSWER));
-}
-
-// Test that we don't start at root when we have a lower NS cached.
-TEST_F(RecursiveQueryTest, CachedNS) {
-    setDNSService(true, true);
-
-    // Check we have a reasonable fallback - if there's nothing of interest
-    // in the cache, start at root.
-    EXPECT_EQ(".", deepestDelegation(Name("www.somewhere.deep.example.org"),
-                                     RRClass::IN(), cache_));
-
-    // Prefill the cache. There's a zone with a NS and IP address for one
-    // of them (to see that one is enough) and another deeper one, with NS,
-    // but without IP.
-    RRsetPtr nsUpper(new RRset(Name("example.org"), RRClass::IN(),
-                               RRType::NS(), RRTTL(300)));
-    nsUpper->addRdata(rdata::generic::NS(Name("ns.example.org")));
-    nsUpper->addRdata(rdata::generic::NS(Name("ns2.example.org")));
-
-    RRsetPtr nsLower(new RRset(Name("somewhere.deep.example.org"),
-                               RRClass::IN(), RRType::NS(), RRTTL(300)));
-    nsLower->addRdata(rdata::generic::NS(Name("ns.somewhere.deep.example.org"))
-                      );
-
-    RRsetPtr nsIp(new RRset(Name("ns2.example.org"), RRClass::IN(),
-                            RRType::A(), RRTTL(300)));
-    nsIp->addRdata(rdata::in::A("192.0.2.1"));
-
-    // Make sure the test runs in the correct environment (we don't test
-    // the cache, but we need it to unswer this way for the test, so we
-    // just make sure)
-    ASSERT_TRUE(cache_.update(nsUpper));
-    ASSERT_TRUE(cache_.update(nsLower));
-    ASSERT_TRUE(cache_.update(nsIp));
-    RRsetPtr deepest(cache_.lookupDeepestNS(Name(
-        "www.somewhere.deep.example.org"), RRClass::IN()));
-    ASSERT_NE(RRsetPtr(), deepest);
-    ASSERT_EQ(nsLower->getName(), deepest->getName());
-
-    // Direct check of the function that chooses the delegation point
-    // It should not use nsLower, because we don't have IP address for
-    // that one. But it can choose nsUpper.
-    EXPECT_EQ("example.org.",
-              deepestDelegation(Name("www.somewhere.deep.example.org"),
-              RRClass::IN(), cache_));
-
-    // Now more complex and indirect test:
-    // We ask it to resolve the name for us. It will pick up a delegation
-    // point and ask NSAS for it. NSAS will in turn ask resolver for NS record
-    // of the delegation point. We then pick it up from the fake resolver
-    // and check it is the correct one. This checks the delegation point
-    // travels safely through the whole path there (it would be enough to check
-    // it up to NSAS, but replacing NSAS is more complicated, so we just
-    // include in the test as well for simplicity).
-
-    // Prepare the recursive query
-    vector<pair<string, uint16_t> > roots;
-    roots.push_back(pair<string, uint16_t>("192.0.2.2", 53));
-    vector<pair<string, uint16_t> > upstream;
-    RecursiveQuery rq(*dns_service_, *nsas_, cache_,
-                      upstream, roots);
-    // Ask a question at the bottom. It should not use the lower NS, because
-    // it would lead to a loop in NS. But it can use the nsUpper one, it has
-    // an IP address and we can avoid asking root.
-    Question q(Name("www.somewhere.deep.example.org"), RRClass::IN(),
-               RRType::A());
-    OutputBufferPtr buffer(new OutputBuffer(0));
-    MessagePtr answer(new Message(Message::RENDER));
-    // The server is here so we have something to pass there
-    MockServer server(io_service_);
-    running_query_ = rq.resolve(q, answer, buffer, &server);
-    // We don't need to run the service in this test. We are interested only
-    // in the place it starts resolving at
-
-    // Look what is asked by NSAS - it should be our delegation point.
-    EXPECT_NO_THROW(EXPECT_EQ(nsUpper->getName(),
-                              (*resolver_)[0]->getName()) <<
-                    "It starts resolving at the wrong place") <<
-        "It does not ask NSAS anything, how does it know where to send?";
-}
-
-// TODO: add tests that check whether the cache is updated on succesfull
-// responses, and not updated on failures.
-
-}
diff --git a/src/lib/resolve/tests/recursive_query_unittest_2.cc b/src/lib/resolve/tests/recursive_query_unittest_2.cc
deleted file mode 100644 (file)
index 8c2e9e3..0000000
+++ /dev/null
@@ -1,728 +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 <algorithm>
-#include <cstdlib>
-#include <iomanip>
-#include <iostream>
-#include <string>
-#include <vector>
-
-#include <gtest/gtest.h>
-#include <boost/bind.hpp>
-
-#include <asio.hpp>
-
-#include <util/buffer.h>
-#include <util/io_utilities.h>
-
-#include <dns/question.h>
-#include <dns/message.h>
-#include <dns/messagerenderer.h>
-#include <dns/opcode.h>
-#include <dns/name.h>
-#include <dns/rcode.h>
-#include <dns/rrtype.h>
-#include <dns/rrset.h>
-#include <dns/rrttl.h>
-#include <dns/rdata.h>
-
-#include <util/io_utilities.h>
-#include <asiodns/dns_service.h>
-#include <asiodns/io_fetch.h>
-#include <asiolink/io_address.h>
-#include <asiolink/io_endpoint.h>
-#include <asiolink/io_service.h>
-#include <resolve/recursive_query.h>
-#include <resolve/resolver_interface.h>
-
-using namespace asio;
-using namespace asio::ip;
-using namespace isc::asiolink;
-using namespace isc::dns;
-using namespace isc::dns::rdata;
-using namespace isc::util;
-using namespace isc::resolve;
-using namespace std;
-
-/// RecursiveQuery Test - 2
-///
-/// The second part of the RecursiveQuery unit tests, this attempts to get the
-/// RecursiveQuery object to follow a set of referrals for "www.example.org" to
-/// and to invoke TCP fallback on one of the queries.  In particular, we expect
-/// that the test will do the following in an attempt to resolve
-/// www.example.org:
-///
-/// - Send question over UDP to "root" - get referral to "org".
-/// - Send question over UDP to "org" - get referral to "example.org" with TC bit set.
-/// - Send question over TCP to "org" - get referral to "example.org".
-/// - Send question over UDP to "example.org" - get response for www.example.org.
-///
-/// (The order of queries is set in this way in order to also test that after a
-/// failover to TCP, queries revert to UDP).
-///
-/// By using the "test_server_" element of RecursiveQuery, all queries are
-/// directed to one or other of the "servers" in the RecursiveQueryTest2 class,
-/// regardless of the glue returned in referrals.
-
-namespace {
-const char* const TEST_ADDRESS = "127.0.0.1"; ///< Servers are on this address
-const uint16_t TEST_PORT = 5301;              ///< ... and this port
-const size_t BUFFER_SIZE = 1024;              ///< For all buffers
-const char* const WWW_EXAMPLE_ORG = "192.0.2.254";
-                                              ///< Address of www.example.org
-} //end anonymous namespace
-
-namespace isc {
-namespace asiodns {
-
-// As the test is fairly long and complex, debugging "print" statements have
-// been left in although they are disabled.  Set the following to "true" to
-// enable them.
-const bool DEBUG_PRINT = false;
-
-class MockResolver : public isc::resolve::ResolverInterface {
-public:
-    virtual void resolve(const QuestionPtr& question,
-                 const ResolverInterface::CallbackPtr& callback) {
-    }
-
-    virtual ~MockResolver() {}
-};
-
-
-
-/// \brief Test fixture for the RecursiveQuery Test
-class RecursiveQueryTest2 : public virtual ::testing::Test
-{
-public:
-
-    /// \brief Status of query
-    ///
-    /// Set before the query and then by each "server" when responding.
-    enum QueryStatus {
-        NONE = 0,                   ///< Default
-        UDP_ROOT = 1,               ///< Query root server over UDP
-        UDP_ORG = 2,                ///< Query ORG server over UDP
-        TCP_ORG = 3,                ///< Query ORG server over TCP
-        UDP_EXAMPLE_ORG_BAD = 4,    ///< Query EXAMPLE.ORG server over UDP
-                                    ///< (return malformed packet)
-        UDP_EXAMPLE_ORG = 5,        ///< Query EXAMPLE.ORG server over UDP
-        COMPLETE = 6                ///< Query is complete
-    };
-
-    // Common stuff
-    bool            debug_;                     ///< Set true for debug print
-    IOService       service_;                   ///< Service to run everything
-    DNSService      dns_service_;               ///< Resolver is part of "server"
-    QuestionPtr     question_;                  ///< What to ask
-    QueryStatus     last_;                      ///< What was the last state
-    QueryStatus     expected_;                  ///< Expected next state
-    OutputBufferPtr question_buffer_;           ///< Question we expect to receive
-    boost::shared_ptr<MockResolver> resolver_;  ///< Mock resolver
-    isc::nsas::NameserverAddressStore* nsas_;   ///< Nameserver address store
-    isc::cache::ResolverCache cache_;           ///< Resolver cache
-
-    // Data for TCP Server
-    size_t          tcp_cumulative_;            ///< Cumulative TCP data received
-    tcp::endpoint   tcp_endpoint_;              ///< Endpoint for TCP receives
-    size_t          tcp_length_;                ///< Expected length value
-    uint8_t         tcp_receive_buffer_[BUFFER_SIZE];   ///< Receive buffer for TCP I/O
-    OutputBufferPtr tcp_send_buffer_;           ///< Send buffer for TCP I/O
-    tcp::socket     tcp_socket_;                ///< Socket used by TCP server
-
-    /// Data for UDP
-    udp::endpoint   udp_remote_;                ///< Endpoint for UDP receives
-    size_t          udp_length_;                ///< Expected length value
-    uint8_t         udp_receive_buffer_[BUFFER_SIZE];   ///< Receive buffer for UDP I/O
-    OutputBufferPtr udp_send_buffer_;           ///< Send buffer for UDP I/O
-    udp::socket     udp_socket_;                ///< Socket used by UDP server
-
-    /// Some of the tests cause an 'active' running query to be created, but
-    /// don't complete the framework that makes that query delete itself.
-    /// This member can be used to store it so that it is deleted automatically
-    /// when the test is finished.
-    AbstractRunningQuery* running_query_;
-
-    /// \brief Constructor
-    RecursiveQueryTest2() :
-        debug_(DEBUG_PRINT),
-        service_(),
-        dns_service_(service_, NULL, NULL),
-        question_(new Question(Name("www.example.org"), RRClass::IN(), RRType::A())),
-        last_(NONE),
-        expected_(NONE),
-        question_buffer_(new OutputBuffer(BUFFER_SIZE)),
-        resolver_(new MockResolver()),
-        nsas_(new isc::nsas::NameserverAddressStore(resolver_)),
-        tcp_cumulative_(0),
-        tcp_endpoint_(asio::ip::address::from_string(TEST_ADDRESS), TEST_PORT),
-        tcp_length_(0),
-        tcp_receive_buffer_(),
-        tcp_send_buffer_(new OutputBuffer(BUFFER_SIZE)),
-        tcp_socket_(service_.get_io_service()),
-        udp_remote_(),
-        udp_length_(0),
-        udp_receive_buffer_(),
-        udp_send_buffer_(new OutputBuffer(BUFFER_SIZE)),
-        udp_socket_(service_.get_io_service(), udp::v4()),
-        running_query_(NULL)
-    {}
-
-    ~RecursiveQueryTest2() {
-        // It would delete itself, but after the io_service_, which could
-        // segfailt in case there were unhandled requests
-        resolver_.reset();
-        // In a similar note, we wait until the resolver has been cleaned up
-        // until deleting and active test running_query_
-        delete running_query_;
-        delete nsas_;
-    }
-
-    /// \brief Set Common Message Bits
-    ///
-    /// Sets up the common bits of a response message returned by the handlers.
-    ///
-    /// \param msg Message buffer in RENDER mode.
-    /// \param qid QID to set the message to
-    void setCommonMessage(isc::dns::Message& msg, uint16_t qid = 0) {
-        msg.setQid(qid);
-        msg.setHeaderFlag(Message::HEADERFLAG_QR);
-        msg.setOpcode(Opcode::QUERY());
-        msg.setHeaderFlag(Message::HEADERFLAG_AA);
-        msg.setRcode(Rcode::NOERROR());
-        msg.addQuestion(*question_);
-    }
-
-    /// \brief Set Referral to "org"
-    ///
-    /// Sets up the passed-in message (expected to be in "RENDER" mode to
-    /// indicate a referral to fictitious .org nameservers.
-    ///
-    /// \param msg Message to update with referral information.
-    void setReferralOrg(isc::dns::Message& msg) {
-        if (debug_) {
-            cout << "setReferralOrg(): creating referral to .org nameservers" << endl;
-        }
-
-        // Do a referral to org.  We'll define all NS records as "in-zone"
-        // nameservers (and supply glue) to avoid the possibility of the
-        // resolver starting another recursive query to resolve the address of
-        // a nameserver.
-        RRsetPtr org_ns(new RRset(Name("org."), RRClass::IN(), RRType::NS(), RRTTL(300)));
-        org_ns->addRdata(createRdata(RRType::NS(), RRClass::IN(), "ns1.org."));
-        org_ns->addRdata(createRdata(RRType::NS(), RRClass::IN(), "ns2.org."));
-        msg.addRRset(Message::SECTION_AUTHORITY, org_ns);
-
-        RRsetPtr org_ns1(new RRset(Name("ns1.org."), RRClass::IN(), RRType::A(), RRTTL(300)));
-        org_ns1->addRdata(createRdata(RRType::A(), RRClass::IN(), "192.0.2.1"));
-        msg.addRRset(Message::SECTION_ADDITIONAL, org_ns1);
-
-        RRsetPtr org_ns2(new RRset(Name("ns2.org."), RRClass::IN(), RRType::A(), RRTTL(300)));
-        org_ns2->addRdata(createRdata(RRType::A(), RRClass::IN(), "192.0.2.2"));
-        msg.addRRset(Message::SECTION_ADDITIONAL, org_ns2);
-    }
-
-    /// \brief Set Referral to "example.org"
-    ///
-    /// Sets up the passed-in message (expected to be in "RENDER" mode to
-    /// indicate a referral to fictitious example.org nameservers.
-    ///
-    /// \param msg Message to update with referral information.
-    void setReferralExampleOrg(isc::dns::Message& msg) {
-        if (debug_) {
-            cout << "setReferralExampleOrg(): creating referral to example.org nameservers" << endl;
-        }
-
-        // Do a referral to example.org.  As before, we'll define all NS
-        // records as "in-zone" nameservers (and supply glue) to avoid the
-        // possibility of the resolver starting another recursive query to look
-        // up the address of the nameserver.
-        RRsetPtr example_org_ns(new RRset(Name("example.org."), RRClass::IN(), RRType::NS(), RRTTL(300)));
-        example_org_ns->addRdata(createRdata(RRType::NS(), RRClass::IN(), "ns1.example.org."));
-        example_org_ns->addRdata(createRdata(RRType::NS(), RRClass::IN(), "ns2.example.org."));
-        msg.addRRset(Message::SECTION_AUTHORITY, example_org_ns);
-
-        RRsetPtr example_org_ns1(new RRset(Name("ns1.example.org."), RRClass::IN(), RRType::A(), RRTTL(300)));
-        example_org_ns1->addRdata(createRdata(RRType::A(), RRClass::IN(), "192.0.2.11"));
-        msg.addRRset(Message::SECTION_ADDITIONAL, example_org_ns1);
-
-        RRsetPtr example_org_ns2(new RRset(Name("ns2.example.org."), RRClass::IN(), RRType::A(), RRTTL(300)));
-        example_org_ns2->addRdata(createRdata(RRType::A(), RRClass::IN(), "192.0.2.21"));
-        msg.addRRset(Message::SECTION_ADDITIONAL, example_org_ns2);
-    }
-
-    /// \brief Set Answer to "www.example.org"
-    ///
-    /// Sets up the passed-in message (expected to be in "RENDER" mode) to
-    /// indicate an authoritative answer to www.example.org.
-    ///
-    /// \param msg Message to update with referral information.
-    void setAnswerWwwExampleOrg(isc::dns::Message& msg) {
-        if (debug_) {
-            cout << "setAnswerWwwExampleOrg(): creating answer for www.example.org" << endl;
-        }
-
-        // Give a response for www.example.org.
-        RRsetPtr www_example_org_a(new RRset(Name("www.example.org."), RRClass::IN(), RRType::A(), RRTTL(300)));
-        www_example_org_a->addRdata(createRdata(RRType::A(), RRClass::IN(), WWW_EXAMPLE_ORG));
-        msg.addRRset(Message::SECTION_ANSWER, www_example_org_a);
-
-        // ... and add the Authority and Additional sections. (These are the
-        // same as in the referral to example.org from the .org nameserver.)
-        setReferralExampleOrg(msg);
-    }
-
-    /// \brief UDP Receive Handler
-    ///
-    /// This is invoked when a message is received over UDP from the
-    /// RecursiveQuery object under test.  It formats an answer and sends it
-    /// asynchronously, with the UdpSendHandler method being specified as the
-    /// completion handler.
-    ///
-    /// \param ec ASIO error code, completion code of asynchronous I/O issued
-    ///        by the "server" to receive data.
-    /// \param length Amount of data received.
-    void udpReceiveHandler(asio::error_code ec = asio::error_code(),
-                           size_t length = 0)
-    {
-        if (debug_) {
-            cout << "udpReceiveHandler(): error = " << ec.value() <<
-                    ", length = " << length << ", last state = " << last_ <<
-                    ", expected state = " << expected_ << endl;
-        }
-
-        // Expected state should be one greater than the last state.
-        EXPECT_EQ(static_cast<int>(expected_), static_cast<int>(last_) + 1);
-        last_ = expected_;
-
-        // The QID in the incoming data is random so set it to 0 for the
-        // data comparison check. (It is set to 0 in the buffer containing
-        // the expected data.)
-        // And check that question we received is what was expected.
-        uint16_t qid = checkReceivedPacket(udp_receive_buffer_, length);
-
-        // The message returned depends on what state we are in.  Set up
-        // common stuff first: bits not mentioned are set to 0.
-        Message msg(Message::RENDER);
-        setCommonMessage(msg, qid);
-
-        // In the case of UDP_EXAMPLE_ORG_BAD, we shall mangle the
-        // response
-        bool mangle_response = false;
-
-        // Set up state-dependent bits:
-        switch (expected_) {
-        case UDP_ROOT:
-            // Return a referral to org.  We then expect to query the "org"
-            // nameservers over UDP next.
-            setReferralOrg(msg);
-            expected_ = UDP_ORG;
-            break;
-
-         case UDP_ORG:
-            // Return a referral to example.org.  We explicitly set the TC bit to
-            // force a repeat query to the .org nameservers over TCP.
-            setReferralExampleOrg(msg);
-            if (debug_) {
-                cout << "udpReceiveHandler(): setting TC bit" << endl;
-            }
-            msg.setHeaderFlag(Message::HEADERFLAG_TC);
-            expected_ = TCP_ORG;
-            break;
-
-         case UDP_EXAMPLE_ORG_BAD:
-            // Return the answer to the question.
-            setAnswerWwwExampleOrg(msg);
-            // Mangle the response to enfore another query
-            mangle_response = true;
-            expected_ = UDP_EXAMPLE_ORG;
-            break;
-
-         case UDP_EXAMPLE_ORG:
-            // Return the answer to the question.
-            setAnswerWwwExampleOrg(msg);
-            expected_ = COMPLETE;
-            break;
-
-         default:
-            FAIL() << "UdpReceiveHandler called with unknown state";
-        }
-
-        // Convert to wire format
-        udp_send_buffer_->clear();
-        MessageRenderer renderer;
-        renderer.setBuffer(udp_send_buffer_.get());
-        msg.toWire(renderer);
-
-        if (mangle_response) {
-            // mangle the packet a bit
-            // set additional to one more
-            udp_send_buffer_->writeUint8At(3, 11);
-        }
-
-        // Return a message back to the IOFetch object (after setting the
-        // expected length of data for the check in the send handler).
-        udp_length_ = udp_send_buffer_->getLength();
-        udp_socket_.async_send_to(asio::buffer(udp_send_buffer_->getData(),
-                                               udp_send_buffer_->getLength()),
-                                  udp_remote_,
-                                  boost::bind(&RecursiveQueryTest2::udpSendHandler,
-                                              this, _1, _2));
-    }
-
-    /// \brief UDP Send Handler
-    ///
-    /// Called when a send operation of the UDP server (i.e. a response
-    /// being sent to the RecursiveQuery) has completed, this re-issues
-    /// a read call.
-    ///
-    /// \param ec Completion error code of the send.
-    /// \param length Actual number of bytes sent.
-    void udpSendHandler(asio::error_code ec = asio::error_code(),
-                        size_t length = 0)
-    {
-        if (debug_) {
-            cout << "udpSendHandler(): error = " << ec.value() <<
-                    ", length = " << length << endl;
-        }
-
-        // Check send was OK
-        EXPECT_EQ(0, ec.value());
-        EXPECT_EQ(udp_length_, length);
-
-        // Reissue the receive call to await the next message.
-        udp_socket_.async_receive_from(
-            asio::buffer(udp_receive_buffer_, sizeof(udp_receive_buffer_)),
-            udp_remote_,
-            boost::bind(&RecursiveQueryTest2::udpReceiveHandler, this, _1, _2));
-    }
-
-    /// \brief Completion Handler for Accepting TCP Data
-    ///
-    /// Called when the remote system connects to the "TCP server".  It issues
-    /// an asynchronous read on the socket to read data.
-    ///
-    /// \param socket Socket on which data will be received
-    /// \param ec Boost error code, value should be zero.
-    void tcpAcceptHandler(asio::error_code ec = asio::error_code(),
-                          size_t length = 0)
-    {
-        if (debug_) {
-            cout << "tcpAcceptHandler(): error = " << ec.value() <<
-                    ", length = " << length << endl;
-        }
-
-        // Expect that the accept completed without a problem.
-        EXPECT_EQ(0, ec.value());
-
-        // Initiate a read on the socket, indicating that nothing has yet been
-        // received.
-        tcp_cumulative_ = 0;
-        tcp_socket_.async_receive(
-            asio::buffer(tcp_receive_buffer_, sizeof(tcp_receive_buffer_)),
-            boost::bind(&RecursiveQueryTest2::tcpReceiveHandler, this, _1, _2));
-    }
-
-    /// \brief Completion Handler for Receiving TCP Data
-    ///
-    /// Reads data from the RecursiveQuery object and loops, reissuing reads,
-    /// until all the message has been read.  It then returns an appropriate
-    /// response.
-    ///
-    /// \param socket Socket to use to send the answer
-    /// \param ec ASIO error code, completion code of asynchronous I/O issued
-    ///        by the "server" to receive data.
-    /// \param length Amount of data received.
-    void tcpReceiveHandler(asio::error_code ec = asio::error_code(),
-                           size_t length = 0)
-    {
-        if (debug_) {
-            cout << "tcpReceiveHandler(): error = " << ec.value() <<
-                    ", length = " << length <<
-                    ", cumulative = " << tcp_cumulative_ << endl;
-        }
-
-        // Expect that the receive completed without a problem.
-        EXPECT_EQ(0, ec.value());
-
-        // Have we received all the data?  We know this by checking if the two-
-        // byte length count in the message is equal to the data received.
-        tcp_cumulative_ += length;
-        bool complete = false;
-        if (tcp_cumulative_ > 2) {
-            uint16_t dns_length = readUint16(tcp_receive_buffer_,
-                                             sizeof(tcp_receive_buffer_));
-            complete = ((dns_length + 2) == tcp_cumulative_);
-        }
-
-        if (!complete) {
-            if (debug_) {
-                cout << "tcpReceiveHandler(): read not complete, " <<
-                        "issuing another read" << endl;
-            }
-
-            // Not complete yet, issue another read.
-            tcp_socket_.async_receive(
-                asio::buffer(tcp_receive_buffer_ + tcp_cumulative_,
-                             sizeof(tcp_receive_buffer_) - tcp_cumulative_),
-                boost::bind(&RecursiveQueryTest2::tcpReceiveHandler, this, _1, _2));
-            return;
-        }
-
-        // Have received a TCP message.  Expected state should be one greater
-        // than the last state.
-        EXPECT_EQ(static_cast<int>(expected_), static_cast<int>(last_) + 1);
-        last_ = expected_;
-
-        // Check that question we received is what was expected.  Note that we
-        // have to ignore the two-byte header in order to parse the message.
-        qid_t qid = checkReceivedPacket(tcp_receive_buffer_ + 2, length - 2);
-
-        // Return a message back.  This is a referral to example.org, which
-        // should result in another query over UDP.  Note the setting of the
-        // QID in the returned message with what was in the received message.
-        Message msg(Message::RENDER);
-        setCommonMessage(msg, qid);
-        setReferralExampleOrg(msg);
-
-        // Convert to wire format
-        // Use a temporary renderer for the dns wire data (we copy it
-        // to the 'real' buffer below)
-        MessageRenderer renderer;
-        msg.toWire(renderer);
-
-        // Expected next state (when checked) is the UDP query to example.org.
-        // Also, take this opportunity to clear the accumulated read count in
-        // readiness for the next read. (If any - at present, there is only
-        // one read in the test, although extensions to this test suite could
-        // change that.)
-        expected_ = UDP_EXAMPLE_ORG_BAD;
-        tcp_cumulative_ = 0;
-
-        // Unless we go through a callback loop we cannot simply use
-        // async_send() multiple times, so we cannot send the size first
-        // followed by the actual data. We copy them to a new buffer
-        // first
-        tcp_send_buffer_->clear();
-        tcp_send_buffer_->writeUint16(renderer.getLength());
-        tcp_send_buffer_->writeData(renderer.getData(), renderer.getLength());
-        tcp_socket_.async_send(asio::buffer(tcp_send_buffer_->getData(),
-                                            tcp_send_buffer_->getLength()),
-                               boost::bind(
-                                   &RecursiveQueryTest2::tcpSendHandler, this,
-                                   tcp_send_buffer_->getLength(), _1, _2));
-    }
-
-    /// \brief Completion Handler for Sending TCP data
-    ///
-    /// Called when the asynchronous send of data back to the RecursiveQuery
-    /// by the TCP "server" in this class has completed.  (This send has to
-    /// be asynchronous because control needs to return to the caller in order
-    /// for the IOService "run()" method to be called to run the handlers.)
-    ///
-    /// \param expected_length Number of bytes that were expected to have been sent.
-    /// \param ec Boost error code, value should be zero.
-    /// \param length Number of bytes sent.
-    void tcpSendHandler(size_t expected_length = 0,
-                        asio::error_code ec = asio::error_code(),
-                        size_t length = 0)
-    {
-        if (debug_) {
-            cout << "tcpSendHandler(): error = " << ec.value() <<
-                    ", length = " << length <<
-                    ", (expected length = " << expected_length << ")" << endl;
-        }
-        EXPECT_EQ(0, ec.value());       // Expect no error
-        EXPECT_EQ(expected_length, length);    // And that amount sent is as expected
-    }
-
-    /// \brief Check Received Packet
-    ///
-    /// Checks the packet received from the RecursiveQuery object to ensure
-    /// that the question is what is expected.
-    ///
-    /// \param data Start of data.  This is the start of the received buffer in
-    ///        the case of UDP data, and an offset into the buffer past the
-    ///        count field for TCP data.
-    /// \param length Length of data.
-    /// \return The QID of the message
-    qid_t checkReceivedPacket(uint8_t* data, size_t length) {
-
-        // Decode the received buffer.
-        InputBuffer buffer(data, length);
-        Message message(Message::PARSE);
-        message.fromWire(buffer);
-
-        // Check the packet.
-        EXPECT_FALSE(message.getHeaderFlag(Message::HEADERFLAG_QR));
-
-        Question question = **(message.beginQuestion());
-        EXPECT_TRUE(question == *question_);
-
-        return message.getQid();
-    }
-};
-
-/// \brief Resolver Callback Object
-///
-/// Holds the success and failure callback methods for the resolver
-class ResolverCallback : public isc::resolve::ResolverInterface::Callback {
-public:
-    /// \brief Constructor
-    ResolverCallback(IOService& service) :
-        service_(service), run_(false), status_(false), debug_(DEBUG_PRINT)
-    {}
-
-    /// \brief Destructor
-    virtual ~ResolverCallback()
-    {}
-
-    /// \brief Resolver Callback Success
-    ///
-    /// Called if the resolver detects that the call has succeeded.
-    ///
-    /// \param response Answer to the question.
-    virtual void success(const isc::dns::MessagePtr response) {
-        if (debug_) {
-            cout << "ResolverCallback::success(): answer received" << endl;
-            cout << response->toText() << endl;
-        }
-
-        // There should be one RR each  in the question and answer sections, and
-        // two RRs in each of the the authority and additional sections.
-        EXPECT_EQ(1, response->getRRCount(Message::SECTION_QUESTION));
-        EXPECT_EQ(1, response->getRRCount(Message::SECTION_ANSWER));
-        EXPECT_EQ(2, response->getRRCount(Message::SECTION_AUTHORITY));
-        EXPECT_EQ(2, response->getRRCount(Message::SECTION_ADDITIONAL));
-
-        // Check the answer - that the RRset is there...
-        EXPECT_TRUE(response->hasRRset(Message::SECTION_ANSWER,
-                                       RRsetPtr(new RRset(Name("www.example.org."),
-                                                RRClass::IN(),
-                                                RRType::A(),
-                                                RRTTL(300)))));
-        const RRsetIterator rrset_i = response->beginSection(Message::SECTION_ANSWER);
-
-        // ... get iterator into the Rdata of this RRset and point to first
-        // element...
-        const RdataIteratorPtr rdata_i = (*rrset_i)->getRdataIterator();
-        rdata_i->first();
-
-        // ... and check it is what we expect.
-        EXPECT_EQ(string(WWW_EXAMPLE_ORG), rdata_i->getCurrent().toText());
-
-        // Flag completion
-        run_ = true;
-        status_ = true;
-
-        service_.stop();    // Cause run() to exit.
-    }
-
-    /// \brief Resolver Failure Completion
-    ///
-    /// Called if the resolver detects that the resolution has failed.
-    virtual void failure() {
-        if (debug_) {
-            cout << "ResolverCallback::success(): resolution failure" << endl;
-        }
-        FAIL() << "Resolver reported completion failure";
-
-        // Flag completion
-        run_ = true;
-        status_ = false;
-
-        service_.stop();    // Cause run() to exit.
-    }
-
-    /// \brief Return status of "run" flag
-    bool getRun() const {
-        return (run_);
-    }
-
-    /// \brief Return "status" flag
-    bool getStatus() const {
-        return (status_);
-    }
-
-private:
-    IOService&      service_;       ///< Service handling the run queue
-    bool            run_;           ///< Set true when completion handler run
-    bool            status_;        ///< Set true for success, false on error
-    bool            debug_;         ///< Debug flag
-};
-
-// Sets up the UDP and TCP "servers", then tries a resolution.
-
-TEST_F(RecursiveQueryTest2, Resolve) {
-    // Set up the UDP server and issue the first read.  The endpoint from which
-    // the query is sent is put in udp_endpoint_ when the read completes, which
-    // is referenced in the callback as the place to which the response is sent.
-    udp_socket_.set_option(socket_base::reuse_address(true));
-    udp_socket_.bind(udp::endpoint(address::from_string(TEST_ADDRESS), TEST_PORT));
-    udp_socket_.async_receive_from(asio::buffer(udp_receive_buffer_,
-                                                sizeof(udp_receive_buffer_)),
-                                   udp_remote_,
-                                   boost::bind(&RecursiveQueryTest2::udpReceiveHandler,
-                                               this, _1, _2));
-
-    // Set up the TCP server and issue the accept.  Acceptance will cause the
-    // read to be issued.
-    tcp::acceptor acceptor(service_.get_io_service(),
-                           tcp::endpoint(tcp::v4(), TEST_PORT));
-    acceptor.async_accept(tcp_socket_,
-                          boost::bind(&RecursiveQueryTest2::tcpAcceptHandler,
-                                      this, _1, 0));
-
-    // Set up the RecursiveQuery object. We will also test that it correctly records
-    // RTT times by setting up a RTT recorder object as well.
-    std::vector<std::pair<std::string, uint16_t> > upstream;         // Empty
-    std::vector<std::pair<std::string, uint16_t> > upstream_root;    // Empty
-    RecursiveQuery query(dns_service_, *nsas_, cache_,
-                         upstream, upstream_root);
-    query.setTestServer(TEST_ADDRESS, TEST_PORT);
-
-    boost::shared_ptr<RttRecorder> recorder(new RttRecorder());
-    query.setRttRecorder(recorder);
-
-    // Set up callback to receive notification that the query has completed.
-    isc::resolve::ResolverInterface::CallbackPtr
-        resolver_callback(new ResolverCallback(service_));
-
-    // Kick off the resolution process.  We expect the first question to go to
-    // "root".
-    expected_ = UDP_ROOT;
-    running_query_ = query.resolve(question_, resolver_callback);
-    service_.run();
-
-    // Check what ran. (We have to cast the callback to ResolverCallback as we
-    // lost the information on the derived class when we used a
-    // ResolverInterface::CallbackPtr to store a pointer to it.)
-    ResolverCallback* rc = static_cast<ResolverCallback*>(resolver_callback.get());
-    EXPECT_TRUE(rc->getRun());
-    EXPECT_TRUE(rc->getStatus());
-
-    // Finally, check that all the RTTs were "reasonable" (defined here as
-    // being below 2 seconds).  This is an explicit check to test that the
-    // variables in the RTT calculation are at least being initialized; if they
-    // weren't, we would expect some absurdly high answers.
-    vector<uint32_t> rtt = recorder->getRtt();
-    EXPECT_GT(rtt.size(), 0);
-    for (vector<uint32_t>::size_type i = 0; i < rtt.size(); ++i) {
-        EXPECT_LT(rtt[i], 2000);
-    }
-}
-
-} // namespace asiodns
-} // namespace isc
diff --git a/src/lib/resolve/tests/recursive_query_unittest_3.cc b/src/lib/resolve/tests/recursive_query_unittest_3.cc
deleted file mode 100644 (file)
index acf60d6..0000000
+++ /dev/null
@@ -1,590 +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 <algorithm>
-#include <cstdlib>
-#include <iomanip>
-#include <iostream>
-#include <string>
-#include <vector>
-
-#include <gtest/gtest.h>
-#include <boost/bind.hpp>
-
-#include <asio.hpp>
-
-#include <util/buffer.h>
-#include <util/io_utilities.h>
-
-#include <dns/question.h>
-#include <dns/message.h>
-#include <dns/messagerenderer.h>
-#include <dns/opcode.h>
-#include <dns/name.h>
-#include <dns/rcode.h>
-#include <dns/rrtype.h>
-#include <dns/rrset.h>
-#include <dns/rrttl.h>
-#include <dns/rdata.h>
-
-#include <util/io_utilities.h>
-#include <asiodns/dns_service.h>
-#include <asiodns/io_fetch.h>
-#include <asiolink/io_address.h>
-#include <asiolink/io_endpoint.h>
-#include <asiolink/io_service.h>
-#include <resolve/recursive_query.h>
-#include <resolve/resolver_interface.h>
-
-using namespace asio;
-using namespace asio::ip;
-using namespace isc::asiolink;
-using namespace isc::dns;
-using namespace isc::dns::rdata;
-using namespace isc::util;
-using namespace isc::resolve;
-using namespace std;
-
-/// RecursiveQuery Test - 3
-///
-/// The second part of the RecursiveQuery unit tests, this attempts to get the
-/// RecursiveQuery object to follow a set of EDNS-induced errors, causing the
-/// resolver to follow the fallback logic.
-///
-/// - Send EDNS question over UDP - get FORMERR
-/// - Send EDNS question over TCP - get FORMERR
-/// - Send non-EDNS question over UDP - get RESPONSE
-///
-/// By using the "test_server_" element of RecursiveQuery, all queries are
-/// directed to one or other of the "servers" in the RecursiveQueryTest3 class.
-
-namespace {
-const char* const TEST_ADDRESS3 = "127.0.0.1"; ///< Servers are on this address
-const uint16_t TEST_PORT3 = 5303;              ///< ... and this port
-const size_t BUFFER_SIZE = 1024;               ///< For all buffers
-
-const char* const DUMMY_ADDR3 = "1.2.3.4";     ///< address to return as A
-} // end anonymous namespace
-
-namespace isc {
-namespace asiodns {
-
-class MockResolver3 : public isc::resolve::ResolverInterface {
-public:
-    virtual void resolve(const QuestionPtr& question,
-                 const ResolverInterface::CallbackPtr& callback) {
-    }
-
-    virtual ~MockResolver3() {}
-};
-
-
-
-/// \brief Test fixture for the RecursiveQuery Test
-class RecursiveQueryTest3 : public virtual ::testing::Test
-{
-public:
-
-    /// \brief Status of query
-    ///
-    /// Set before the query and then by each "server" when responding.
-    enum QueryStatus {
-        NONE = 0,                   ///< Default
-        EDNS_UDP = 1,               ///< EDNS query over UDP
-        NON_EDNS_UDP = 2,           ///< Non-EDNS query over UDP
-        COMPLETE = 6                ///< Query is complete
-    };
-
-    // Common stuff
-    IOService       service_;                   ///< Service to run everything
-    DNSService      dns_service_;               ///< Resolver is part of "server"
-    QuestionPtr     question_;                  ///< What to ask
-    QueryStatus     last_;                      ///< What was the last state
-    QueryStatus     expected_;                  ///< Expected next state
-    OutputBufferPtr question_buffer_;           ///< Question we expect to receive
-    boost::shared_ptr<MockResolver3> resolver_;  ///< Mock resolver
-    isc::nsas::NameserverAddressStore* nsas_;   ///< Nameserver address store
-    isc::cache::ResolverCache cache_;           ///< Resolver cache
-
-    // Data for TCP Server
-    size_t          tcp_cumulative_;            ///< Cumulative TCP data received
-    tcp::endpoint   tcp_endpoint_;              ///< Endpoint for TCP receives
-    size_t          tcp_length_;                ///< Expected length value
-    uint8_t         tcp_receive_buffer_[BUFFER_SIZE];   ///< Receive buffer for TCP I/O
-    OutputBufferPtr tcp_send_buffer_;           ///< Send buffer for TCP I/O
-    tcp::socket     tcp_socket_;                ///< Socket used by TCP server
-
-    /// Data for UDP
-    udp::endpoint   udp_remote_;                ///< Endpoint for UDP receives
-    size_t          udp_length_;                ///< Expected length value
-    uint8_t         udp_receive_buffer_[BUFFER_SIZE];   ///< Receive buffer for UDP I/O
-    OutputBufferPtr udp_send_buffer_;           ///< Send buffer for UDP I/O
-    udp::socket     udp_socket_;                ///< Socket used by UDP server
-
-    /// Some of the tests cause an 'active' running query to be created, but
-    /// don't complete the framework that makes that query delete itself.
-    /// This member can be used to store it so that it is deleted automatically
-    /// when the test is finished.
-    AbstractRunningQuery* running_query_;
-
-    /// \brief Constructor
-    RecursiveQueryTest3() :
-        service_(),
-        dns_service_(service_, NULL, NULL),
-        question_(new Question(Name("ednsfallback"),
-                  RRClass::IN(), RRType::A())),
-        last_(NONE),
-        expected_(NONE),
-        question_buffer_(new OutputBuffer(BUFFER_SIZE)),
-        resolver_(new MockResolver3()),
-        nsas_(new isc::nsas::NameserverAddressStore(resolver_)),
-        tcp_cumulative_(0),
-        tcp_endpoint_(asio::ip::address::from_string(TEST_ADDRESS3),
-                      TEST_PORT3),
-        tcp_length_(0),
-        tcp_receive_buffer_(),
-        tcp_send_buffer_(new OutputBuffer(BUFFER_SIZE)),
-        tcp_socket_(service_.get_io_service()),
-        udp_remote_(),
-        udp_length_(0),
-        udp_receive_buffer_(),
-        udp_send_buffer_(new OutputBuffer(BUFFER_SIZE)),
-        udp_socket_(service_.get_io_service(), udp::v4()),
-        running_query_(NULL)
-    {
-    }
-
-    ~RecursiveQueryTest3() {
-        delete nsas_;
-        // It would delete itself, but after the io_service_, which could
-        // segfailt in case there were unhandled requests
-        resolver_.reset();
-        // In a similar note, we wait until the resolver has been cleaned up
-        // until deleting and active test running_query_
-        delete running_query_;
-    }
-
-    /// \brief Set Common Message Bits
-    ///
-    /// Sets up the common bits of a response message returned by the handlers.
-    ///
-    /// \param message Message buffer in RENDER mode.
-    /// \param qid QID to set the message to
-    void setCommonMessage(isc::dns::Message& message, uint16_t qid) {
-        message.setQid(qid);
-        message.setHeaderFlag(Message::HEADERFLAG_QR);
-        message.setOpcode(Opcode::QUERY());
-        message.setHeaderFlag(Message::HEADERFLAG_AA);
-        message.addQuestion(*question_);
-    }
-
-    /// \brief Set FORMERR answer
-    ///
-    /// \param message Message to update with FORMERR status
-    void setFORMERR(isc::dns::Message& message) {
-        message.setRcode(Rcode::FORMERR());
-    }
-
-    /// \brief Set Answer
-    ///
-    /// \param message Message to update with FORMERR status
-    void setAnswer(isc::dns::Message& message) {
-        // Give a response
-        RRsetPtr answer(new RRset(Name("ednsfallback."), RRClass::IN(),
-                        RRType::A(), RRTTL(300)));
-        answer->addRdata(createRdata(RRType::A(), RRClass::IN(), DUMMY_ADDR3));
-        message.addRRset(Message::SECTION_ANSWER, answer);
-        message.setRcode(Rcode::NOERROR());
-    }
-
-    /// \brief UDP Receive Handler
-    ///
-    /// This is invoked when a message is received over UDP from the
-    /// RecursiveQuery object under test.  It formats an answer and sends it
-    /// asynchronously, with the UdpSendHandler method being specified as the
-    /// completion handler.
-    ///
-    /// \param ec ASIO error code, completion code of asynchronous I/O issued
-    ///        by the "server" to receive data.
-    /// \param length Amount of data received.
-    void udpReceiveHandler(asio::error_code ec = asio::error_code(),
-                           size_t length = 0) {
-        // Expected state should be one greater than the last state.
-        EXPECT_EQ(static_cast<int>(expected_), static_cast<int>(last_) + 1);
-        last_ = expected_;
-
-        Message query(Message::PARSE);
-
-        // The QID in the incoming data is random so set it to 0 for the
-        // data comparison check. (It is set to 0 in the buffer containing
-        // the expected data.)
-        // And check that question we received is what was expected.
-        checkReceivedPacket(udp_receive_buffer_, length, query);
-
-        // The message returned depends on what state we are in.  Set up
-        // common stuff first: bits not mentioned are set to 0.
-        Message message(Message::RENDER);
-        setCommonMessage(message, query.getQid());
-
-        // Set up state-dependent bits:
-        switch (expected_) {
-        case EDNS_UDP:
-            EXPECT_TRUE(query.getEDNS());
-            // Return FORMERROR
-            setFORMERR(message);
-            expected_ = NON_EDNS_UDP;
-            break;
-
-        case NON_EDNS_UDP:
-            EXPECT_FALSE(query.getEDNS());
-            // Return the answer to the question.
-            setAnswer(message);
-            expected_ = COMPLETE;
-            break;
-
-         default:
-            FAIL() << "UdpReceiveHandler called with unknown state";
-        }
-
-        // Convert to wire format
-        udp_send_buffer_->clear();
-        MessageRenderer renderer;
-        renderer.setBuffer(udp_send_buffer_.get());
-        message.toWire(renderer);
-        renderer.setBuffer(NULL);
-
-        // Return a message back to the IOFetch object (after setting the
-        // expected length of data for the check in the send handler).
-        udp_length_ = udp_send_buffer_->getLength();
-        udp_socket_.async_send_to(asio::buffer(udp_send_buffer_->getData(),
-                                               udp_send_buffer_->getLength()),
-                                  udp_remote_,
-                              boost::bind(&RecursiveQueryTest3::udpSendHandler,
-                                              this, _1, _2));
-    }
-
-    /// \brief UDP Send Handler
-    ///
-    /// Called when a send operation of the UDP server (i.e. a response
-    /// being sent to the RecursiveQuery) has completed, this re-issues
-    /// a read call.
-    ///
-    /// \param ec Completion error code of the send.
-    /// \param length Actual number of bytes sent.
-    void udpSendHandler(asio::error_code ec = asio::error_code(),
-                        size_t length = 0) {
-        // Check send was OK
-        EXPECT_EQ(0, ec.value());
-        EXPECT_EQ(udp_length_, length);
-
-        // Reissue the receive call to await the next message.
-        udp_socket_.async_receive_from(
-            asio::buffer(udp_receive_buffer_, sizeof(udp_receive_buffer_)),
-            udp_remote_,
-            boost::bind(&RecursiveQueryTest3::udpReceiveHandler,
-                        this, _1, _2));
-    }
-
-    /// \brief Completion Handler for Accepting TCP Data
-    ///
-    /// Called when the remote system connects to the "TCP server".  It issues
-    /// an asynchronous read on the socket to read data.
-    ///
-    /// \param socket Socket on which data will be received
-    /// \param ec Boost error code, value should be zero.
-    void tcpAcceptHandler(asio::error_code ec = asio::error_code(),
-                          size_t length = 0) {
-        // Expect that the accept completed without a problem.
-        EXPECT_EQ(0, ec.value());
-
-        // Initiate a read on the socket, indicating that nothing has yet been
-        // received.
-        tcp_cumulative_ = 0;
-        tcp_socket_.async_receive(
-            asio::buffer(tcp_receive_buffer_, sizeof(tcp_receive_buffer_)),
-            boost::bind(&RecursiveQueryTest3::tcpReceiveHandler, this, _1, _2));
-    }
-
-    /// \brief Completion Handler for Receiving TCP Data
-    ///
-    /// Reads data from the RecursiveQuery object and loops, reissuing reads,
-    /// until all the message has been read.  It then returns an appropriate
-    /// response.
-    ///
-    /// \param socket Socket to use to send the answer
-    /// \param ec ASIO error code, completion code of asynchronous I/O issued
-    ///        by the "server" to receive data.
-    /// \param length Amount of data received.
-    void tcpReceiveHandler(asio::error_code ec = asio::error_code(),
-                           size_t length = 0) {
-        // Expect that the receive completed without a problem.
-        EXPECT_EQ(0, ec.value());
-
-        // Have we received all the data?  We know this by checking if the two-
-        // byte length count in the message is equal to the data received.
-        tcp_cumulative_ += length;
-        bool complete = false;
-        if (tcp_cumulative_ > 2) {
-            uint16_t dns_length = readUint16(tcp_receive_buffer_,
-                                             sizeof(tcp_receive_buffer_));
-            complete = ((dns_length + 2) == tcp_cumulative_);
-        }
-
-        if (!complete) {
-            // Not complete yet, issue another read.
-            tcp_socket_.async_receive(
-                asio::buffer(tcp_receive_buffer_ + tcp_cumulative_,
-                             sizeof(tcp_receive_buffer_) - tcp_cumulative_),
-                boost::bind(&RecursiveQueryTest3::tcpReceiveHandler,
-                            this, _1, _2));
-            return;
-        }
-
-        // Have received a TCP message.  Expected state should be one greater
-        // than the last state.
-        EXPECT_EQ(static_cast<int>(expected_), static_cast<int>(last_) + 1);
-        last_ = expected_;
-
-        Message query(Message::PARSE);
-
-        // Check that question we received is what was expected.  Note that we
-        // have to ignore the two-byte header in order to parse the message.
-        checkReceivedPacket(tcp_receive_buffer_ + 2, length - 2, query);
-
-        // Return a message back.  This is a referral to example.org, which
-        // should result in another query over UDP.  Note the setting of the
-        // QID in the returned message with what was in the received message.
-        Message message(Message::RENDER);
-        setCommonMessage(message, query.getQid());
-
-        // Set up state-dependent bits:
-        switch (expected_) {
-        default:
-            FAIL() << "TcpReceiveHandler called with unknown state";
-        }
-
-
-        // Convert to wire format
-        // Use a temporary buffer for the dns wire data (we copy it
-        // to the 'real' buffer below)
-        MessageRenderer renderer;
-        message.toWire(renderer);
-
-        // Also, take this opportunity to clear the accumulated read count in
-        // readiness for the next read. (If any - at present, there is only
-        // one read in the test, although extensions to this test suite could
-        // change that.)
-        tcp_cumulative_ = 0;
-
-        // Unless we go through a callback loop we cannot simply use
-        // async_send() multiple times, so we cannot send the size first
-        // followed by the actual data. We copy them to a new buffer
-        // first
-        tcp_send_buffer_->clear();
-        tcp_send_buffer_->writeUint16(renderer.getLength());
-        tcp_send_buffer_->writeData(renderer.getData(), renderer.getLength());
-        tcp_socket_.async_send(asio::buffer(tcp_send_buffer_->getData(),
-                                            tcp_send_buffer_->getLength()),
-                               boost::bind(
-                                   &RecursiveQueryTest3::tcpSendHandler,
-                                   this,
-                                   tcp_send_buffer_->getLength(), _1, _2));
-    }
-
-    /// \brief Completion Handler for Sending TCP data
-    ///
-    /// Called when the asynchronous send of data back to the RecursiveQuery
-    /// by the TCP "server" in this class has completed.  (This send has to
-    /// be asynchronous because control needs to return to the caller in order
-    /// for the IOService "run()" method to be called to run the handlers.)
-    ///
-    /// \param expected_length Number of bytes that were expected to have been
-    /// sent.
-    /// \param ec Boost error code, value should be zero.
-    /// \param length Number of bytes sent.
-    void tcpSendHandler(size_t expected_length = 0,
-                        asio::error_code ec = asio::error_code(),
-                        size_t length = 0)
-    {
-        EXPECT_EQ(0, ec.value());       // Expect no error
-        EXPECT_EQ(expected_length, length);    // And that amount sent is as
-                                               // expected
-    }
-
-    /// \brief Check Received Packet
-    ///
-    /// Checks the packet received from the RecursiveQuery object to ensure
-    /// that the question is what is expected.
-    ///
-    /// \param data Start of data.  This is the start of the received buffer in
-    ///        the case of UDP data, and an offset into the buffer past the
-    ///        count field for TCP data.
-    /// \param length Length of data.
-    /// \return The QID of the message
-    void checkReceivedPacket(uint8_t* data, size_t length, Message& message) {
-
-        // Decode the received buffer.
-        InputBuffer buffer(data, length);
-        message.fromWire(buffer);
-
-        // Check the packet.
-        EXPECT_FALSE(message.getHeaderFlag(Message::HEADERFLAG_QR));
-
-        Question question = **(message.beginQuestion());
-        EXPECT_TRUE(question == *question_);
-    }
-};
-
-/// \brief Resolver Callback Object
-///
-/// Holds the success and failure callback methods for the resolver
-class ResolverCallback3 : public isc::resolve::ResolverInterface::Callback {
-public:
-    /// \brief Constructor
-    ResolverCallback3(IOService& service) :
-        service_(service), run_(false), status_(false)
-    {}
-
-    /// \brief Destructor
-    virtual ~ResolverCallback3()
-    {}
-
-    /// \brief Resolver Callback Success
-    ///
-    /// Called if the resolver detects that the call has succeeded.
-    ///
-    /// \param response Answer to the question.
-    virtual void success(const isc::dns::MessagePtr response) {
-        // There should be one RR each  in the question and answer sections,
-        // and two RRs in each of the the authority and additional sections.
-        EXPECT_EQ(1, response->getRRCount(Message::SECTION_QUESTION));
-        EXPECT_EQ(1, response->getRRCount(Message::SECTION_ANSWER));
-
-        // Check the answer - that the RRset is there...
-        EXPECT_TRUE(response->hasRRset(Message::SECTION_ANSWER,
-                                       RRsetPtr(new RRset(Name("ednsfallback."),
-                                                RRClass::IN(),
-                                                RRType::A(),
-                                                RRTTL(300)))));
-        const RRsetIterator rrset_i = response->beginSection(Message::SECTION_ANSWER);
-
-        // ... get iterator into the Rdata of this RRset and point to first
-        // element...
-        const RdataIteratorPtr rdata_i = (*rrset_i)->getRdataIterator();
-        rdata_i->first();
-
-        // ... and check it is what we expect.
-        EXPECT_EQ(string(DUMMY_ADDR3), rdata_i->getCurrent().toText());
-
-        // Flag completion
-        run_ = true;
-        status_ = true;
-
-        service_.stop();    // Cause run() to exit.
-    }
-
-    /// \brief Resolver Failure Completion
-    ///
-    /// Called if the resolver detects that the resolution has failed.
-    virtual void failure() {
-        FAIL() << "Resolver reported completion failure";
-
-        // Flag completion
-        run_ = true;
-        status_ = false;
-
-        service_.stop();    // Cause run() to exit.
-    }
-
-    /// \brief Return status of "run" flag
-    bool getRun() const {
-        return (run_);
-    }
-
-    /// \brief Return "status" flag
-    bool getStatus() const {
-        return (status_);
-    }
-
-private:
-    IOService&      service_;       ///< Service handling the run queue
-    bool            run_;           ///< Set true when completion handler run
-    bool            status_;        ///< Set true for success, false on error
-};
-
-// Sets up the UDP and TCP "servers", then tries a resolution.
-
-TEST_F(RecursiveQueryTest3, Resolve) {
-    // Set up the UDP server and issue the first read.  The endpoint from which
-    // the query is sent is put in udp_endpoint_ when the read completes, which
-    // is referenced in the callback as the place to which the response is
-    // sent.
-    udp_socket_.set_option(socket_base::reuse_address(true));
-    udp_socket_.bind(udp::endpoint(address::from_string(TEST_ADDRESS3),
-                                   TEST_PORT3));
-    udp_socket_.async_receive_from(asio::buffer(udp_receive_buffer_,
-                                                sizeof(udp_receive_buffer_)),
-                                   udp_remote_,
-                           boost::bind(&RecursiveQueryTest3::udpReceiveHandler,
-                                               this, _1, _2));
-
-    // Set up the TCP server and issue the accept.  Acceptance will cause the
-    // read to be issued.
-    tcp::acceptor acceptor(service_.get_io_service(),
-                           tcp::endpoint(tcp::v4(), TEST_PORT3));
-    acceptor.async_accept(tcp_socket_,
-                          boost::bind(&RecursiveQueryTest3::tcpAcceptHandler,
-                                      this, _1, 0));
-
-    // Set up the RecursiveQuery object. We will also test that it correctly
-    // records RTT times by setting up a RTT recorder object as well.
-    std::vector<std::pair<std::string, uint16_t> > upstream;         // Empty
-    std::vector<std::pair<std::string, uint16_t> > upstream_root;    // Empty
-    RecursiveQuery query(dns_service_, *nsas_, cache_,
-                         upstream, upstream_root);
-    query.setTestServer(TEST_ADDRESS3, TEST_PORT3);
-
-    boost::shared_ptr<RttRecorder> recorder(new RttRecorder());
-    query.setRttRecorder(recorder);
-
-    // Set up callback to receive notification that the query has completed.
-    isc::resolve::ResolverInterface::CallbackPtr
-        resolver_callback(new ResolverCallback3(service_));
-
-    // Kick off the resolution process.
-    expected_ = EDNS_UDP;
-    running_query_ = query.resolve(question_, resolver_callback);
-    service_.run();
-
-    // Check what ran. (We have to cast the callback to ResolverCallback3 as we
-    // lost the information on the derived class when we used a
-    // ResolverInterface::CallbackPtr to store a pointer to it.)
-    ResolverCallback3* rc
-                    = static_cast<ResolverCallback3*>(resolver_callback.get());
-    EXPECT_TRUE(rc->getRun());
-    EXPECT_TRUE(rc->getStatus());
-
-    // Finally, check that all the RTTs were "reasonable" (defined here as
-    // being below 2 seconds).  This is an explicit check to test that the
-    // variables in the RTT calculation are at least being initialized; if they
-    // weren't, we would expect some absurdly high answers.
-    vector<uint32_t> rtt = recorder->getRtt();
-    EXPECT_GT(rtt.size(), 0);
-    for (int i = 0; i < rtt.size(); ++i) {
-        EXPECT_LT(rtt[i], 2000);
-    }
-}
-
-} // namespace asiodns
-} // namespace isc
diff --git a/src/lib/resolve/tests/resolve_unittest.cc b/src/lib/resolve/tests/resolve_unittest.cc
deleted file mode 100644 (file)
index 85d264d..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright (C) 2010  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 <iostream>
-#include <gtest/gtest.h>
-
-#include <dns/message.h>
-#include <dns/question.h>
-#include <dns/opcode.h>
-#include <dns/rcode.h>
-#include <dns/rrttl.h>
-#include <dns/rdata.h>
-#include <resolve/resolve.h>
-
-using namespace isc::dns;
-
-namespace {
-
-class ResolveHelperFunctionsTest : public ::testing::Test {
-public:
-    ResolveHelperFunctionsTest() :
-        message_a_(new Message(Message::RENDER)),
-        message_b_(new Message(Message::RENDER)),
-        question_(new Question(Name("www.example.com"), RRClass::IN(), RRType::A()))
-    {
-        createMessageA();
-        createMessageB();
-    };
-
-    void createMessageA() {
-        message_a_->setOpcode(Opcode::QUERY());
-        message_a_->setRcode(Rcode::NOERROR());
-        message_a_->addQuestion(question_);
-    }
-
-    void createMessageB() {
-        message_b_->setOpcode(Opcode::QUERY());
-        message_b_->setRcode(Rcode::NOERROR());
-        message_b_->addQuestion(question_);
-
-        // We could reuse the same rrset in the different sections,
-        // but to be sure, we create separate ones
-        RRsetPtr answer_rrset(new RRset(Name("www.example.com"),
-                                        RRClass::IN(), RRType::TXT(),
-                                        RRTTL(3600)));
-        answer_rrset->addRdata(rdata::createRdata(RRType::TXT(),
-                                                  RRClass::IN(),
-                                                  "Answer"));
-        message_b_->addRRset(Message::SECTION_ANSWER, answer_rrset);
-    
-        RRsetPtr auth_rrset(new RRset(Name("www.example.com"),
-                                        RRClass::IN(), RRType::TXT(),
-                                        RRTTL(3600)));
-        auth_rrset->addRdata(rdata::createRdata(RRType::TXT(),
-                                                  RRClass::IN(),
-                                                  "Authority"));
-        auth_rrset->addRdata(rdata::createRdata(RRType::TXT(),
-                                                  RRClass::IN(),
-                                                  "Rdata"));
-        message_b_->addRRset(Message::SECTION_AUTHORITY, auth_rrset);
-    
-        RRsetPtr add_rrset(new RRset(Name("www.example.com"),
-                                     RRClass::IN(), RRType::TXT(),
-                                     RRTTL(3600)));
-        add_rrset->addRdata(rdata::createRdata(RRType::TXT(),
-                                               RRClass::IN(),
-                                               "Additional"));
-        add_rrset->addRdata(rdata::createRdata(RRType::TXT(),
-                                               RRClass::IN(),
-                                               "Rdata"));
-        add_rrset->addRdata(rdata::createRdata(RRType::TXT(),
-                                               RRClass::IN(),
-                                               "fields."));
-        message_b_->addRRset(Message::SECTION_ADDITIONAL, add_rrset);
-    };
-
-    MessagePtr message_a_;
-    MessagePtr message_b_;
-    QuestionPtr question_;
-};
-
-TEST_F(ResolveHelperFunctionsTest, makeErrorMessageEmptyMessage) {
-    ASSERT_EQ(Rcode::NOERROR(), message_a_->getRcode());
-    ASSERT_EQ(1, message_a_->getRRCount(Message::SECTION_QUESTION));
-    ASSERT_EQ(0, message_a_->getRRCount(Message::SECTION_ANSWER));
-    ASSERT_EQ(0, message_a_->getRRCount(Message::SECTION_AUTHORITY));
-    ASSERT_EQ(0, message_a_->getRRCount(Message::SECTION_ADDITIONAL));
-
-    isc::resolve::makeErrorMessage(message_a_, Rcode::SERVFAIL());
-    EXPECT_EQ(Rcode::SERVFAIL(), message_a_->getRcode());
-    EXPECT_EQ(1, message_a_->getRRCount(Message::SECTION_QUESTION));
-    EXPECT_EQ(0, message_a_->getRRCount(Message::SECTION_ANSWER));
-    EXPECT_EQ(0, message_a_->getRRCount(Message::SECTION_AUTHORITY));
-    EXPECT_EQ(0, message_a_->getRRCount(Message::SECTION_ADDITIONAL));
-}
-
-TEST_F(ResolveHelperFunctionsTest, makeErrorMessageNonEmptyMessage) {
-
-    ASSERT_EQ(Rcode::NOERROR(), message_b_->getRcode());
-    ASSERT_EQ(1, message_b_->getRRCount(Message::SECTION_QUESTION));
-    ASSERT_EQ(1, message_b_->getRRCount(Message::SECTION_ANSWER));
-    ASSERT_EQ(2, message_b_->getRRCount(Message::SECTION_AUTHORITY));
-    ASSERT_EQ(3, message_b_->getRRCount(Message::SECTION_ADDITIONAL));
-
-    isc::resolve::makeErrorMessage(message_b_, Rcode::FORMERR());
-    EXPECT_EQ(Rcode::FORMERR(), message_b_->getRcode());
-    EXPECT_EQ(1, message_b_->getRRCount(Message::SECTION_QUESTION));
-    EXPECT_EQ(0, message_b_->getRRCount(Message::SECTION_ANSWER));
-    EXPECT_EQ(0, message_b_->getRRCount(Message::SECTION_AUTHORITY));
-    EXPECT_EQ(0, message_b_->getRRCount(Message::SECTION_ADDITIONAL));
-}
-
-void
-compareSections(const Message& message_a, const Message& message_b,
-                Message::Section section)
-{
-    RRsetIterator rrs_a = message_a.beginSection(section);
-    RRsetIterator rrs_b = message_b.beginSection(section);
-    while (rrs_a != message_a.endSection(section) &&
-           rrs_b != message_b.endSection(section)
-          ) {
-        EXPECT_EQ(*rrs_a, *rrs_b);
-        ++rrs_a;
-        ++rrs_b;
-    }
-    // can't use EXPECT_EQ here, no eqHelper for endsection comparison
-    EXPECT_TRUE(rrs_a == message_a.endSection(section));
-    EXPECT_TRUE(rrs_b == message_b.endSection(section));
-}
-
-TEST_F(ResolveHelperFunctionsTest, initResponseMessage) {
-    Message response_parse(Message::PARSE);
-    EXPECT_THROW(isc::resolve::initResponseMessage(*message_a_,
-                                                   response_parse),
-                 isc::dns::InvalidMessageOperation);
-    EXPECT_THROW(isc::resolve::initResponseMessage(*question_,
-                                                   response_parse),
-                 isc::dns::InvalidMessageOperation);
-    
-    Message response1(Message::RENDER);
-    isc::resolve::initResponseMessage(*message_a_, response1);
-    ASSERT_EQ(message_a_->getOpcode(), response1.getOpcode());
-    ASSERT_EQ(message_a_->getQid(), response1.getQid());
-    isc::dns::QuestionIterator qi = response1.beginQuestion();
-    ASSERT_EQ(*question_, **qi);
-    ASSERT_TRUE(++qi == response1.endQuestion());
-
-    Message response2(Message::RENDER);
-    isc::resolve::initResponseMessage(*question_, response2);
-    ASSERT_EQ(Opcode::QUERY(), response2.getOpcode());
-    ASSERT_EQ(0, response2.getQid());
-    qi = response2.beginQuestion();
-    ASSERT_EQ(*question_, **qi);
-    ASSERT_TRUE(++qi == response2.endQuestion());
-}
-
-TEST_F(ResolveHelperFunctionsTest, copyAnswerMessage) {
-    message_b_->setRcode(Rcode::NXDOMAIN());
-    
-    ASSERT_NE(message_b_->getRcode(), message_a_->getRcode());
-    ASSERT_NE(message_b_->getRRCount(Message::SECTION_ANSWER),
-              message_a_->getRRCount(Message::SECTION_ANSWER));
-    ASSERT_NE(message_b_->getRRCount(Message::SECTION_AUTHORITY),
-              message_a_->getRRCount(Message::SECTION_AUTHORITY));
-    ASSERT_NE(message_b_->getRRCount(Message::SECTION_ADDITIONAL),
-              message_a_->getRRCount(Message::SECTION_ADDITIONAL));
-    ASSERT_EQ(0, message_a_->getRRCount(Message::SECTION_ANSWER));
-    ASSERT_EQ(0, message_a_->getRRCount(Message::SECTION_AUTHORITY));
-    ASSERT_EQ(0, message_a_->getRRCount(Message::SECTION_ADDITIONAL));
-
-    isc::resolve::copyResponseMessage(*message_b_, message_a_);
-
-    EXPECT_EQ(message_b_->getRcode(), message_a_->getRcode());
-    ASSERT_EQ(message_b_->getRRCount(Message::SECTION_ANSWER),
-              message_a_->getRRCount(Message::SECTION_ANSWER));
-    ASSERT_EQ(message_b_->getRRCount(Message::SECTION_AUTHORITY),
-              message_a_->getRRCount(Message::SECTION_AUTHORITY));
-    ASSERT_EQ(message_b_->getRRCount(Message::SECTION_ADDITIONAL),
-              message_a_->getRRCount(Message::SECTION_ADDITIONAL));
-
-    
-    compareSections(*message_a_, *message_b_, Message::SECTION_ANSWER);
-    compareSections(*message_a_, *message_b_, Message::SECTION_AUTHORITY);
-    compareSections(*message_a_, *message_b_, Message::SECTION_ADDITIONAL);
-}
-
-} // Anonymous namespace
diff --git a/src/lib/resolve/tests/resolver_callback_unittest.cc b/src/lib/resolve/tests/resolver_callback_unittest.cc
deleted file mode 100644 (file)
index e94f13d..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (C) 2010  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 <gtest/gtest.h>
-#include <asiodns/dns_server.h>
-#include <resolve/resolver_callback.h>
-
-using namespace isc::resolve;
-
-// Dummy subclass for DNSServer*
-// We want to check if resume is called
-// Since the server will get cloned(), we want the clones to share
-// our bools for whether resume got called and with what value
-class DummyServer : public isc::asiodns::DNSServer {
-public:
-    DummyServer(DummyServer* orig) {
-        resume_called_ = orig->getResumeCalled();
-        resume_value_ = orig->getResumeValue();
-    }
-    DummyServer(bool* resume_called, bool* resume_value) :
-        resume_called_(resume_called), resume_value_(resume_value)
-    {}
-
-    bool* getResumeCalled() { return resume_called_; }
-    bool* getResumeValue() { return resume_value_; }
-
-    DNSServer* clone() {
-        DummyServer* n = new DummyServer(this);
-        return n;
-    }
-
-    void resume(bool value) {
-        *resume_called_ = true;
-        *resume_value_ = value;
-    }
-
-private:
-    bool* resume_called_;
-    bool* resume_value_;
-};
-
-class ResolverCallbackServerTest : public ::testing::Test {
-public:
-    ResolverCallbackServerTest() : resume_called_(false),
-                                   resume_value_(false) {
-        server_ = new DummyServer(&resume_called_, &resume_value_);
-        callback_ = new ResolverCallbackServer(server_);
-    };
-
-    ~ResolverCallbackServerTest() {
-        delete callback_;
-        delete server_;
-    }
-
-    DummyServer* getServer() { return server_; }
-    ResolverCallbackServer* getCallback() { return callback_; }
-    bool getResumeCalled() { return resume_called_; }
-    bool getResumeValue() { return resume_value_; }
-
-private:
-    DummyServer* server_;
-    ResolverCallbackServer* callback_;
-    bool resume_called_;
-    bool resume_value_;
-};
-
-TEST_F(ResolverCallbackServerTest, testSuccess) {
-    EXPECT_FALSE(getResumeCalled());
-    getCallback()->success(isc::dns::MessagePtr());
-    EXPECT_TRUE(getResumeCalled());
-    EXPECT_TRUE(getResumeValue());
-}
-
-TEST_F(ResolverCallbackServerTest, testFailure) {
-    EXPECT_FALSE(getResumeCalled());
-    getCallback()->failure();
-    EXPECT_TRUE(getResumeCalled());
-    EXPECT_FALSE(getResumeValue());
-}
diff --git a/src/lib/resolve/tests/response_classifier_unittest.cc b/src/lib/resolve/tests/response_classifier_unittest.cc
deleted file mode 100644 (file)
index 30aeabb..0000000
+++ /dev/null
@@ -1,554 +0,0 @@
-// Copyright (C) 2010  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 <iostream>
-#include <gtest/gtest.h>
-
-#include <dns/tests/unittest_util.h>
-
-#include <resolve/response_classifier.h>
-
-#include <dns/name.h>
-#include <dns/opcode.h>
-#include <dns/question.h>
-#include <dns/rdata.h>
-#include <dns/rdataclass.h>
-#include <dns/rcode.h>
-#include <dns/rrclass.h>
-#include <dns/rrset.h>
-#include <dns/rrtype.h>
-#include <dns/rrttl.h>
-
-using namespace std;
-using namespace isc::dns;
-using namespace rdata;
-using namespace isc::dns::rdata::generic;
-using namespace isc::dns::rdata::in;
-using namespace isc::resolve;
-
-
-namespace {
-class ResponseClassifierTest : public ::testing::Test {
-public:
-    /// \brief Constructor
-    ///
-    /// The naming convention is:
-    ///
-    /// <category>_<class>_<type>_<name>
-    ///
-    /// <category> is "qu" (question), "rrs" (rrset),
-    /// <qclass> is self-explanatory
-    /// <qtype> is self-explanatory
-    /// <name> is the first part of the domain name (all expected to be in
-    /// example.com)
-    ///
-    /// Message variables
-    ///
-    /// msg_<qtype>  Where <qtype> is the type of query.  These are only used
-    /// in the early tests where simple messages are required.
-
-    ResponseClassifierTest() :
-        msg_a(Message::RENDER),
-        msg_any(Message::RENDER),
-        qu_ch_a_www(Name("www.example.com"), RRClass::CH(), RRType::A()),
-        qu_in_any_www(Name("www.example.com"), RRClass::IN(), RRType::ANY()),
-        qu_in_a_www2(Name("www2.example.com"), RRClass::IN(), RRType::A()),
-        qu_in_a_www(Name("www.example.com"), RRClass::IN(), RRType::A()),
-        qu_in_cname_www1(Name("www1.example.com"), RRClass::IN(), RRType::A()),
-        qu_in_ns_(Name("example.com"), RRClass::IN(), RRType::NS()),
-        qu_in_txt_www(Name("www.example.com"), RRClass::IN(), RRType::TXT()),
-        rrs_hs_txt_www(new RRset(Name("www.example.com"), RRClass::HS(),
-            RRType::TXT(), RRTTL(300))),
-        rrs_in_a_mail(new RRset(Name("mail.example.com"), RRClass::IN(),
-            RRType::A(), RRTTL(300))),
-        rrs_in_a_www(new RRset(Name("www.example.com"), RRClass::IN(),
-            RRType::A(), RRTTL(300))),
-        rrs_in_cname_www1(new RRset(Name("www1.example.com"), RRClass::IN(),
-            RRType::CNAME(), RRTTL(300))),
-        rrs_in_cname_www2(new RRset(Name("www2.example.com"), RRClass::IN(),
-            RRType::CNAME(), RRTTL(300))),
-        rrs_in_ns_(new RRset(Name("example.com"), RRClass::IN(),
-            RRType::NS(), RRTTL(300))),
-        rrs_in_soa_(new RRset(Name("example.com"), RRClass::IN(),
-            RRType::SOA(), RRTTL(300))),
-        rrs_in_txt_www(new RRset(Name("www.example.com"), RRClass::IN(),
-            RRType::TXT(), RRTTL(300))),
-        cname_target("."),
-        cname_count(0)
-    {
-        // Set up the message to indicate a successful response to the question
-        // "www.example.com A", but don't add in any response sections.
-        msg_a.setHeaderFlag(Message::HEADERFLAG_QR);
-        msg_a.setOpcode(Opcode::QUERY());
-        msg_a.setRcode(Rcode::NOERROR());
-        msg_a.addQuestion(qu_in_a_www);
-
-        // ditto for the query "www.example.com ANY"
-        msg_any.setHeaderFlag(Message::HEADERFLAG_QR);
-        msg_any.setOpcode(Opcode::QUERY());
-        msg_any.setRcode(Rcode::NOERROR());
-        msg_any.addQuestion(qu_in_any_www);
-
-        // The next set of assignments set up the following zone records
-        //
-        // example.com           NS     ns0.isc.org
-        //                       NS     ns0.example.org
-        //
-        // www.example.com       A      1.2.3.4
-        //                       TXT    "An example text string"
-        //
-        // mail.example.com      A      4.5.6.7
-        //
-        // www1.example.com      CNAME  www.example.com
-        //
-        // www2.example.com      CNAME  www1.example.com
-
-        // Set up an imaginary NS RRset for an authority section
-        rrs_in_ns_->addRdata(ConstRdataPtr(new NS(Name("ns0.isc.org"))));
-        rrs_in_ns_->addRdata(ConstRdataPtr(new NS(Name("ns0.example.org"))));
-        
-        // And an imaginary SOA
-        rrs_in_soa_->addRdata(ConstRdataPtr(new SOA(Name("ns0.example.org"), Name("root.example.org"), 1, 2, 3, 4, 5)));
-
-        // Set up the records for the www host
-        rrs_in_a_www->addRdata(ConstRdataPtr(new A("1.2.3.4")));
-        rrs_in_txt_www->addRdata(ConstRdataPtr(
-            new TXT("An example text string")));
-
-        // ... for the mail host
-        rrs_in_a_mail->addRdata(ConstRdataPtr(new A("5.6.7.8")));
-
-        // ... the CNAME records
-        rrs_in_cname_www1->addRdata(ConstRdataPtr(
-            new CNAME("www.example.com.")));
-        rrs_in_cname_www2->addRdata(ConstRdataPtr(
-            new CNAME("www1.example.com.")));
-    }
-
-    Message     msg_a;              // Pointer to message in RENDER state
-    Message     msg_any;            // Pointer to message in RENDER state
-    Question    qu_ch_a_www;        // www.example.com CH A
-    Question    qu_in_any_www;      // www.example.com IN ANY
-    Question    qu_in_a_www2;       // www.example.com IN ANY
-    Question    qu_in_a_www;        // www.example.com IN A
-    Question    qu_in_cname_www1;   // www1.example.com IN CNAME
-    Question    qu_in_ns_;          // example.com IN NS
-    Question    qu_in_txt_www;      // www.example.com IN TXT
-    RRsetPtr    rrs_hs_txt_www;     // www.example.com HS TXT
-    RRsetPtr    rrs_in_a_mail;      // mail.example.com IN A
-    RRsetPtr    rrs_in_a_www;       // www.example.com IN A
-    RRsetPtr    rrs_in_cname_www1;  // www1.example.com IN CNAME
-    RRsetPtr    rrs_in_cname_www2;  // www2.example.com IN CNAME
-    RRsetPtr    rrs_in_ns_;         // example.com IN NS
-    RRsetPtr    rrs_in_soa_;        // example.com IN SOA
-    RRsetPtr    rrs_in_txt_www;     // www.example.com IN TXT
-    Name        cname_target;       // Used in response classifier to
-                                    // store the target of a possible
-                                    // CNAME chain
-    unsigned int cname_count;       // Used to count cnames in a chain
-};
-
-// Test that the error() function categorises the codes correctly.
-
-TEST_F(ResponseClassifierTest, StatusCodes) {
-    EXPECT_FALSE(ResponseClassifier::error(ResponseClassifier::ANSWER));
-    EXPECT_FALSE(ResponseClassifier::error(ResponseClassifier::ANSWERCNAME));
-    EXPECT_FALSE(ResponseClassifier::error(ResponseClassifier::CNAME));
-    EXPECT_FALSE(ResponseClassifier::error(ResponseClassifier::NXDOMAIN));
-    EXPECT_FALSE(ResponseClassifier::error(ResponseClassifier::REFERRAL));
-
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::EMPTY));
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::EXTRADATA));
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::INVNAMCLASS));
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::INVTYPE));
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::MISMATQUEST));
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::MULTICLASS));
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::NOTONEQUEST));
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::NOTRESPONSE));
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::NOTSINGLE));
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::OPCODE));
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::RCODE));
-    EXPECT_TRUE(ResponseClassifier::error(ResponseClassifier::TRUNCATED));
-}
-
-// Test that the system will reject a message which is a query.
-
-TEST_F(ResponseClassifierTest, Query) {
-
-    // Set up message to indicate a query (QR flag = 0, one question).  By
-    // default the opcode will be 0 (query)
-    msg_a.setHeaderFlag(Message::HEADERFLAG_QR, false);
-
-    // Should be rejected as it is a query, not a response
-    EXPECT_EQ(ResponseClassifier::NOTRESPONSE,
-        ResponseClassifier::classify(qu_in_a_www, msg_a,
-                                     cname_target, cname_count));
-}
-
-// Check that we get an OPCODE error on all but QUERY opcodes.
-
-TEST_F(ResponseClassifierTest, Opcode) {
-
-    uint8_t query = static_cast<uint8_t>(Opcode::QUERY().getCode());
-
-    for (uint8_t i = 0; i < (1 << 4); ++i) {
-        msg_a.setOpcode(Opcode(i));
-        if (i == query) {
-            EXPECT_NE(ResponseClassifier::OPCODE,
-                ResponseClassifier::classify(qu_in_a_www, msg_a,
-                                             cname_target, cname_count));
-        } else {
-            EXPECT_EQ(ResponseClassifier::OPCODE,
-                ResponseClassifier::classify(qu_in_a_www, msg_a,
-                                             cname_target, cname_count));
-        }
-    }
-}
-
-// Test that the system will reject a response with anything other than one
-// question.
-
-TEST_F(ResponseClassifierTest, MultipleQuestions) {
-
-    // Create a message object for this test that has no question section.
-    Message message(Message::RENDER);
-    message.setHeaderFlag(Message::HEADERFLAG_QR);
-    message.setOpcode(Opcode::QUERY());
-    message.setRcode(Rcode::NOERROR());
-
-    // Zero questions
-    EXPECT_EQ(ResponseClassifier::NOTONEQUEST,
-        ResponseClassifier::classify(qu_in_a_www, message,
-                                     cname_target, cname_count));
-
-    // One question
-    message.addQuestion(qu_in_a_www);
-    EXPECT_NE(ResponseClassifier::NOTONEQUEST,
-        ResponseClassifier::classify(qu_in_a_www, message,
-                                     cname_target, cname_count));
-
-    // Two questions
-    message.addQuestion(qu_in_ns_);
-    EXPECT_EQ(ResponseClassifier::NOTONEQUEST,
-        ResponseClassifier::classify(qu_in_a_www, message,
-                                     cname_target, cname_count));
-
-    // And finish the check with three questions
-    message.addQuestion(qu_in_txt_www);
-    EXPECT_EQ(ResponseClassifier::NOTONEQUEST,
-        ResponseClassifier::classify(qu_in_a_www, message,
-                                     cname_target, cname_count));
-}
-
-// Test that the question in the question section in the message response
-// is equal to the question supplied.
-
-TEST_F(ResponseClassifierTest, SameQuestion) {
-
-    EXPECT_EQ(ResponseClassifier::MISMATQUEST,
-        ResponseClassifier::classify(qu_in_ns_, msg_a,
-                                     cname_target, cname_count));
-    EXPECT_NE(ResponseClassifier::MISMATQUEST,
-        ResponseClassifier::classify(qu_in_a_www, msg_a,
-                                     cname_target, cname_count));
-}
-
-// Should get an NXDOMAIN response only on an NXDOMAIN RCODE.
-
-TEST_F(ResponseClassifierTest, NXDOMAIN) {
-
-    uint16_t nxdomain = static_cast<uint16_t>(Rcode::NXDOMAIN().getCode());
-
-    for (uint8_t i = 0; i < (1 << 4); ++i) {
-        msg_a.setRcode(Rcode(i));
-        if (i == nxdomain) {
-            EXPECT_EQ(ResponseClassifier::NXDOMAIN,
-                ResponseClassifier::classify(qu_in_a_www, msg_a,
-                                             cname_target, cname_count));
-        } else {
-            EXPECT_NE(ResponseClassifier::NXDOMAIN,
-                ResponseClassifier::classify(qu_in_a_www, msg_a,
-                                             cname_target, cname_count));
-        }
-    }
-}
-
-// Check that we get an RCODE error on all but NXDOMAIN and NOERROR responses.
-
-TEST_F(ResponseClassifierTest, RCODE) {
-
-    uint16_t nxdomain = static_cast<uint16_t>(Rcode::NXDOMAIN().getCode());
-    uint16_t noerror = static_cast<uint16_t>(Rcode::NOERROR().getCode());
-
-    for (uint8_t i = 0; i < (1 << 4); ++i) {
-        msg_a.setRcode(Rcode(i));
-        if ((i == nxdomain) || (i == noerror)) {
-            EXPECT_NE(ResponseClassifier::RCODE,
-                ResponseClassifier::classify(qu_in_a_www, msg_a,
-                                             cname_target, cname_count));
-        } else {
-            EXPECT_EQ(ResponseClassifier::RCODE,
-                ResponseClassifier::classify(qu_in_a_www, msg_a,
-                                             cname_target, cname_count));
-        }
-    }
-}
-
-// Test that the code will detect a truncated message.  Even if nothing else
-// is wrong, we'll want to retry the query if we receive a truncated code.
-// However, we give the option to the user of the code aws to whether they
-// want to take into account the truncated bit.
-
-TEST_F(ResponseClassifierTest, Truncated) {
-
-    // Don't expect the truncated code whatever option we ask for if the TC
-    // bit is not set.
-    msg_a.setHeaderFlag(Message::HEADERFLAG_TC, false);
-    EXPECT_NE(ResponseClassifier::TRUNCATED,
-        ResponseClassifier::classify(qu_in_a_www, msg_a, cname_target,
-                                     cname_count, true));
-    EXPECT_NE(ResponseClassifier::TRUNCATED,
-        ResponseClassifier::classify(qu_in_a_www, msg_a, cname_target,
-                                     cname_count, false));
-
-    // Expect the truncated code if the TC bit is set, only if we don't ignore
-    // it.
-    msg_a.setHeaderFlag(Message::HEADERFLAG_TC, true);
-    EXPECT_NE(ResponseClassifier::TRUNCATED,
-        ResponseClassifier::classify(qu_in_a_www, msg_a, cname_target,
-                                     cname_count, true));
-    EXPECT_EQ(ResponseClassifier::TRUNCATED,
-        ResponseClassifier::classify(qu_in_a_www, msg_a, cname_target,
-                                     cname_count, false));
-}
-
-// Check for an empty packet (i.e. no error, but with the answer and additional
-// sections empty).
-
-TEST_F(ResponseClassifierTest, Empty) {
-
-    EXPECT_EQ(ResponseClassifier::EMPTY,
-        ResponseClassifier::classify(qu_in_a_www, msg_a, cname_target,
-                                     cname_count));
-}
-
-// Anything where we have an empty answer section but something in the
-// authority section is a referral (if the status is NOERROR).
-
-TEST_F(ResponseClassifierTest, EmptyAnswerReferral) {
-
-    msg_a.addRRset(Message::SECTION_AUTHORITY, rrs_in_ns_);
-    EXPECT_EQ(ResponseClassifier::REFERRAL,
-        ResponseClassifier::classify(qu_in_a_www, msg_a, cname_target,
-                                     cname_count));
-
-}
-
-// Test if we get a NOERROR answer that contains neither an actual
-// answer nor a delegation
-TEST_F(ResponseClassifierTest, NoErrorNoData) {
-
-    msg_a.addRRset(Message::SECTION_AUTHORITY, rrs_in_soa_);
-    EXPECT_EQ(ResponseClassifier::NXRRSET,
-        ResponseClassifier::classify(qu_in_a_www, msg_a, cname_target,
-                                     cname_count));
-
-}
-
-// Check the case where we have a simple answer in the answer section.  This
-// occurs when the QNAME/QTYPE/QCLASS matches one of the RRsets in the
-// answer section - expect when the QTYPE is ANY, in which case the match
-// must be on the QNAME/QCLASS alone.
-
-TEST_F(ResponseClassifierTest, SingleAnswer) {
-
-    // Check a question that matches the answer
-    msg_a.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
-    EXPECT_EQ(ResponseClassifier::ANSWER,
-        ResponseClassifier::classify(qu_in_a_www, msg_a, cname_target,
-                                     cname_count));
-
-    // Check an ANY question that matches the answer
-    msg_any.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
-    EXPECT_EQ(ResponseClassifier::ANSWER,
-        ResponseClassifier::classify(qu_in_any_www, msg_any, cname_target,
-                                     cname_count));
-
-    // Check a CNAME response that matches the QNAME.
-    Message message_a(Message::RENDER);
-    message_a.setHeaderFlag(Message::HEADERFLAG_QR);
-    message_a.setOpcode(Opcode::QUERY());
-    message_a.setRcode(Rcode::NOERROR());
-    message_a.addQuestion(qu_in_cname_www1);
-    message_a.addRRset(Message::SECTION_ANSWER, rrs_in_cname_www1);
-    EXPECT_EQ(ResponseClassifier::CNAME,
-        ResponseClassifier::classify(qu_in_cname_www1, message_a,
-                                     cname_target, cname_count));
-
-    // Check if the answer QNAME does not match the question
-    // Q: www.example.com  IN A
-    // A: mail.example.com IN A
-    Message message_b(Message::RENDER);
-    message_b.setHeaderFlag(Message::HEADERFLAG_QR);
-    message_b.setOpcode(Opcode::QUERY());
-    message_b.setRcode(Rcode::NOERROR());
-    message_b.addQuestion(qu_in_a_www);
-    message_b.addRRset(Message::SECTION_ANSWER, rrs_in_a_mail);
-    EXPECT_EQ(ResponseClassifier::INVNAMCLASS,
-        ResponseClassifier::classify(qu_in_a_www, message_b,
-                                     cname_target, cname_count));
-
-    // Check if the answer class does not match the question
-    // Q: www.example.com CH A
-    // A: www.example.com IN A
-    Message message_c(Message::RENDER);
-    message_c.setHeaderFlag(Message::HEADERFLAG_QR);
-    message_c.setOpcode(Opcode::QUERY());
-    message_c.setRcode(Rcode::NOERROR());
-    message_c.addQuestion(qu_ch_a_www);
-    message_c.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
-    EXPECT_EQ(ResponseClassifier::INVNAMCLASS,
-        ResponseClassifier::classify(qu_ch_a_www, message_c,
-                                     cname_target, cname_count));
-
-    // Check if the answer type does not match the question
-    // Q: www.example.com IN A
-    // A: www.example.com IN TXT
-    Message message_d(Message::RENDER);
-    message_d.setHeaderFlag(Message::HEADERFLAG_QR);
-    message_d.setOpcode(Opcode::QUERY());
-    message_d.setRcode(Rcode::NOERROR());
-    message_d.addQuestion(qu_in_a_www);
-    message_d.addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
-    EXPECT_EQ(ResponseClassifier::INVTYPE,
-        ResponseClassifier::classify(qu_in_a_www, message_d,
-                                     cname_target, cname_count));
-}
-
-// Check what happens if we have multiple RRsets in the answer.
-
-TEST_F(ResponseClassifierTest, MultipleAnswerRRsets) {
-
-    // All the same QNAME but different types is only valid on an ANY query.
-    Message message_a(Message::RENDER);
-    message_a.setHeaderFlag(Message::HEADERFLAG_QR);
-    message_a.setOpcode(Opcode::QUERY());
-    message_a.setRcode(Rcode::NOERROR());
-    message_a.addQuestion(qu_in_any_www);
-    message_a.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
-    message_a.addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
-    EXPECT_EQ(ResponseClassifier::ANSWER,
-        ResponseClassifier::classify(qu_in_any_www, message_a,
-                                     cname_target, cname_count));
-
-    // On another type of query, it results in an EXTRADATA error
-    Message message_b(Message::RENDER);
-    message_b.setHeaderFlag(Message::HEADERFLAG_QR);
-    message_b.setOpcode(Opcode::QUERY());
-    message_b.setRcode(Rcode::NOERROR());
-    message_b.addQuestion(qu_in_a_www);
-    message_b.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
-    message_b.addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
-    EXPECT_EQ(ResponseClassifier::EXTRADATA,
-        ResponseClassifier::classify(qu_in_a_www, message_b,
-                                     cname_target, cname_count));
-
-    // Same QNAME on an ANY query is not valid with mixed classes
-    Message message_c(Message::RENDER);
-    message_c.setHeaderFlag(Message::HEADERFLAG_QR);
-    message_c.setOpcode(Opcode::QUERY());
-    message_c.setRcode(Rcode::NOERROR());
-    message_c.addQuestion(qu_in_any_www);
-    message_c.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
-    message_c.addRRset(Message::SECTION_ANSWER, rrs_hs_txt_www);
-    EXPECT_EQ(ResponseClassifier::MULTICLASS,
-        ResponseClassifier::classify(qu_in_any_www, message_c,
-                                     cname_target, cname_count));
-
-    // Mixed QNAME is not valid unless QNAME requested is a CNAME.
-    Message message_d(Message::RENDER);
-    message_d.setHeaderFlag(Message::HEADERFLAG_QR);
-    message_d.setOpcode(Opcode::QUERY());
-    message_d.setRcode(Rcode::NOERROR());
-    message_d.addQuestion(qu_in_a_www);
-    message_d.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
-    message_d.addRRset(Message::SECTION_ANSWER, rrs_in_a_mail);
-    EXPECT_EQ(ResponseClassifier::EXTRADATA,
-        ResponseClassifier::classify(qu_in_a_www, message_d,
-                                     cname_target, cname_count));
-
-    // Mixed QNAME is not valid when the query is an ANY.
-    Message message_e(Message::RENDER);
-    message_e.setHeaderFlag(Message::HEADERFLAG_QR);
-    message_e.setOpcode(Opcode::QUERY());
-    message_e.setRcode(Rcode::NOERROR());
-    message_e.addQuestion(qu_in_any_www);
-    message_e.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
-    message_e.addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
-    message_e.addRRset(Message::SECTION_ANSWER, rrs_in_a_mail);
-    EXPECT_EQ(ResponseClassifier::EXTRADATA,
-        ResponseClassifier::classify(qu_in_any_www, message_e,
-                                     cname_target, cname_count));
-}
-
-// CNAME chain is CNAME if it terminates in a CNAME, answer if it
-// does not, and error if there are RRs left over.
-TEST_F(ResponseClassifierTest, CNAMEChain) {
-
-    // Answer contains a single CNAME
-    Message message_a(Message::RENDER);
-    message_a.setHeaderFlag(Message::HEADERFLAG_QR);
-    message_a.setOpcode(Opcode::QUERY());
-    message_a.setRcode(Rcode::NOERROR());
-    message_a.addQuestion(qu_in_a_www2);
-    message_a.addRRset(Message::SECTION_ANSWER, rrs_in_cname_www2);
-    EXPECT_EQ(ResponseClassifier::CNAME,
-        ResponseClassifier::classify(qu_in_a_www2, message_a,
-                                     cname_target, cname_count));
-
-    // Add a CNAME for www1, and it should still return a CNAME
-    message_a.addRRset(Message::SECTION_ANSWER, rrs_in_cname_www1);
-    EXPECT_EQ(ResponseClassifier::CNAME,
-        ResponseClassifier::classify(qu_in_a_www2, message_a,
-                                     cname_target, cname_count));
-
-    // Add the A record for www and it should be an answer
-    message_a.addRRset(Message::SECTION_ANSWER, rrs_in_a_www);
-    EXPECT_EQ(ResponseClassifier::ANSWERCNAME,
-        ResponseClassifier::classify(qu_in_a_www2, message_a,
-                                     cname_target, cname_count));
-
-    // Adding an unrelated TXT record should result in EXTRADATA
-    message_a.addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
-    EXPECT_EQ(ResponseClassifier::EXTRADATA,
-        ResponseClassifier::classify(qu_in_a_www2, message_a,
-                                     cname_target, cname_count));
-
-    // Recreate the chain, but this time end with a TXT RR and not the A
-    // record.  This should return INVTYPE.
-    Message message_b(Message::RENDER);
-    message_b.setHeaderFlag(Message::HEADERFLAG_QR);
-    message_b.setOpcode(Opcode::QUERY());
-    message_b.setRcode(Rcode::NOERROR());
-    message_b.addQuestion(qu_in_a_www2);
-    message_b.addRRset(Message::SECTION_ANSWER, rrs_in_cname_www2);
-    message_b.addRRset(Message::SECTION_ANSWER, rrs_in_cname_www1);
-    message_b.addRRset(Message::SECTION_ANSWER, rrs_in_txt_www);
-
-    EXPECT_EQ(ResponseClassifier::INVTYPE,
-        ResponseClassifier::classify(qu_in_a_www2, message_b,
-                                     cname_target, cname_count));
-}
-
-} // Anonymous namespace
diff --git a/src/lib/resolve/tests/run_unittests.cc b/src/lib/resolve/tests/run_unittests.cc
deleted file mode 100644 (file)
index fe8124e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (C) 2009  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 <gtest/gtest.h>
-#include <util/unittests/run_all.h>
-
-#include <dns/tests/unittest_util.h>
-#include <log/logger_support.h>
-
-int
-main(int argc, char* argv[]) {
-    ::testing::InitGoogleTest(&argc, argv);
-    isc::log::initLogger();
-
-    return (isc::util::unittests::run_all());
-}
index 00c2dcd7d58a30126fc36e8b6491bbecb35b3925..1881f78f0c74ec868561778e7b8d50aa09575c22 100644 (file)
@@ -22,7 +22,7 @@
 #include <cc/data.h>
 #include <cc/session.h>
 
-#include <xfr/xfrout_client.h>
+//#include <xfr/xfrout_client.h>
 
 #include <asiodns/asiodns.h>
 
@@ -173,8 +173,11 @@ private:
     bool done_;
 };
 
+// Commenting out this class as it is not used anyware. The removal of this class
+// allows for removal of the lib/xfr.
+
 // Mock Xfrout client
-class MockXfroutClient : public isc::xfr::AbstractXfroutClient {
+/*class MockXfroutClient : public isc::xfr::AbstractXfroutClient {
 public:
     MockXfroutClient() :
         is_connected_(false), connect_ok_(true), send_ok_(true),
@@ -215,7 +218,7 @@ private:
     bool connect_ok_;
     bool send_ok_;
     bool disconnect_ok_;
-};
+    }; */
 
 } // end of testutils
 } // end of isc
diff --git a/src/lib/xfr/Makefile.am b/src/lib/xfr/Makefile.am
deleted file mode 100644 (file)
index 5e90e9b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-SUBDIRS = . tests
-
-AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
-AM_CPPFLAGS += $(BOOST_INCLUDES)
-
-AM_CXXFLAGS = $(B10_CXXFLAGS)
-AM_CXXFLAGS += -Wno-unused-parameter
-# see src/lib/cc/Makefile.am
-
-CLEANFILES = *.gcno *.gcda
-
-lib_LTLIBRARIES = libb10-xfr.la
-libb10_xfr_la_SOURCES = xfrout_client.h xfrout_client.cc
-libb10_xfr_la_LIBADD = $(top_builddir)/src/lib/util/io/libb10-util-io.la
diff --git a/src/lib/xfr/tests/.gitignore b/src/lib/xfr/tests/.gitignore
deleted file mode 100644 (file)
index d6d1ec8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/run_unittests
diff --git a/src/lib/xfr/tests/Makefile.am b/src/lib/xfr/tests/Makefile.am
deleted file mode 100644 (file)
index 908abe8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
-AM_CPPFLAGS += $(BOOST_INCLUDES)
-AM_CXXFLAGS = $(B10_CXXFLAGS)
-
-if USE_STATIC_LINK
-AM_LDFLAGS = -static
-endif
-
-CLEANFILES = *.gcno *.gcda
-
-TESTS_ENVIRONMENT = \
-        $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
-
-TESTS =
-if HAVE_GTEST
-TESTS += run_unittests
-run_unittests_SOURCES = run_unittests.cc client_test.cc
-
-run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
-
-run_unittests_LDADD = $(GTEST_LDADD)
-run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
-run_unittests_LDADD += $(top_builddir)/src/lib/xfr/libb10-xfr.la
-run_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
-endif
-
-noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/xfr/tests/client_test.cc b/src/lib/xfr/tests/client_test.cc
deleted file mode 100644 (file)
index ce783b0..0000000
+++ /dev/null
@@ -1,37 +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 <gtest/gtest.h>
-
-#include <sys/un.h>
-#include <string>
-
-#include <xfr/xfrout_client.h>
-
-using namespace std;
-using namespace isc::xfr;
-
-namespace {
-
-TEST(ClientTest, connectFile) {
-    // File path is too long
-    struct sockaddr_un s;     // can't be const; some compiler complains
-    EXPECT_THROW(XfroutClient(string(sizeof(s.sun_path), 'x')).connect(),
-                 XfroutError);
-
-    // File doesn't exist (we assume the file "no_such_file" doesn't exist)
-    EXPECT_THROW(XfroutClient("no_such_file").connect(), XfroutError);
-}
-
-}
diff --git a/src/lib/xfr/tests/run_unittests.cc b/src/lib/xfr/tests/run_unittests.cc
deleted file mode 100644 (file)
index 8dc59a2..0000000
+++ /dev/null
@@ -1,24 +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 <gtest/gtest.h>
-#include <log/logger_support.h>
-#include <util/unittests/run_all.h>
-
-int
-main(int argc, char* argv[]) {
-    ::testing::InitGoogleTest(&argc, argv);
-    isc::log::initLogger();
-    return (isc::util::unittests::run_all());
-}
diff --git a/src/lib/xfr/xfrout_client.cc b/src/lib/xfr/xfrout_client.cc
deleted file mode 100644 (file)
index af0c1b5..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (C) 2010  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 <cstdlib>
-#include <cstring>
-#include <iostream>
-
-// for some IPC/network system calls in asio/detail/pipe_select_interrupter.hpp
-#include <unistd.h>
-#include <asio.hpp>
-
-#include <util/io/fd_share.h>
-#include <xfr/xfrout_client.h>
-
-using namespace std;
-using namespace isc::util::io;
-using asio::local::stream_protocol;
-
-namespace isc {
-namespace xfr {
-
-struct XfroutClientImpl {
-    XfroutClientImpl(const string& file);
-    const std::string file_path_;
-    asio::io_service io_service_;
-    // The socket used to communicate with the xfrout server.
-    stream_protocol::socket socket_;
-};
-
-XfroutClientImpl::XfroutClientImpl(const string& file) :
-    file_path_(file), socket_(io_service_)
-{}
-
-XfroutClient::XfroutClient(const string& file) :
-    impl_(new XfroutClientImpl(file))
-{}
-
-XfroutClient::~XfroutClient() {
-    delete impl_;
-}
-
-void
-XfroutClient::connect() {
-    try {
-        impl_->socket_.connect(stream_protocol::endpoint(impl_->file_path_));
-    } catch (const asio::system_error& err) {
-        isc_throw(XfroutError, "socket connect failed for " <<
-                  impl_->file_path_ << ": " << err.what());
-    }
-}
-
-void
-XfroutClient::disconnect() {
-    asio::error_code err;
-    impl_->socket_.close(err);
-    if (err) {
-        isc_throw(XfroutError, "close socket failed: " << err.message());
-    }
-}
-
-int
-XfroutClient::sendXfroutRequestInfo(const int tcp_sock,
-                                    const void* const msg_data,
-                                    const uint16_t msg_len)
-{
-    if (send_fd(impl_->socket_.native(), tcp_sock) < 0) {
-        isc_throw(XfroutError,
-                  "Failed to send the socket file descriptor "
-                  "to xfrout module");
-    }
-
-    // TODO: this shouldn't be blocking send, even though it's unlikely to
-    // block.
-    // Converting the 16-bit word to network byte order.
-
-    // Splitting msg_len below performs something called a 'narrowing
-    // conversion' (conversion of uint16_t to uint8_t). C++0x (and GCC
-    // 4.7) requires explicit casting when a narrowing conversion is
-    // performed. For reference, see 8.5.4/6 of n3225.
-    const uint8_t lenbuf[2] = { static_cast<uint8_t>(msg_len >> 8),
-                                static_cast<uint8_t>(msg_len & 0xff) };
-    if (send(impl_->socket_.native(), lenbuf, sizeof(lenbuf), 0) !=
-        sizeof(lenbuf)) {
-        isc_throw(XfroutError,
-                  "failed to send XFR request length to xfrout module");
-    }
-    if (send(impl_->socket_.native(), msg_data, msg_len, 0) != msg_len) {
-        isc_throw(XfroutError,
-                  "failed to send XFR request data to xfrout module");
-    }
-
-    return (0);
-}
-
-} // End for xfr
-} // End for isc
-
diff --git a/src/lib/xfr/xfrout_client.h b/src/lib/xfr/xfrout_client.h
deleted file mode 100644 (file)
index e691fb1..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (C) 2010  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 XFROUT_CLIENT_H
-#define XFROUT_CLIENT_H
-
-#include <stdint.h>
-
-#include <string>
-
-#include <exceptions/exceptions.h>
-
-namespace isc {
-namespace xfr {
-
-struct XfroutClientImpl;
-
-class XfroutError: public Exception {
-public:
-    XfroutError(const char *file, size_t line, const char *what):
-        isc::Exception(file, line, what) {}
-};
-
-/// \brief The AbstractXfroutClient class is an abstract base class that
-/// defines the interfaces of XfroutClient.
-///
-/// The intended primary usage of abstraction is to allow tests for the
-/// user class of XfroutClient without requiring actual communication.
-class AbstractXfroutClient {
-    ///
-    /// \name Constructors, Assignment Operator and Destructor.
-    ///
-    /// Note: The copy constructor and the assignment operator are
-    /// intentionally defined as private to make it explicit that this is a
-    /// pure base class.
-    //@{
-private:
-    AbstractXfroutClient(const AbstractXfroutClient& source);
-    AbstractXfroutClient& operator=(const AbstractXfroutClient& 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).
-    AbstractXfroutClient() {}
-public:
-    /// \brief The destructor.
-    virtual ~AbstractXfroutClient() {}
-    //@}
-    virtual void connect() = 0;
-    virtual void disconnect() = 0;
-    virtual int sendXfroutRequestInfo(int tcp_sock, const void* msg_data,
-                                      uint16_t msg_len) = 0;
-};
-
-class XfroutClient : public AbstractXfroutClient {
-public:
-    XfroutClient(const std::string& file);
-    ~XfroutClient();
-private:
-    // make this class non copyable
-    XfroutClient(const XfroutClient& source);
-    XfroutClient& operator=(const XfroutClient& source);
-public:
-    virtual void connect();
-    virtual void disconnect();
-    virtual int sendXfroutRequestInfo(int tcp_sock, const void* msg_data,
-                                      uint16_t msg_len);
-private:
-    XfroutClientImpl* impl_;
-};
-
-} // End for namespace xfr
-} // End for namespace isc
-
-#endif
-
-// Local Variables: 
-// mode: c++
-// End: