Browse Source

preserved the question section when returning an error to a query

git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1349 e5f2f494-b856-4b98-b285-d166d9295462
JINMEI Tatuya 15 years ago
parent
commit
14ea192940

+ 18 - 0
src/bin/auth/auth_srv.cc

@@ -21,8 +21,10 @@
 #include <netdb.h>
 #include <stdlib.h>
 
+#include <algorithm>
 #include <cassert>
 #include <iostream>
+#include <vector>
 
 #include <exceptions/exceptions.h>
 
@@ -94,6 +96,15 @@ AuthSrv::~AuthSrv() {
 }
 
 namespace {
+class QuestionInserter {
+public:
+    QuestionInserter(Message* message) : message_(message) {}
+    void operator()(const QuestionPtr question) {
+        message_->addQuestion(question);
+    }
+    Message* message_;
+};
+
 void
 makeErrorMessage(Message& message, MessageRenderer& renderer,
                  const Rcode& rcode)
@@ -105,6 +116,12 @@ makeErrorMessage(Message& message, MessageRenderer& renderer,
     const bool rd = message.getHeaderFlag(MessageFlag::RD());
     const bool cd = message.getHeaderFlag(MessageFlag::CD());
     const Opcode& opcode = message.getOpcode();
+    vector<QuestionPtr> questions;
+
+    // If this is an error to a query, we should also copy the question section.
+    if (opcode == Opcode::QUERY()) {
+        questions.assign(message.beginQuestion(), message.endQuestion());
+    }
 
     message.clear(Message::RENDER);
     message.setQid(qid);
@@ -116,6 +133,7 @@ makeErrorMessage(Message& message, MessageRenderer& renderer,
     if (cd) {
         message.setHeaderFlag(MessageFlag::CD());
     }
+    for_each(questions.begin(), questions.end(), QuestionInserter(&message));
     message.setRcode(rcode);
     message.toWire(renderer);
 }

+ 12 - 2
src/bin/auth/tests/auth_srv_unittest.cc

@@ -115,14 +115,24 @@ TEST_F(AuthSrvTest, unsupportedRequest) {
 }
 
 // Multiple questions.  Should result in FORMERR.
-
 TEST_F(AuthSrvTest, multiQuestion) {
     createDataFromFile("testdata/multiquestion_fromWire", data);
     InputBuffer buffer(&data[0], data.size());
     EXPECT_EQ(0, server.processMessage(buffer, parse_message,
                                            response_renderer, true, false));
     headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
-                QR_FLAG, 0, 0, 0, 0);
+                QR_FLAG, 2, 0, 0, 0);
+
+    QuestionIterator qit = parse_message.beginQuestion();
+    EXPECT_EQ(Name("example.com"), (*qit)->getName());
+    EXPECT_EQ(RRClass::IN(), (*qit)->getClass());
+    EXPECT_EQ(RRType::A(), (*qit)->getType());
+    ++qit;
+    EXPECT_EQ(Name("example.com"), (*qit)->getName());
+    EXPECT_EQ(RRClass::IN(), (*qit)->getClass());
+    EXPECT_EQ(RRType::AAAA(), (*qit)->getType());
+    ++qit;
+    EXPECT_TRUE(qit == parse_message.endQuestion());
 }
 
 }

+ 2 - 2
src/bin/auth/tests/testdata/multiquestion_fromWire

@@ -13,5 +13,5 @@
 076578616d706c6503636f6d00 0001 0001
 
 # Question Section
-# QNAME=q2.example.com QTYPE=A(1) QCLASS=IN(1)
-027132076578616d706c6503636f6d00 0001 0001
+# QNAME=example.com. QTYPE=AAAA(28) QCLASS=IN(1)
+076578616d706c6503636f6d00 001c 0001

+ 1 - 1
src/bin/auth/tests/testdata/multiquestion_fromWire.spec

@@ -9,4 +9,4 @@ qdcount: 2
 [question/0]
 # use default
 [question/1]
-name: q2.example.com
+rrtype: AAAA