Browse Source

Merge branch 'trac697'

Jelte Jansen 14 years ago
parent
commit
1b02466cee

+ 39 - 16
src/lib/resolve/recursive_query.cc

@@ -27,6 +27,7 @@
 #include <dns/question.h>
 #include <dns/message.h>
 #include <dns/opcode.h>
+#include <dns/exceptions.h>
 
 #include <resolve/resolve.h>
 #include <cache/resolver_cache.h>
@@ -619,22 +620,44 @@ public:
             dlog("RTT: " + boost::lexical_cast<std::string>(rtt));
             current_ns_address.updateRTT(rtt);
             
-            Message incoming(Message::PARSE);
-            InputBuffer ibuf(buffer_->getData(), buffer_->getLength());
-            incoming.fromWire(ibuf);
-
-            buffer_->clear();
-            if (recursive_mode() &&
-                incoming.getRcode() == Rcode::NOERROR()) {
-                done_ = handleRecursiveAnswer(incoming);
-            } else {
-                isc::resolve::copyResponseMessage(incoming, answer_message_);
-                done_ = true;
-            }
-            
-            if (done_) {
-                callCallback(true);
-                stop();
+            try {
+                Message incoming(Message::PARSE);
+                InputBuffer ibuf(buffer_->getData(), buffer_->getLength());
+
+                incoming.fromWire(ibuf);
+
+                buffer_->clear();
+                if (recursive_mode() &&
+                    incoming.getRcode() == Rcode::NOERROR()) {
+                    done_ = handleRecursiveAnswer(incoming);
+                } else {
+                    isc::resolve::copyResponseMessage(incoming, answer_message_);
+                    done_ = true;
+                }
+                if (done_) {
+                    callCallback(true);
+                    stop();
+                }
+            } catch (const isc::dns::DNSProtocolError& dpe) {
+                dlog("DNS Protocol error in answer for " +
+                     question_.toText() + " " +
+                     question_.getType().toText() + ": " +
+                     dpe.what());
+                // 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_--) {
+                    dlog("Retrying");
+                    send();
+                } else {
+                    dlog("Giving up");
+                    if (!callback_called_) {
+                        makeSERVFAIL();
+                        callCallback(true);
+                    }
+                    stop();
+                }
             }
         } else if (!done_ && retries_--) {
             // Query timed out, but we have some retries, so send again

+ 23 - 3
src/lib/resolve/tests/recursive_query_unittest_2.cc

@@ -107,8 +107,10 @@ public:
         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 = 4,        ///< Query EXAMPLE.ORG server over UDP
-        COMPLETE = 5                ///< Query is complete
+        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
@@ -289,6 +291,10 @@ public:
         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:
@@ -309,6 +315,14 @@ public:
             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);
@@ -324,6 +338,12 @@ public:
         MessageRenderer renderer(*udp_send_buffer_);
         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();
@@ -454,7 +474,7 @@ public:
         // 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;
+        expected_ = UDP_EXAMPLE_ORG_BAD;
         tcp_cumulative_ = 0;
 
         // Unless we go through a callback loop we cannot simply use