Browse Source

added a test for a short message
also changed the return type of AuthSrv::processMessage() from int to bool
(we actually used it as a boolean flag, so it didn't make sense to call it
an integer)


git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1351 e5f2f494-b856-4b98-b285-d166d9295462

JINMEI Tatuya 15 years ago
parent
commit
1670cdbbe8

+ 22 - 14
src/bin/auth/auth_srv.cc

@@ -139,22 +139,38 @@ makeErrorMessage(Message& message, MessageRenderer& renderer,
 }
 }
 
-int
+bool
 AuthSrv::processMessage(InputBuffer& request_buffer,
                         Message& message,
                         MessageRenderer& response_renderer,
                         const bool udp_buffer, const bool verbose_mode)
 {
+    // First, check the header part.  If we fail even for the base header,
+    // just drop the message.
+    try {
+        message.parseHeader(request_buffer);
+
+        // Ignore all responses.
+        if (message.getHeaderFlag(MessageFlag::QR())) {
+            if (verbose_mode) {
+                cerr << "received unexpected response, ignoring" << endl;
+            }
+            return (false);
+        }
+    } catch (const Exception& ex) {
+        return (false);
+    }
+
     try {
         message.fromWire(request_buffer);
     } catch (const DNSProtocolError& error) {
         cerr << "returning protocol error" << endl;
         makeErrorMessage(message, response_renderer, error.getRcode());
-        return (0);
+        return (true);
     } catch (const Exception& ex) {
         cerr << "returning servfail" << endl;
         makeErrorMessage(message, response_renderer, Rcode::SERVFAIL());
-        return (0);
+        return (true);
     } // other exceptions will be handled at a higher layer.
 
     if (verbose_mode) {
@@ -165,26 +181,18 @@ AuthSrv::processMessage(InputBuffer& request_buffer,
     // Incoming Message Validation
     //
 
-    // Ignore all requests.
-    if (message.getHeaderFlag(MessageFlag::QR())) {
-        if (verbose_mode) {
-            cerr << "received unexpected response, ignoring" << endl;
-        }
-        return (-1);
-    }
-
     // In this implementation, we only support normal queries
     if (message.getOpcode() != Opcode::QUERY()) {
         if (verbose_mode) {
             cerr << "unsupported opcode" << endl;
         }
         makeErrorMessage(message, response_renderer, Rcode::NOTIMP());
-        return (0);
+        return (true);
     }
 
     if (message.getRRCount(Section::QUESTION()) != 1) {
         makeErrorMessage(message, response_renderer, Rcode::FORMERR());
-        return (0);
+        return (true);
     }
 
     const bool dnssec_ok = message.isDNSSECSupported();
@@ -211,7 +219,7 @@ AuthSrv::processMessage(InputBuffer& request_buffer,
              << " bytes):\n" << message.toText() << endl;
     }
 
-    return (0);
+    return (true);
 }
 
 ElementPtr

+ 6 - 4
src/bin/auth/auth_srv.h

@@ -45,10 +45,12 @@ public:
     explicit AuthSrv();
     ~AuthSrv();
     //@}
-    int processMessage(isc::dns::InputBuffer& request_buffer,
-                       isc::dns::Message& message,
-                       isc::dns::MessageRenderer& response_renderer,
-                       bool udp_buffer, bool verbose_mode);
+    /// \return \c true if the \message contains a response to be returned;
+    /// otherwise \c false.
+    bool processMessage(isc::dns::InputBuffer& request_buffer,
+                        isc::dns::Message& message,
+                        isc::dns::MessageRenderer& response_renderer,
+                        bool udp_buffer, bool verbose_mode);
     void serve(std::string zone_name);
     isc::data::ElementPtr updateConfig(isc::data::ElementPtr config);
 private:

+ 4 - 4
src/bin/auth/main.cc

@@ -155,7 +155,7 @@ public:
             InputBuffer dnsbuffer(data_, bytes_transferred);
             if (auth_server->processMessage(dnsbuffer, dns_message_,
                                             response_renderer_, false,
-                                            verbose_mode) == 0) {
+                                            verbose_mode)) {
                 responselen_buffer_.writeUint16(response_buffer_.getLength());
                 async_write(socket_,
                             boost::asio::buffer(
@@ -268,7 +268,7 @@ public:
             response_renderer_.clear();
             if (auth_server->processMessage(request_buffer, dns_message_,
                                             response_renderer_, true,
-                                            verbose_mode) == 0) {
+                                            verbose_mode)) {
                 socket_.async_send_to(
                     boost::asio::buffer(response_buffer_.getData(),
                                         response_buffer_.getLength()),
@@ -462,7 +462,7 @@ processMessageUDP(const int fd, Message& dns_message,
     if ((cc = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, sa, &sa_len)) > 0) {
         InputBuffer buffer(recvbuf, cc);
         if (auth_server->processMessage(buffer, dns_message, response_renderer,
-                                        true, verbose_mode) == 0) {
+                                        true, verbose_mode)) {
             sendto(fd, response_renderer.getData(),
                    response_renderer.getLength(), 0, sa, sa_len);
         }
@@ -508,7 +508,7 @@ processMessageTCP(const int fd, Message& dns_message,
     dns_message.clear(Message::PARSE);
     response_renderer.clear();
     if (auth_server->processMessage(buffer, dns_message, response_renderer,
-                                    false, verbose_mode) == 0) {
+                                    false, verbose_mode)) {
         size = response_renderer.getLength();
         size_n = htons(size);
         if (send(ts, &size_n, 2, 0) == 2) {

+ 13 - 4
src/bin/auth/tests/auth_srv_unittest.cc

@@ -107,8 +107,8 @@ TEST_F(AuthSrvTest, unsupportedRequest) {
 
         InputBuffer buffer(&data[0], data.size());
         parse_message.clear(Message::PARSE);
-        EXPECT_EQ(0, server.processMessage(buffer, parse_message,
-                                           response_renderer, true, false));
+        EXPECT_EQ(true, server.processMessage(buffer, parse_message,
+                                              response_renderer, true, false));
         headerCheck(parse_message, default_qid, Rcode::NOTIMP(), i, QR_FLAG,
                     0, 0, 0, 0);
     }
@@ -118,8 +118,8 @@ TEST_F(AuthSrvTest, unsupportedRequest) {
 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));
+    EXPECT_EQ(true, server.processMessage(buffer, parse_message,
+                                          response_renderer, true, false));
     headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
                 QR_FLAG, 2, 0, 0, 0);
 
@@ -135,4 +135,13 @@ TEST_F(AuthSrvTest, multiQuestion) {
     EXPECT_TRUE(qit == parse_message.endQuestion());
 }
 
+// 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,
+                                           response_renderer, true, false));
+}
+
 }

+ 9 - 0
src/bin/auth/tests/testdata/shortmessage_fromWire

@@ -0,0 +1,9 @@
+###
+### DNS message-like data but doesn't contain sufficient length of data.
+###
+
+# Header Section
+# ID=4149 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0)
+1035 0000
+# QDCNT=1, ANCNT=0, NSCNT=0, (ARCNT is missing)
+0001 0000 0000