"item_default": 0,
"item_title": "Received requests opcode 15",
"item_description": "The number of total request counts whose opcode is15 (reserved)"
+ },
+ {
+ "item_name": "rcode.noerror",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent success response",
+ "item_description": "The number of total responses with rcode 0 (NOERROR)"
+ },
+ {
+ "item_name": "rcode.formerr",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'format error' response",
+ "item_description": "The number of total responses with rcode 1 (FORMERR)"
+ },
+ {
+ "item_name": "rcode.servfail",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'server failure' response",
+ "item_description": "The number of total responses with rcode 2 (SERVFAIL)"
+ },
+ {
+ "item_name": "rcode.nxdomain",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'name error' response",
+ "item_description": "The number of total responses with rcode 3 (NXDOMAIN)"
+ },
+ {
+ "item_name": "rcode.notimp",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'not implemented' response",
+ "item_description": "The number of total responses with rcode 4 (NOTIMP)"
+ },
+ {
+ "item_name": "rcode.refused",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'refused' response",
+ "item_description": "The number of total responses with rcode 5 (REFUSED)"
+ },
+ {
+ "item_name": "rcode.yxdomain",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'name unexpectedly exists' response",
+ "item_description": "The number of total responses with rcode 6 (YXDOMAIN)"
+ },
+ {
+ "item_name": "rcode.yxrrset",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'rrset unexpectedly exists' response",
+ "item_description": "The number of total responses with rcode 7 (YXRRSET)"
+ },
+ {
+ "item_name": "rcode.nxrrset",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'no such rrset' response",
+ "item_description": "The number of total responses with rcode 8 ()"
+ },
+ {
+ "item_name": "rcode.notauth",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'not authoritative' response",
+ "item_description": "The number of total responses with rcode 9 (NOTAUTH)"
+ },
+ {
+ "item_name": "rcode.notzone",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'name not in zone' response",
+ "item_description": "The number of total responses with rcode 10 (NOTZONE)"
+ },
+ {
+ "item_name": "rcode.reserved11",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent response with rcode 11",
+ "item_description": "The number of total responses with rcode 11 (reserved)"
+ },
+ {
+ "item_name": "rcode.reserved12",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent response with rcode 12",
+ "item_description": "The number of total responses with rcode 12 (reserved)"
+ },
+ {
+ "item_name": "rcode.reserved13",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent response with rcode 13",
+ "item_description": "The number of total responses with rcode 13 (reserved)"
+ },
+ {
+ "item_name": "rcode.reserved14",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent response with rcode 14",
+ "item_description": "The number of total responses with rcode 14 (reserved)"
+ },
+ {
+ "item_name": "rcode.reserved15",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent response with rcode 15",
+ "item_description": "The number of total responses with rcode 15 (reserved)"
+ },
+ {
+ "item_name": "rcode.badvers",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'EDNS version not implemented' response",
+ "item_description": "The number of total responses with rcode 16 (BADVERS)"
}
]
}
}
}
+ // update per rcode statistics counter.
+ impl_->counters_.inc(message->getRcode());
+
server->resume(send_answer);
}
void inc(const Opcode opcode) {
opcode_counter_.inc(opcode.getCode());
}
+ void inc(const Rcode rcode) {
+ rcode_counter_.inc(rcode.getCode());
+ }
void inc(const std::string& zone,
const AuthCounters::PerZoneCounterType type);
bool submitStatistics() const;
uint64_t getCounter(const Opcode opcode) const {
return (opcode_counter_.get(opcode.getCode()));
}
+ uint64_t getCounter(const Rcode rcode) const {
+ return (rcode_counter_.get(rcode.getCode()));
+ }
private:
Counter server_counter_;
Counter opcode_counter_;
static const size_t NUM_OPCODES = 16;
+ Counter rcode_counter_;
+ static const size_t NUM_RCODES = 17;
CounterDictionary per_zone_counter_;
isc::cc::AbstractSession* statistics_session_;
AuthCounters::validator_type validator_;
// size of server_counter_: AuthCounters::SERVER_COUNTER_TYPES
// size of per_zone_counter_: AuthCounters::PER_ZONE_COUNTER_TYPES
server_counter_(AuthCounters::SERVER_COUNTER_TYPES),
- opcode_counter_(NUM_OPCODES),
+ opcode_counter_(NUM_OPCODES), rcode_counter_(NUM_RCODES),
per_zone_counter_(AuthCounters::PER_ZONE_COUNTER_TYPES),
statistics_session_(NULL)
{
<< counter;
}
}
+ // Insert non 0 Rcode counters.
+ for (int i = 0; i < NUM_RCODES; ++i) {
+ const Counter::Type counter = rcode_counter_.get(i);
+ if (counter != 0) {
+ // The counter item name should be derived lower-cased textual
+ // representation of the code.
+ std::string rcode_txt = Rcode(i).toText();
+ std::transform(rcode_txt.begin(), rcode_txt.end(),
+ rcode_txt.begin(), ::tolower);
+ statistics_string << ", \"rcode." << rcode_txt << "\": "
+ << counter;
+ }
+ }
statistics_string << " }"
<< "}"
<< "]}";
impl_->inc(opcode);
}
+void
+AuthCounters::inc(const Rcode rcode) {
+ impl_->inc(rcode);
+}
+
bool
AuthCounters::submitStatistics() const {
return (impl_->submitStatistics());
return (impl_->getCounter(opcode));
}
+uint64_t
+AuthCounters::getCounter(const Rcode rcode) const {
+ return (impl_->getCounter(rcode));
+}
+
void
AuthCounters::registerStatisticsValidator
(AuthCounters::validator_type validator) const
#define __STATISTICS_H 1
#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <cc/session.h>
#include <stdint.h>
/// \throw None
void inc(const isc::dns::Opcode opcode);
+ /// \brief Increment the counter of a per rcode counter.
+ ///
+ /// \note This is a tentative interface. See \c getCounter().
+ ///
+ /// \param rcode The rcode of the counter to increment.
+ ///
+ /// \throw None
+ void inc(const isc::dns::Rcode rcode);
+
/// \brief Submit statistics counters to statistics module.
///
/// This method is desinged to be called periodically
/// \return the value of the counter specified by \a type.
uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
- /// \brief Get the value of a per opcode counter.
+ /// \brief Get the value of a per rcode counter.
///
/// This method returns the value of the per opcode counter for the
/// specified \c opcode.
/// \return the value of the counter.
uint64_t getCounter(const isc::dns::Opcode opcode) const;
+ /// \brief Get the value of a per rcode counter.
+ ///
+ /// This method returns the value of the per rcode counter for the
+ /// specified \c rcode.
+ ///
+ /// \note As mentioned in getCounter(const isc::dns::Opcode opcode),
+ /// This is a tentative interface as an attempt of experimentally
+ /// supporting more statistics counters. This should eventually be more
+ /// generalized. In any case, this method is mainly for testing.
+ ///
+ /// \throw None
+ /// \param rcode The rcode of the counter to get the value of
+ /// \return the value of the counter.
+ uint64_t getCounter(const isc::dns::Rcode rcode) const;
+
/// \brief A type of validation function for the specification in
/// isc::config::ModuleSpec.
///
#include <boost/bind.hpp>
#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <cc/data.h>
#include <cc/session.h>
}
}
+TEST_F(AuthCountersTest, incrementRcodeCounter) {
+ // The counter should be initialized to 0. If we increment it by 1
+ // the counter should be 1.
+ for (int i = 0; i < 17; ++i) {
+ EXPECT_EQ(0, counters.getCounter(Rcode(i)));
+ counters.inc(Rcode(i));
+ EXPECT_EQ(1, counters.getCounter(Rcode(i)));
+ }
+}
+
TEST_F(AuthCountersTest, submitStatisticsWithoutSession) {
// Set statistics_session to NULL and call submitStatistics().
// Expect to return false.
ASSERT_EQ(static_cast<const char*>(NULL), item_names[i]);
}
+void
+rcodeDataCheck(ConstElementPtr data, const int expected[17]) {
+ const char* item_names[] = {
+ "noerror", "formerr", "servfail", "nxdomain", "notimp", "refused",
+ "yxdomain", "yxrrset", "nxrrset", "notauth", "notzone", "reserved11",
+ "reserved12", "reserved13", "reserved14", "reserved15", "badvers",
+ NULL
+ };
+ int i;
+ for (i = 0; i < 17; ++i) {
+ ASSERT_NE(static_cast<const char*>(NULL), item_names[i]);
+ const string item_name = "rcode." + string(item_names[i]);
+ if (expected[i] == 0) {
+ EXPECT_FALSE(data->get(item_name));
+ } else {
+ EXPECT_EQ(expected[i], data->get(item_name)->intValue());
+ }
+ }
+ // We should have examined all names
+ ASSERT_EQ(static_cast<const char*>(NULL), item_names[i]);
+}
+
+
TEST_F(AuthCountersTest, submitStatisticsWithoutValidator) {
// Submit statistics data.
// Validate if it submits correct data.
const int opcode_results[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
opcodeDataCheck(statistics_data, opcode_results);
+ // By default rcode counters are all 0 and omitted
+ const int rcode_results[17] = { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 };
+ rcodeDataCheck(statistics_data, rcode_results);
}
void
}
}
+void
+updateRcodeCounters(AuthCounters &counters, const int expected[17]) {
+ for (int i = 0; i < 17; ++i) {
+ for (int j = 0; j < expected[i]; ++j) {
+ counters.inc(Rcode(i));
+ }
+ }
+}
+
TEST_F(AuthCountersTest, submitStatisticsWithOpcodeCounters) {
// Increment some of the opcode counters. Then they should appear in the
// submitted data; others shouldn't
opcodeDataCheck(statistics_data, opcode_results);
}
+TEST_F(AuthCountersTest, submitStatisticsWithRcodeCounters) {
+ // Increment some of the opcode counters. Then they should appear in the
+ // submitted data; others shouldn't
+ const int rcode_results[17] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 0, 0, 0, 0, 0, 0, 11 };
+ updateRcodeCounters(counters, rcode_results);
+ counters.submitStatistics();
+ ConstElementPtr statistics_data = statistics_session_.sent_msg
+ ->get("command")->get(1)->get("data");
+ rcodeDataCheck(statistics_data, rcode_results);
+}
+
+TEST_F(AuthCountersTest, submitStatisticsWithAllRcodeCounters) {
+ // Increment all opcode counters. Then they should appear in the
+ // submitted data.
+ const int rcode_results[17] = { 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1 };
+ updateOpcodeCounters(counters, rcode_results);
+ counters.submitStatistics();
+ ConstElementPtr statistics_data = statistics_session_.sent_msg
+ ->get("command")->get(1)->get("data");
+ opcodeDataCheck(statistics_data, rcode_results);
+}
+
TEST_F(AuthCountersTest, submitStatisticsWithValidator) {
//a validator for the unittest