Browse Source

[trac497] use responseclassifier in handleRecursiveAnswer

Jelte Jansen 14 years ago
parent
commit
81d20bfeea
1 changed files with 77 additions and 0 deletions
  1. 77 0
      src/lib/asiolink/asiolink.cc

+ 77 - 0
src/lib/asiolink/asiolink.cc

@@ -432,6 +432,83 @@ private:
     // returns true if we are done
     // returns false if we are not done
     bool handleRecursiveAnswer(const Message& incoming) {
+        isc::resolve::ResponseClassifier::Category category =
+            isc::resolve::ResponseClassifier::classify(question_, incoming, true);
+
+        bool found_ns_address = false;
+        switch (category) {
+        case isc::resolve::ResponseClassifier::ANSWER:
+        case isc::resolve::ResponseClassifier::ANSWERCNAME:
+            copyAnswerMessage(incoming, answer_message_);
+            return true;
+            break;
+        case isc::resolve::ResponseClassifier::CNAME:
+            // TODO: add CNAME, restart
+            copyAnswerMessage(incoming, answer_message_);
+            return true;
+            break;
+        case isc::resolve::ResponseClassifier::NXDOMAIN:
+            copyAnswerMessage(incoming, answer_message_);
+            return true;
+            break;
+        case isc::resolve::ResponseClassifier::REFERRAL:
+            zone_servers_.clear();
+
+            for (RRsetIterator rrsi = incoming.beginSection(Message::SECTION_ADDITIONAL);
+                 rrsi != incoming.endSection(Message::SECTION_ADDITIONAL) && !found_ns_address;
+                 rrsi++) {
+                ConstRRsetPtr rrs = *rrsi;
+                if (rrs->getType() == RRType::A()) {
+                    // found address
+                    RdataIteratorPtr rdi = rrs->getRdataIterator();
+                    // just use the first for now
+                    if (!rdi->isLast()) {
+                        std::string addr_str = rdi->getCurrent().toText();
+                        dlog("[XX] first address found: " + addr_str);
+                        // now we have one address, simply
+                        // resend that exact same query
+                        // to that address and yield, when it
+                        // returns, loop again.
+                        
+                        // should use NSAS
+                        zone_servers_.push_back(addr_t(addr_str, 53));
+                        found_ns_address = true;
+                    }
+                }
+            }
+            if (found_ns_address) {
+                // next resolver round
+                send();
+                return false;
+            } else {
+                dlog("[XX] no ready-made addresses in additional. need nsas.");
+                // this will result in answering with the delegation. oh well
+                copyAnswerMessage(incoming, answer_message_);
+                return true;
+            }
+            break;
+        case isc::resolve::ResponseClassifier::EMPTY:
+        case isc::resolve::ResponseClassifier::EXTRADATA:
+        case isc::resolve::ResponseClassifier::INVNAMCLASS:
+        case isc::resolve::ResponseClassifier::INVTYPE:
+        case isc::resolve::ResponseClassifier::MISMATQUEST:
+        case isc::resolve::ResponseClassifier::MULTICLASS:
+        case isc::resolve::ResponseClassifier::NOTONEQUEST:
+        case isc::resolve::ResponseClassifier::NOTRESPONSE:
+        case isc::resolve::ResponseClassifier::NOTSINGLE:
+        case isc::resolve::ResponseClassifier::OPCODE:
+        case isc::resolve::ResponseClassifier::RCODE:
+        case isc::resolve::ResponseClassifier::TRUNCATED:
+            // TODO should create SERVFAIL?
+            return true;
+            break;
+        }
+        // should not be reached
+        dlog("[FATAL] unreachable code");
+        return true;
+    }
+    
+    bool oldhandleRecursiveAnswer(const Message& incoming) {
         if (incoming.getRRCount(Message::SECTION_ANSWER) > 0) {
             dlog("Got final result, copying answer.");
             copyAnswerMessage(incoming, answer_message_);