BIND 10 trac495, updated. 120a7ea6efb5ba35008ed9b3502846f4b8fb2ed8 [trac495] added NXRRSET to classifier result list, and debug msgs

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Feb 28 14:51:41 UTC 2011


The branch, trac495 has been updated
       via  120a7ea6efb5ba35008ed9b3502846f4b8fb2ed8 (commit)
      from  28c720f2b0319ee8b2ee21cea1105e411a31360c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 120a7ea6efb5ba35008ed9b3502846f4b8fb2ed8
Author: Jelte Jansen <jelte at isc.org>
Date:   Mon Feb 28 15:50:43 2011 +0100

    [trac495] added NXRRSET to classifier result list, and debug msgs
    
    currently, the NSAS appears to work, but it does fail on glue-only referrals

-----------------------------------------------------------------------

Summary of changes:
 src/lib/asiolink/recursive_query.cc                |   58 +++++++++++++++-----
 src/lib/resolve/response_classifier.cc             |   10 +++-
 src/lib/resolve/response_classifier.h              |    1 +
 .../resolve/tests/response_classifier_unittest.cc  |   17 ++++++
 4 files changed, 68 insertions(+), 18 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/asiolink/recursive_query.cc b/src/lib/asiolink/recursive_query.cc
index 2975981..d74440d 100644
--- a/src/lib/asiolink/recursive_query.cc
+++ b/src/lib/asiolink/recursive_query.cc
@@ -84,6 +84,7 @@ public:
     ResolverNSASCallback(RunningQuery* rq) : rq_(rq) {}
     
     void success(const isc::nsas::NameserverAddress& address) {
+        dlog("Found a nameserver, sending query to " + address.getAddress().toText());
         rq_->sendTo(address);
     }
     
@@ -183,7 +184,9 @@ private:
         if (cache_.lookup(question_.getName(), question_.getType(),
                           question_.getClass(), cached_message)) {
             dlog("Message found in cache, returning that");
-            handleRecursiveAnswer(cached_message);
+            if (handleRecursiveAnswer(cached_message)) {
+                stop(true);
+            }
         } else {
             cur_zone_ = ".";
             send();
@@ -196,11 +199,11 @@ private:
         // the RTT
         current_ns_address = address;
         gettimeofday(&current_ns_qsent_time, NULL);
+        ++queries_out_;
         IOFetch query(IPPROTO_UDP, io_, question_,
             current_ns_address.getAddress(),
             53, buffer_, this,
             query_timeout_);
-        ++queries_out_;
         io_.get_io_service().post(query);
     }
     
@@ -212,15 +215,16 @@ private:
             int serverIndex = rand() % uc;
             dlog("Sending upstream query (" + question_.toText() +
                 ") to " + upstream_->at(serverIndex).first);
+            ++queries_out_;
             IOFetch query(IPPROTO_UDP, io_, question_,
                 upstream_->at(serverIndex).first,
                 upstream_->at(serverIndex).second, buffer_, this,
                 query_timeout_);
-            ++queries_out_;
             io_.get_io_service().post(query);
         } else {
             // Ask the NSAS for an address for the current zone,
             // the callback will call the actual sendTo()
+            dlog("Look up nameserver for " + cur_zone_ + " in NSAS");
             nsas_.lookup(cur_zone_, question_.getClass(), nsas_callback_);
         }
     }
@@ -234,21 +238,21 @@ private:
             int serverIndex = rand() % uc;
             dlog("Sending upstream query (" + question_.toText() +
                 ") to " + upstream_->at(serverIndex).first);
+            ++queries_out_;
             IOFetch query(IPPROTO_UDP, io_, question_,
                 upstream_->at(serverIndex).first,
                 upstream_->at(serverIndex).second, buffer_, this,
                 query_timeout_);
-            ++queries_out_;
             io_.get_io_service().post(query);
         } else if (zs > 0) {
             int serverIndex = rand() % zs;
             dlog("Sending query to zone server (" + question_.toText() +
                 ") to " + zone_servers_.at(serverIndex).first);
+            ++queries_out_;
             IOFetch query(IPPROTO_UDP, io_, question_,
                 zone_servers_.at(serverIndex).first,
                 zone_servers_.at(serverIndex).second, buffer_, this,
                 query_timeout_);
-            ++queries_out_;
             io_.get_io_service().post(query);
         } else {
             dlog("Error, no upstream servers to send to.");
@@ -279,19 +283,22 @@ private:
         bool found_ns_address = false;
             
         // If the packet is OK, store it in the cache
-        if (!isc::resolve::ResponseClassifier::error(category)) {
-            cache_.update(incoming);
-        }
+        //if (!isc::resolve::ResponseClassifier::error(category)) {
+        //    cache_.update(incoming);
+        //}
 
         switch (category) {
         case isc::resolve::ResponseClassifier::ANSWER:
         case isc::resolve::ResponseClassifier::ANSWERCNAME:
             // Done. copy and return.
+            dlog("Response is an answer");
+            cache_.update(incoming);
             isc::resolve::copyResponseMessage(incoming, answer_message_);
             return true;
             break;
         case isc::resolve::ResponseClassifier::CNAME:
             dlog("Response is CNAME!");
+            cache_.update(incoming);
             // (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).
@@ -315,11 +322,18 @@ private:
             return false;
             break;
         case isc::resolve::ResponseClassifier::NXDOMAIN:
+        case isc::resolve::ResponseClassifier::NXRRSET:
+            dlog("Response is NXDOMAIN or NXRRSET");
             // NXDOMAIN, just copy and return.
+            // no negcache yet
+            //cache_.update(incoming);
+            dlog(incoming.toText());
             isc::resolve::copyResponseMessage(incoming, answer_message_);
             return true;
             break;
         case isc::resolve::ResponseClassifier::REFERRAL:
+            dlog("Response is referral");
+            cache_.update(incoming);
             // Referral. For now we just take the first glue address
             // we find and continue with that
             zone_servers_.clear();
@@ -329,10 +343,11 @@ private:
             // TODO: should we check if it really is subzone?
             for (RRsetIterator rrsi = incoming.beginSection(Message::SECTION_AUTHORITY);
                  rrsi != incoming.endSection(Message::SECTION_AUTHORITY) && !found_ns_address;
-                 rrsi++) {
+                 ++rrsi) {
                 ConstRRsetPtr rrs = *rrsi;
                 if (rrs->getType() == RRType::NS()) {
                     cur_zone_ = rrs->getName().toText();
+                    dlog("Referred to zone " + cur_zone_);
                     found_ns_address = true;
                     break;
                 }
@@ -347,6 +362,7 @@ private:
                 send();
                 return false;
             } else {
+                dlog("No NS RRset in referral?");
                 // TODO this will result in answering with the delegation. oh well
                 isc::resolve::copyResponseMessage(incoming, answer_message_);
                 return true;
@@ -364,6 +380,7 @@ private:
         case isc::resolve::ResponseClassifier::OPCODE:
         case isc::resolve::ResponseClassifier::RCODE:
         case isc::resolve::ResponseClassifier::TRUNCATED:
+            dlog("Error in response, returning SERVFAIL");
             // Should we try a different server rather than SERVFAIL?
             isc::resolve::makeErrorMessage(answer_message_,
                                            Rcode::SERVFAIL());
@@ -501,6 +518,7 @@ public:
         if (queries_out_ > 0) {
             return;
         }
+        dlog("Recursive query stopped, deleting");
         delete this;
     }
 
@@ -545,12 +563,17 @@ public:
             }
         } else if (!done_ && retries_--) {
             // We timed out, but we have some retries, so send again
-            dlog("Timeout, resending query");
-            //current_ns_address.updateRTT(isc::nsas::AddressEntry::UNREACHABLE);
+            dlog("Timeout for " + question_.toText() + " to " + current_ns_address.getAddress().toText() + ", resending query");
+            if (upstream_->empty()) {
+                current_ns_address.updateRTT(isc::nsas::AddressEntry::UNREACHABLE);
+            }
             send();
         } else {
             // out of retries, give up for now
-            //current_ns_address.updateRTT(isc::nsas::AddressEntry::UNREACHABLE);
+            dlog("Timeout for " + question_.toText() + " to " + current_ns_address.getAddress().toText() + ", giving up");
+            if (upstream_->empty()) {
+                current_ns_address.updateRTT(isc::nsas::AddressEntry::UNREACHABLE);
+            }
             stop(false);
         }
     }
@@ -569,14 +592,16 @@ RecursiveQuery::resolve(const QuestionPtr& question,
 
     OutputBufferPtr buffer(new OutputBuffer(0));
 
+    dlog("Asked to resolve: " + question->toText());
+    
     dlog("Try out cache first (direct call to resolve)");
     // First try to see if we have something cached in the messagecache
     if (cache_.lookup(question->getName(), question->getType(),
-                      question->getClass(), *answer_message)) {
+                      question->getClass(), *answer_message) &&
+        answer_message->getRRCount(Message::SECTION_ANSWER) > 0) {
         dlog("Message found in cache, returning that");
         // TODO: err, should cache set rcode as well?
         answer_message->setRcode(Rcode::NOERROR());
-        std::cout << answer_message->toText();
         callback->success(answer_message);
     } else {
         // Perhaps we only have the one RRset?
@@ -620,10 +645,13 @@ RecursiveQuery::resolve(const Question& question,
     answer_message->setOpcode(isc::dns::Opcode::QUERY());
     answer_message->addQuestion(question);
     
+    dlog("Asked to resolve: " + question.toText());
+    
     // First try to see if we have something cached in the messagecache
     dlog("Try out cache first (started by incoming event)");
     if (cache_.lookup(question.getName(), question.getType(),
-                      question.getClass(), *answer_message)) {
+                      question.getClass(), *answer_message) &&
+        answer_message->getRRCount(Message::SECTION_ANSWER) > 0) {
         dlog("Message found in cache, returning that");
         // TODO: err, should cache set rcode as well?
         answer_message->setRcode(Rcode::NOERROR());
diff --git a/src/lib/resolve/response_classifier.cc b/src/lib/resolve/response_classifier.cc
index 45e9cbc..02808e4 100644
--- a/src/lib/resolve/response_classifier.cc
+++ b/src/lib/resolve/response_classifier.cc
@@ -114,13 +114,17 @@ ResponseClassifier::Category ResponseClassifier::classify(
             );
 
     // If there is nothing in the answer section, it is a referral - unless
-    // there is nothing in the authority section
+    // there is no NS in the authority section
     if (answer.empty()) {
         if (authority.empty()) {
             return (EMPTY);
-        } else {
-            return (REFERRAL);
         }
+        for (int 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
diff --git a/src/lib/resolve/response_classifier.h b/src/lib/resolve/response_classifier.h
index bee0628..3821560 100644
--- a/src/lib/resolve/response_classifier.h
+++ b/src/lib/resolve/response_classifier.h
@@ -53,6 +53,7 @@ public:
         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()
diff --git a/src/lib/resolve/tests/response_classifier_unittest.cc b/src/lib/resolve/tests/response_classifier_unittest.cc
index b37ded7..23c8666 100644
--- a/src/lib/resolve/tests/response_classifier_unittest.cc
+++ b/src/lib/resolve/tests/response_classifier_unittest.cc
@@ -80,6 +80,8 @@ public:
             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("."),
@@ -115,6 +117,9 @@ public:
         // 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")));
@@ -146,6 +151,7 @@ public:
     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
@@ -349,6 +355,17 @@ TEST_F(ResponseClassifierTest, EmptyAnswerReferral) {
 
 }
 
+// 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




More information about the bind10-changes mailing list