diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/resolve/recursive_query.cc | 55 | ||||
-rw-r--r-- | src/lib/resolve/tests/recursive_query_unittest_2.cc | 26 |
2 files changed, 62 insertions, 19 deletions
diff --git a/src/lib/resolve/recursive_query.cc b/src/lib/resolve/recursive_query.cc index b68d80f1e9..65545a4420 100644 --- a/src/lib/resolve/recursive_query.cc +++ b/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 diff --git a/src/lib/resolve/tests/recursive_query_unittest_2.cc b/src/lib/resolve/tests/recursive_query_unittest_2.cc index 21798b177a..643c5a3aa2 100644 --- a/src/lib/resolve/tests/recursive_query_unittest_2.cc +++ b/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 |