summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/resolve/recursive_query.cc55
-rw-r--r--src/lib/resolve/tests/recursive_query_unittest_2.cc26
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