Browse Source

[2796] add statistics item 'qryrecursion'

Yoshitaka Aharen 12 years ago
parent
commit
192787144f

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

@@ -521,6 +521,8 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
         return;
     }
 
+    stats_attrs.setRequestRD(message.getHeaderFlag(Message::HEADERFLAG_RD));
+
     const Opcode& opcode = message.getOpcode();
     // Get opcode at this point; for all requests regardless of message body
     // sanity check.

+ 10 - 1
src/bin/auth/statistics.cc.pre

@@ -138,7 +138,16 @@ Counters::incRequest(const MessageAttributes& msgattrs) {
     // if a short message which does not contain DNS header is received, or
     // a response message (i.e. QR bit is set) is received.
     if (opcode) {
-        server_msg_counter_.inc(opcode_to_msgcounter[opcode.get().getCode()]);
+        const int code = opcode.get().getCode();
+        server_msg_counter_.inc(opcode_to_msgcounter[code]);
+
+        // Opcode = 0: Query
+        if (code == 0) {
+            // Recursion Desired bit
+            if (msgattrs.requestHasRD()) {
+                server_msg_counter_.inc(MSG_QRYRECURSION);
+            }
+        }
     }
 
     // TSIG

+ 19 - 0
src/bin/auth/statistics.h

@@ -66,6 +66,8 @@ private:
     enum BitAttributes {
         REQ_WITH_EDNS_0,            // request with EDNS ver.0
         REQ_WITH_DNSSEC_OK,         // DNSSEC OK (DO) bit is set in request
+        REQ_WITH_RD,                // Recursion Desired (RD) bit is set in
+                                    // request
         REQ_TSIG_SIGNED,            // request is signed with valid TSIG
         REQ_BADSIG,                 // request is signed but bad signature
         RES_IS_TRUNCATED,           // response is truncated
@@ -170,6 +172,23 @@ public:
         bit_attributes_[REQ_WITH_DNSSEC_OK] = with_dnssec_ok;
     }
 
+    /// \brief Return Recursion Desired (RD) bit of the request.
+    ///
+    /// \return true if Recursion Desired (RD) bit of the request is set
+    /// \throw None
+    bool requestHasRD() const {
+        return (bit_attributes_[REQ_WITH_RD]);
+    }
+
+    /// \brief Set Recursion Desired (RD) bit of the request.
+    ///
+    /// \param with_dnssec_ok true if Recursion Desired (RD)bit of the request
+    //                        is set
+    /// \throw None
+    void setRequestRD(const bool with_rd) {
+        bit_attributes_[REQ_WITH_RD] = with_rd;
+    }
+
     /// \brief Return whether the request is TSIG signed or not.
     ///
     /// \return true if the request is TSIG signed

+ 1 - 0
src/bin/auth/statistics_msg_items.def

@@ -31,6 +31,7 @@ qrynoauthans	MSG_QRYNOAUTHANS		Number of queries received by the b10-auth server
 qryreferral	MSG_QRYREFERRAL			Number of queries received by the b10-auth server resulted in referral answer.
 qrynxrrset	MSG_QRYNXRRSET			Number of queries received by the b10-auth server resulted in NoError and AA bit is set in the response, but the number of answer RR == 0.
 authqryrej	MSG_QRYREJECT			Number of authoritative queries rejected by the b10-auth server.
+qryrecursion	MSG_QRYRECURSION		Number of queries received by the b10-auth server with "Recursion Desired" (RD) bit was set.
 rcode		msg_counter_rcode	Rcode statistics	=
 	noerror		MSG_RCODE_NOERROR	Number of requests received by the b10-auth server resulted in RCODE = 0 (NoError).
 	formerr		MSG_RCODE_FORMERR	Number of requests received by the b10-auth server resulted in RCODE = 1 (FormErr).

+ 58 - 0
src/bin/auth/tests/statistics_unittest.cc.pre

@@ -361,6 +361,64 @@ TEST_F(CountersTest, incrementTSIG) {
     }
 }
 
+TEST_F(CountersTest, incrementRD) {
+    Message response(Message::RENDER);
+    MessageAttributes msgattrs;
+    std::map<std::string, int> expect;
+
+    // Test these patterns:
+    //     OpCode         Recursion Desired
+    //    ---------------------------
+    //     0 (Query)      false
+    //     0 (Query)      true
+    //     2 (Status)     false
+    //     2 (Status)     true
+    //  Make sure the counter will be incremented only for the requests with
+    //  OpCode=Query and Recursion Desired (RD) bit=1.
+    int count_opcode_query = 0;
+    int count_opcode_status = 0;
+    for (int i = 0; i < 4; ++i) {
+        const bool is_recursion_desired = i & 1;
+        const uint8_t opcode_code = i & 0x2;
+        const Opcode opcode(opcode_code);
+        buildSkeletonMessage(msgattrs);
+        msgattrs.setRequestRD(is_recursion_desired);
+        msgattrs.setRequestOpCode(opcode);
+
+        response.setRcode(Rcode::REFUSED());
+        response.addQuestion(Question(Name("example.com"),
+                                      RRClass::IN(), RRType::AAAA()));
+        response.setHeaderFlag(Message::HEADERFLAG_QR);
+
+        counters.inc(msgattrs, response, true);
+
+        if (opcode == Opcode::QUERY()) {
+            ++count_opcode_query;
+        } else {
+            ++count_opcode_status;
+        }
+
+        expect.clear();
+        expect["opcode.query"] = count_opcode_query;
+        expect["opcode.status"] = count_opcode_status;
+        expect["request.v4"] = i+1;
+        expect["request.udp"] = i+1;
+        expect["request.edns0"] = i+1;
+        expect["request.dnssec_ok"] = i+1;
+        expect["responses"] = i+1;
+        // qryrecursion will (only) be incremented if i == 1: OpCode=Query and
+        // RD bit=1
+        expect["qryrecursion"] = (i == 0) ? 0 : 1;
+        expect["rcode.refused"] = i+1;
+        // these counters are for queries; the value will be equal to the
+        // number of requests with OpCode=Query
+        expect["qrynoauthans"] = count_opcode_query;
+        expect["authqryrej"] = count_opcode_query;
+        checkStatisticsCounters(counters.get()->get("zones")->get("_SERVER_"),
+                                expect);
+    }
+}
+
 TEST_F(CountersTest, incrementOpcode) {
     Message response(Message::RENDER);
     MessageAttributes msgattrs;