Browse Source

added tests for various kinds of responses (which must be silently dropped)

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

+ 3 - 12
src/bin/auth/auth_srv.cc

@@ -14,13 +14,6 @@
 
 // $Id$
 
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <stdlib.h>
-
 #include <algorithm>
 #include <cassert>
 #include <iostream>
@@ -140,8 +133,7 @@ makeErrorMessage(Message& message, MessageRenderer& renderer,
 }
 
 bool
-AuthSrv::processMessage(InputBuffer& request_buffer,
-                        Message& message,
+AuthSrv::processMessage(InputBuffer& request_buffer, Message& message,
                         MessageRenderer& response_renderer,
                         const bool udp_buffer, const bool verbose_mode)
 {
@@ -161,6 +153,7 @@ AuthSrv::processMessage(InputBuffer& request_buffer,
         return (false);
     }
 
+    // Parse the message.  On failure, return an appropriate error.
     try {
         message.fromWire(request_buffer);
     } catch (const DNSProtocolError& error) {
@@ -177,9 +170,7 @@ AuthSrv::processMessage(InputBuffer& request_buffer,
         cerr << "[AuthSrv] received a message:\n" << message.toText() << endl;
     }
 
-    //
-    // Incoming Message Validation
-    //
+    // Perform further protocol-level validation.
 
     // In this implementation, we only support normal queries
     if (message.getOpcode() != Opcode::QUERY()) {

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

@@ -37,7 +37,7 @@ protected:
     AuthSrvTest() : request_message(Message::RENDER),
                     parse_message(Message::PARSE), default_qid(0x1035),
                     opcode(Opcode(Opcode::QUERY())), qname("www.example.com"),
-                    qclass(RRClass::IN()), qtype(RRType::A()),
+                    qclass(RRClass::IN()), qtype(RRType::A()), ibuffer(NULL),
                     request_obuffer(0), request_renderer(request_obuffer),
                     response_obuffer(0), response_renderer(response_obuffer)
     {}
@@ -49,11 +49,14 @@ protected:
     Name qname;
     RRClass qclass;
     RRType qtype;
+    InputBuffer* ibuffer;
     OutputBuffer request_obuffer;
     MessageRenderer request_renderer;
     OutputBuffer response_obuffer;
     MessageRenderer response_renderer;
     vector<uint8_t> data;
+
+    void createDataFromFile(const char* const datafile);
 };
 
 // These are flags to indicate whether the corresponding flag bit of the
@@ -68,9 +71,12 @@ const unsigned int AD_FLAG = 0x20;
 const unsigned int CD_FLAG = 0x40;
 
 void
-createDataFromFile(const char* const datafile, vector<uint8_t>& data) {
+AuthSrvTest::createDataFromFile(const char* const datafile) {
+    delete ibuffer;
+    data.clear();
+
     UnitTestUtil::readWireData(datafile, data);
-    InputBuffer buffer(&data[0], data.size());
+    ibuffer = new InputBuffer(&data[0], data.size());
 }
 
 void
@@ -99,15 +105,14 @@ headerCheck(const Message& message, const qid_t qid, const Rcode& rcode,
 
 // Unsupported requests.  Should result in NOTIMP.
 TEST_F(AuthSrvTest, unsupportedRequest) {
-    createDataFromFile("testdata/simplequery_fromWire", data);
     for (unsigned int i = 1; i < 16; ++i) {
         // set Opcode to 'i', which iterators over all possible codes except
         // the standard query (0)
+        createDataFromFile("testdata/simplequery_fromWire");
         data[2] = ((i << 3) & 0xff);
 
-        InputBuffer buffer(&data[0], data.size());
         parse_message.clear(Message::PARSE);
-        EXPECT_EQ(true, server.processMessage(buffer, parse_message,
+        EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
                                               response_renderer, true, false));
         headerCheck(parse_message, default_qid, Rcode::NOTIMP(), i, QR_FLAG,
                     0, 0, 0, 0);
@@ -116,9 +121,8 @@ 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(true, server.processMessage(buffer, parse_message,
+    createDataFromFile("testdata/multiquestion_fromWire");
+    EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
                                           response_renderer, true, false));
     headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
                 QR_FLAG, 2, 0, 0, 0);
@@ -138,10 +142,30 @@ TEST_F(AuthSrvTest, multiQuestion) {
 // Incoming data doesn't even contain the complete header.  Must be silently
 // dropped.
 TEST_F(AuthSrvTest, shortMessage) {
-    createDataFromFile("testdata/shortmessage_fromWire", data);
-    InputBuffer buffer(&data[0], data.size());
-    EXPECT_EQ(false, server.processMessage(buffer, parse_message,
+    createDataFromFile("testdata/shortmessage_fromWire");
+    EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
+                                           response_renderer, true, false));
+}
+
+// Response messages.  Must be silently dropped, whether it's a valid response
+// or malformed or could otherwise cause a protocol error.
+TEST_F(AuthSrvTest, response) {
+    // A valid (although unusual) response
+    createDataFromFile("testdata/simpleresponse_fromWire");
+    EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
                                            response_renderer, true, false));
+
+    // A response with a broken question section.  must be dropped rather than
+    // returning FORMERR.
+    createDataFromFile("testdata/shortresponse_fromWire");
+    EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
+                                           response_renderer, true, false));    
+
+    // A response to iquery.  must be dropped rather than returning NOTIMP.
+    createDataFromFile("testdata/iqueryresponse_fromWire");
+    EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
+                                           response_renderer, true, false));    
+
 }
 
 }

+ 13 - 0
src/bin/auth/tests/testdata/iqueryresponse_fromWire

@@ -0,0 +1,13 @@
+###
+### This data file was auto-generated from iqueryresponse_fromWire.spec
+###
+
+# Header Section
+# ID=4149 QR=Response Opcode=IQUERY(1) Rcode=NOERROR(0)
+1035 c000
+# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=0
+0001 0000 0000 0000
+
+# Question Section
+# QNAME=example.com. QTYPE=A(1) QCLASS=IN(1)
+076578616d706c6503636f6d00 0001 0001

+ 9 - 0
src/bin/auth/tests/testdata/iqueryresponse_fromWire.spec

@@ -0,0 +1,9 @@
+#
+# A response to an IQUERY request.
+#
+
+[header]
+qr: response
+opcode: iquery
+[question]
+# use default

+ 13 - 0
src/bin/auth/tests/testdata/shortresponse_fromWire

@@ -0,0 +1,13 @@
+###
+### A response-like data, but missing QCLASS field in the Question section.
+###
+
+# Header Section
+# ID=4149 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0)
+1035 8000
+# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=0
+0001 0000 0000 0000
+
+# Question Section
+# QNAME=example.com. QTYPE=A(1) (QCLASS is missing)
+076578616d706c6503636f6d00 0001

+ 13 - 0
src/bin/auth/tests/testdata/simpleresponse_fromWire

@@ -0,0 +1,13 @@
+###
+### This data file was auto-generated from simpleresponse_fromWire.spec
+###
+
+# Header Section
+# ID=4149 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0)
+1035 8000
+# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=0
+0001 0000 0000 0000
+
+# Question Section
+# QNAME=example.com. QTYPE=A(1) QCLASS=IN(1)
+076578616d706c6503636f6d00 0001 0001

+ 8 - 0
src/bin/auth/tests/testdata/simpleresponse_fromWire.spec

@@ -0,0 +1,8 @@
+#
+# A simple response message.
+#
+
+[header]
+qr: response
+[question]
+# use default