BIND 10 trac2155_2, updated. 72941a64efbe4843657cbb05f8945f7c6dc0e3a0 [2155] modify Counters::inc() to update new counters
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Oct 2 09:55:35 UTC 2012
The branch, trac2155_2 has been updated
via 72941a64efbe4843657cbb05f8945f7c6dc0e3a0 (commit)
via 3c3bea55f38dac4d8fcc9c0cda55c6382d6c2cd7 (commit)
via 307071b44a3b5e5e3e8d3cc75b00c69d81fefaee (commit)
via a7adf4e4fe023903dd4ca362a6cfa6cafc06241d (commit)
via 98cdad7fa22451ef1ca067ee747c70a31262ee61 (commit)
via c76e3fc072e8b1b771b55b6547889863ba263f31 (commit)
via 50c395e0d786b2330919498c37149edf22808a52 (commit)
from 6de9ca4708fe4e56e17aedab38b89d7f76bf2515 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
doc/Doxyfile | 4 +-
src/bin/auth/Makefile.am | 3 +-
src/bin/auth/auth.spec.pre.in | 140 ++----
src/bin/auth/auth_srv.cc | 104 +++--
src/bin/auth/auth_srv.h | 46 +-
src/bin/auth/benchmarks/Makefile.am | 3 +-
src/bin/auth/statistics.cc | 297 ++++++++-----
src/bin/auth/statistics.h | 260 +++++++----
src/bin/auth/statistics_items.h | 682 +++++++++++++++++++++++++++++
src/bin/auth/tests/Makefile.am | 3 +-
src/bin/auth/tests/auth_srv_unittest.cc | 200 +++++++--
src/bin/auth/tests/statistics_unittest.cc | 387 ++++------------
src/lib/statistics/Makefile.am | 6 +-
src/lib/statistics/counter.cc | 82 ----
src/lib/statistics/counter.h | 54 ++-
src/lib/statistics/counter_dict.cc | 265 -----------
src/lib/statistics/counter_dict.h | 202 +++++----
src/lib/statistics/tests/Makefile.am | 1 -
18 files changed, 1537 insertions(+), 1202 deletions(-)
create mode 100644 src/bin/auth/statistics_items.h
delete mode 100644 src/lib/statistics/counter.cc
delete mode 100644 src/lib/statistics/counter_dict.cc
-----------------------------------------------------------------------
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 7e122e9..9f0f7f1 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -579,8 +579,8 @@ INPUT = ../src/lib/exceptions ../src/lib/cc \
../src/lib/log/compiler ../src/lib/asiolink/ ../src/lib/nsas \
../src/lib/testutils ../src/lib/cache ../src/lib/server_common/ \
../src/bin/sockcreator/ ../src/lib/util/ ../src/lib/util/io/ \
- ../src/lib/resolve ../src/lib/acl ../src/bin/dhcp6 ../src/lib/dhcp \
- ../src/bin/dhcp4 ../tests/tools/perfdhcp devel
+ ../src/lib/resolve ../src/lib/acl ../src/lib/statistics ../src/lib/dhcp \
+ ../src/bin/dhcp6 ../src/bin/dhcp4 ../tests/tools/perfdhcp devel
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
diff --git a/src/bin/auth/Makefile.am b/src/bin/auth/Makefile.am
index 3efa9d3..2060ad6 100644
--- a/src/bin/auth/Makefile.am
+++ b/src/bin/auth/Makefile.am
@@ -54,7 +54,7 @@ b10_auth_SOURCES += auth_log.cc auth_log.h
b10_auth_SOURCES += auth_config.cc auth_config.h
b10_auth_SOURCES += command.cc command.h
b10_auth_SOURCES += common.h common.cc
-b10_auth_SOURCES += statistics.cc statistics.h
+b10_auth_SOURCES += statistics.cc statistics.h statistics_items.h
b10_auth_SOURCES += datasrc_configurator.h
b10_auth_SOURCES += main.cc
@@ -73,7 +73,6 @@ b10_auth_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
b10_auth_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
b10_auth_LDADD += $(top_builddir)/src/lib/xfr/libb10-xfr.la
b10_auth_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
-b10_auth_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
b10_auth_LDADD += $(SQLITE_LIBS)
# TODO: config.h.in is wrong because doesn't honor pkgdatadir
diff --git a/src/bin/auth/auth.spec.pre.in b/src/bin/auth/auth.spec.pre.in
index a471b7a..30a455d 100644
--- a/src/bin/auth/auth.spec.pre.in
+++ b/src/bin/auth/auth.spec.pre.in
@@ -145,7 +145,7 @@
"item_type": "integer",
"item_optional": false,
"item_default": 0,
- "item_title": "Queries TCP ",
+ "item_title": "Queries TCP",
"item_description": "A number of total query counts which all auth servers receive over TCP since they started initially"
},
{
@@ -181,14 +181,6 @@
"item_description": "The number of total request counts whose opcode is status"
},
{
- "item_name": "opcode.reserved3",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 3",
- "item_description": "The number of total request counts whose opcode is 3 (reserved)"
- },
- {
"item_name": "opcode.notify",
"item_type": "integer",
"item_optional": true,
@@ -205,84 +197,12 @@
"item_description": "The number of total request counts whose opcode is update"
},
{
- "item_name": "opcode.reserved6",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 6",
- "item_description": "The number of total request counts whose opcode is 6 (reserved)"
- },
- {
- "item_name": "opcode.reserved7",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 7",
- "item_description": "The number of total request counts whose opcode is 7 (reserved)"
- },
- {
- "item_name": "opcode.reserved8",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 8",
- "item_description": "The number of total request counts whose opcode is 8 (reserved)"
- },
- {
- "item_name": "opcode.reserved9",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 9",
- "item_description": "The number of total request counts whose opcode is 9 (reserved)"
- },
- {
- "item_name": "opcode.reserved10",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 10",
- "item_description": "The number of total request counts whose opcode is 10 (reserved)"
- },
- {
- "item_name": "opcode.reserved11",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 11",
- "item_description": "The number of total request counts whose opcode is 11 (reserved)"
- },
- {
- "item_name": "opcode.reserved12",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 12",
- "item_description": "The number of total request counts whose opcode is 12 (reserved)"
- },
- {
- "item_name": "opcode.reserved13",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 13",
- "item_description": "The number of total request counts whose opcode is 13 (reserved)"
- },
- {
- "item_name": "opcode.reserved14",
- "item_type": "integer",
- "item_optional": true,
- "item_default": 0,
- "item_title": "Received requests opcode 14",
- "item_description": "The number of total request counts whose opcode is 14 (reserved)"
- },
- {
- "item_name": "opcode.reserved15",
+ "item_name": "opcode.other",
"item_type": "integer",
"item_optional": true,
"item_default": 0,
- "item_title": "Received requests opcode 15",
- "item_description": "The number of total request counts whose opcode is 15 (reserved)"
+ "item_title": "Received requests opcode other",
+ "item_description": "The number of total request counts whose opcode is other (not well-known)"
},
{
"item_name": "rcode.noerror",
@@ -373,52 +293,68 @@
"item_description": "The number of total responses with rcode 10 (NOTZONE)"
},
{
- "item_name": "rcode.reserved11",
+ "item_name": "rcode.badsigvers",
"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_title": "Sent 'EDNS version not implemented' response",
+ "item_description": "The number of total responses with rcode 16 (BADVERS)"
},
{
- "item_name": "rcode.reserved12",
+ "item_name": "rcode.badkey",
"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_title": "Sent 'Key not recognized' response",
+ "item_description": "The number of total responses with rcode 17 (BADKEY)"
},
{
- "item_name": "rcode.reserved13",
+ "item_name": "rcode.badtime",
"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_title": "Sent 'Signature out of time window' response",
+ "item_description": "The number of total responses with rcode 18 (BADTIME)"
},
{
- "item_name": "rcode.reserved14",
+ "item_name": "rcode.badmode",
"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_title": "Sent 'Bad TKEY Mode' response",
+ "item_description": "The number of total responses with rcode 19 (BADMODE)"
},
{
- "item_name": "rcode.reserved15",
+ "item_name": "rcode.badname",
"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_title": "Sent 'Duplicate key name' response",
+ "item_description": "The number of total responses with rcode 20 (BADNAME)"
},
{
- "item_name": "rcode.badvers",
+ "item_name": "rcode.badalg",
"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)"
+ "item_title": "Sent 'Algorithm not supported' response",
+ "item_description": "The number of total responses with rcode 21 (BADALG)"
+ },
+ {
+ "item_name": "rcode.badtrunc",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent 'Bad Truncation' response",
+ "item_description": "The number of total responses with rcode 22 (BADTRUNC)"
+ },
+ {
+ "item_name": "rcode.other",
+ "item_type": "integer",
+ "item_optional": true,
+ "item_default": 0,
+ "item_title": "Sent responses with rcode other",
+ "item_description": "The number of total responses with rcode other (not well-known)"
}
]
}
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index 82a98a4..a297301 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -82,6 +82,7 @@ using namespace isc::xfr;
using namespace isc::asiolink;
using namespace isc::asiodns;
using namespace isc::server_common::portconfig;
+using isc::auth::statistics::Counters;
namespace {
// A helper class for cleaning up message renderer.
@@ -257,7 +258,7 @@ public:
AbstractSession* xfrin_session_;
/// Query counters for statistics
- AuthCounters counters_;
+ Counters counters_;
/// Addresses we listen on
AddressList listen_addresses_;
@@ -295,27 +296,29 @@ public:
/// \brief Resume the server
///
- /// This is a wrapper call for DNSServer::resume(done), if 'done' is true,
- /// the Rcode set in the given Message is counted in the statistics
- /// counter.
+ /// This is a wrapper call for DNSServer::resume(done). Query/Response
+ /// statistics counters are incremented in this method.
///
/// This method is expected to be called by processMessage()
///
/// \param server The DNSServer as passed to processMessage()
/// \param message The response as constructed by processMessage()
- /// \param done If true, the Rcode from the given message is counted,
- /// this value is then passed to server->resume(bool)
+ /// \param stats_attrs Query/response attributes for statistics which is
+ /// not in \p messsage.
+ /// Note: This parameter is modified inside this method
+ /// to store whether the answer has been sent and
+ /// the response is truncated.
+ /// \param done If true, it indicates there is a response.
+ /// this value will be passed to server->resume(bool)
void resumeServer(isc::asiodns::DNSServer* server,
isc::dns::Message& message,
- bool done);
+ statistics::QRAttributes& stats_attrs,
+ const bool done);
private:
bool xfrout_connected_;
AbstractXfroutClient& xfrout_client_;
- /// Increment query counter
- void incCounter(const int protocol);
-
// validateStatistics
bool validateStatistics(isc::data::ConstElementPtr data) const;
@@ -499,6 +502,12 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
OutputBuffer& buffer, DNSServer* server)
{
InputBuffer request_buffer(io_message.getData(), io_message.getDataSize());
+ statistics::QRAttributes stats_attrs;
+
+ // statistics: check transport carrying the message (IP, transport)
+ stats_attrs.setQueryIPVersion(io_message.getRemoteEndpoint().getFamily());
+ stats_attrs.setQueryTransportProtocol(
+ io_message.getRemoteEndpoint().getProtocol());
// First, check the header part. If we fail even for the base header,
// just drop the message.
@@ -508,13 +517,13 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
// Ignore all responses.
if (message.getHeaderFlag(Message::HEADERFLAG_QR)) {
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_RESPONSE_RECEIVED);
- impl_->resumeServer(server, message, false);
+ impl_->resumeServer(server, message, stats_attrs, false);
return;
}
} catch (const Exception& ex) {
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_HEADER_PARSE_FAIL)
.arg(ex.what());
- impl_->resumeServer(server, message, false);
+ impl_->resumeServer(server, message, stats_attrs, false);
return;
}
@@ -525,13 +534,13 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_PACKET_PROTOCOL_ERROR)
.arg(error.getRcode().toText()).arg(error.what());
makeErrorMessage(impl_->renderer_, message, buffer, error.getRcode());
- impl_->resumeServer(server, message, true);
+ impl_->resumeServer(server, message, stats_attrs, true);
return;
} catch (const Exception& ex) {
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_PACKET_PARSE_ERROR)
.arg(ex.what());
makeErrorMessage(impl_->renderer_, message, buffer, Rcode::SERVFAIL());
- impl_->resumeServer(server, message, true);
+ impl_->resumeServer(server, message, stats_attrs, true);
return;
} // other exceptions will be handled at a higher layer.
@@ -554,21 +563,35 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
**impl_->keyring_));
tsig_error = tsig_context->verify(tsig_record, io_message.getData(),
io_message.getDataSize());
+ // statistics: check TSIG attributes
+ // SIG(0) is currently not implemented in Auth
+ stats_attrs.setQuerySig(true, false,
+ tsig_error == TSIGError::NOERROR());
}
if (tsig_error != TSIGError::NOERROR()) {
makeErrorMessage(impl_->renderer_, message, buffer,
tsig_error.toRcode(), tsig_context);
- impl_->resumeServer(server, message, true);
+ impl_->resumeServer(server, message, stats_attrs, true);
return;
}
const Opcode opcode = message.getOpcode();
bool send_answer = true;
try {
- // update per opcode statistics counter. This can only be reliable
- // after TSIG check succeeds.
- impl_->counters_.inc(message.getOpcode());
+ // statistics: check EDNS
+ // note: This can only be reliable after TSIG check succeeds.
+ {
+ ConstEDNSPtr edns = message.getEDNS();
+ if (edns != NULL) {
+ stats_attrs.setQueryEDNS(true, edns->getVersion() == 0);
+ stats_attrs.setQueryDO(edns->getDNSSECAwareness());
+ }
+ }
+
+ // statistics: check OpCode
+ // note: This can only be reliable after TSIG check succeeds.
+ stats_attrs.setQueryOpCode(opcode.getCode());
if (opcode == Opcode::NOTIFY()) {
send_answer = impl_->processNotify(io_message, message, buffer,
@@ -610,7 +633,7 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_RESPONSE_FAILURE_UNKNOWN);
makeErrorMessage(impl_->renderer_, message, buffer, Rcode::SERVFAIL());
}
- impl_->resumeServer(server, message, send_answer);
+ impl_->resumeServer(server, message, stats_attrs, send_answer);
}
bool
@@ -627,9 +650,6 @@ AuthSrvImpl::processNormalQuery(const IOMessage& io_message, Message& message,
message.setHeaderFlag(Message::HEADERFLAG_AA);
message.setRcode(Rcode::NOERROR());
- // Increment query counter.
- incCounter(io_message.getSocket().getProtocol());
-
if (remote_edns) {
EDNSPtr local_edns = EDNSPtr(new EDNS());
local_edns->setDNSSECAwareness(dnssec_ok);
@@ -674,9 +694,6 @@ AuthSrvImpl::processXfrQuery(const IOMessage& io_message, Message& message,
OutputBuffer& buffer,
auto_ptr<TSIGContext> tsig_context)
{
- // Increment query counter.
- incCounter(io_message.getSocket().getProtocol());
-
if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_AXFR_UDP);
makeErrorMessage(renderer_, message, buffer, Rcode::FORMERR(),
@@ -809,19 +826,6 @@ AuthSrvImpl::processUpdate(const IOMessage& io_message) {
}
void
-AuthSrvImpl::incCounter(const int protocol) {
- // Increment query counter.
- if (protocol == IPPROTO_UDP) {
- counters_.inc(AuthCounters::SERVER_UDP_QUERY);
- } else if (protocol == IPPROTO_TCP) {
- counters_.inc(AuthCounters::SERVER_TCP_QUERY);
- } else {
- // unknown protocol
- isc_throw(Unexpected, "Unknown protocol: " << protocol);
- }
-}
-
-void
AuthSrvImpl::registerStatisticsValidator() {
counters_.registerStatisticsValidator(
boost::bind(&AuthSrvImpl::validateStatistics, this, _1));
@@ -838,10 +842,15 @@ AuthSrvImpl::validateStatistics(isc::data::ConstElementPtr data) const {
}
void
-AuthSrvImpl::resumeServer(DNSServer* server, Message& message, bool done) {
+AuthSrvImpl::resumeServer(DNSServer* server, Message& message,
+ statistics::QRAttributes& stats_attrs,
+ const bool done) {
if (done) {
- counters_.inc(message.getRcode());
+ stats_attrs.answerWasSent();
+ // isTruncated from MessageRenderer
+ stats_attrs.setResponseTruncated(renderer_.isTruncated());
}
+ counters_.inc(stats_attrs, message);
server->resume(done);
}
@@ -864,21 +873,6 @@ ConstElementPtr AuthSrv::getStatistics() const {
return (impl_->counters_.getStatistics());
}
-uint64_t
-AuthSrv::getCounter(const AuthCounters::ServerCounterType type) const {
- return (impl_->counters_.getCounter(type));
-}
-
-uint64_t
-AuthSrv::getCounter(const Opcode opcode) const {
- return (impl_->counters_.getCounter(opcode));
-}
-
-uint64_t
-AuthSrv::getCounter(const Rcode rcode) const {
- return (impl_->counters_.getCounter(rcode));
-}
-
const AddressList&
AuthSrv::getListenAddresses() const {
return (impl_->listen_addresses_);
diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h
index e2ffd71..a3d8402 100644
--- a/src/bin/auth/auth_srv.h
+++ b/src/bin/auth/auth_srv.h
@@ -205,55 +205,11 @@ public:
/// \brief Returns statistics data
///
/// This function can throw an exception from
- /// AuthCounters::getStatistics().
+ /// Counters::getStatistics().
///
/// \return JSON format statistics data.
isc::data::ConstElementPtr getStatistics() const;
- /// \brief Get the value of counter in the AuthCounters.
- ///
- /// This function calls AuthCounters::getStatistics() and
- /// returns its return value.
- ///
- /// This function never throws an exception as far as
- /// AuthCounters::getStatistics() doesn't throw.
- ///
- /// Note: Currently this function is for testing purpose only.
- ///
- /// \param type Type of a counter to get the value of
- ///
- /// \return the value of the counter.
-
- uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
-
- /// \brief Get the value of per Opcode counter in the Auth Counters.
- ///
- /// This function calls AuthCounters::getCounter(isc::dns::Opcode) and
- /// returns its return value.
- ///
- /// \note 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 opcode The opcode of the counter to get the value of
- /// \return the value of the counter.
- uint64_t getCounter(const isc::dns::Opcode opcode) const;
-
- /// \brief Get the value of per Rcode counter in the Auth Counters.
- ///
- /// This function calls AuthCounters::getCounter(isc::dns::Rcode) and
- /// returns its return value.
- ///
- /// \note 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 Set and get the addresses we listen on.
*/
diff --git a/src/bin/auth/benchmarks/Makefile.am b/src/bin/auth/benchmarks/Makefile.am
index 948e718..35e3179 100644
--- a/src/bin/auth/benchmarks/Makefile.am
+++ b/src/bin/auth/benchmarks/Makefile.am
@@ -15,7 +15,7 @@ query_bench_SOURCES = query_bench.cc
query_bench_SOURCES += ../query.h ../query.cc
query_bench_SOURCES += ../auth_srv.h ../auth_srv.cc
query_bench_SOURCES += ../auth_config.h ../auth_config.cc
-query_bench_SOURCES += ../statistics.h ../statistics.cc
+query_bench_SOURCES += ../statistics.h ../statistics.cc ../statistics_items.h
query_bench_SOURCES += ../auth_log.h ../auth_log.cc
nodist_query_bench_SOURCES = ../auth_messages.h ../auth_messages.cc
@@ -33,6 +33,5 @@ query_bench_LDADD += $(top_builddir)/src/lib/nsas/libb10-nsas.la
query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
query_bench_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
query_bench_LDADD += $(top_builddir)/src/lib/asiodns/libb10-asiodns.la
-query_bench_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
query_bench_LDADD += $(SQLITE_LIBS)
diff --git a/src/bin/auth/statistics.cc b/src/bin/auth/statistics.cc
index 2d5f336..e1b12a4 100644
--- a/src/bin/auth/statistics.cc
+++ b/src/bin/auth/statistics.cc
@@ -13,9 +13,11 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <auth/statistics.h>
+#include <auth/statistics_items.h>
#include <auth/auth_log.h>
#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <cc/data.h>
#include <cc/session.h>
@@ -32,106 +34,210 @@
#include <boost/noncopyable.hpp>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
using namespace isc::dns;
using namespace isc::auth;
using namespace isc::statistics;
-// TODO: We need a namespace ("auth_server"?) to hold
-// AuthSrv and AuthCounters.
+namespace isc {
+namespace auth {
+namespace statistics {
// TODO: Make use of wrappers like isc::dns::Opcode
// for counter item type.
-class AuthCountersImpl : boost::noncopyable {
+class CountersImpl : boost::noncopyable {
public:
- AuthCountersImpl();
- ~AuthCountersImpl();
- void inc(const AuthCounters::ServerCounterType type);
- 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);
+ CountersImpl();
+ ~CountersImpl();
+ void inc(const QRAttributes& qrattrs, const Message& response);
isc::data::ConstElementPtr getStatistics() const;
- void registerStatisticsValidator
- (AuthCounters::validator_type validator);
- // Currently for testing purpose only
- uint64_t getCounter(const AuthCounters::ServerCounterType type) 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()));
- }
+ void registerStatisticsValidator(Counters::validator_type validator);
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_;
- AuthCounters::validator_type validator_;
+ // counter for query/response
+ Counter server_qr_counter_;
+ // counter for socket
+ Counter socket_counter_;
+ // set of counters for zones
+ CounterDictionary zone_qr_counters_;
+ // validator
+ Counters::validator_type validator_;
};
-AuthCountersImpl::AuthCountersImpl() :
- // initialize counter
- // 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), rcode_counter_(NUM_RCODES),
- per_zone_counter_(AuthCounters::PER_ZONE_COUNTER_TYPES)
-{
- per_zone_counter_.addElement("_SERVER_");
-}
+CountersImpl::CountersImpl() :
+ // size of server_qr_counter_, zone_qr_counters_: QR_COUNTER_TYPES
+ // size of server_socket_counter_: SOCKET_COUNTER_TYPES
+ server_qr_counter_(QR_COUNTER_TYPES),
+ socket_counter_(SOCKET_COUNTER_TYPES),
+ zone_qr_counters_(QR_COUNTER_TYPES),
+ validator_()
+{}
-AuthCountersImpl::~AuthCountersImpl()
+CountersImpl::~CountersImpl()
{}
void
-AuthCountersImpl::inc(const AuthCounters::ServerCounterType type) {
- server_counter_.inc(type);
-}
+CountersImpl::inc(const QRAttributes& qrattrs, const Message& response) {
+ // protocols carrying request
+ if (qrattrs.req_ip_version_ == AF_INET) {
+ server_qr_counter_.inc(QR_REQUEST_IPV4);
+ } else if (qrattrs.req_ip_version_ == AF_INET6) {
+ server_qr_counter_.inc(QR_REQUEST_IPV6);
+ }
+ if (qrattrs.req_transport_protocol_ == IPPROTO_UDP) {
+ server_qr_counter_.inc(QR_REQUEST_UDP);
+ } else if (qrattrs.req_transport_protocol_ == IPPROTO_TCP) {
+ server_qr_counter_.inc(QR_REQUEST_TCP);
+ }
-void
-AuthCountersImpl::inc(const std::string& zone,
- const AuthCounters::PerZoneCounterType type)
-{
- per_zone_counter_[zone].inc(type);
+ // query TSIG
+ if (qrattrs.req_is_tsig_) {
+ server_qr_counter_.inc(QR_REQUEST_TSIG);
+ }
+ if (qrattrs.req_is_sig0_) {
+ server_qr_counter_.inc(QR_REQUEST_SIG0);
+ }
+ if (qrattrs.req_is_badsig_) {
+ server_qr_counter_.inc(QR_REQUEST_BADSIG);
+ // If signature validation is failed, no other attributes are reliable
+ return;
+ }
+
+ // query EDNS
+ if (qrattrs.req_is_edns_0_) {
+ server_qr_counter_.inc(QR_REQUEST_EDNS0);
+ }
+ if (qrattrs.req_is_edns_badver_) {
+ server_qr_counter_.inc(QR_REQUEST_BADEDNSVER);
+ }
+
+ // query DNSSEC
+ if (qrattrs.req_is_dnssec_ok_) {
+ server_qr_counter_.inc(QR_REQUEST_DNSSEC_OK);
+ }
+
+ // QTYPE
+ unsigned int qtype_type = QR_QTYPE_OTHER;
+ const QuestionIterator qiter = response.beginQuestion();
+ if (qiter != response.endQuestion()) {
+ // get the first and only question section
+ const QuestionPtr qptr = *qiter;
+ if (qptr != NULL) {
+ // get the qtype code
+ const unsigned int qtype = qptr->getType().getCode();
+ if (qtype < 258) {
+ // qtype 0..257
+ qtype_type = QRQTypeToQRCounterType[qtype];
+ } else if (qtype < 32768) {
+ // qtype 258..32767
+ qtype_type = QR_QTYPE_OTHER;
+ } else if (qtype < 32770) {
+ // qtype 32768..32769
+ qtype_type = QR_QTYPE_TA + (qtype - 32768);
+ } else {
+ // qtype 32770..65535
+ qtype_type = QR_QTYPE_OTHER;
+ }
+ }
+ }
+ server_qr_counter_.inc(qtype_type);
+ // OPCODE
+ server_qr_counter_.inc(QROpCodeToQRCounterType[qrattrs.req_opcode_]);
+
+ // response
+ if (qrattrs.answer_sent_) {
+ // responded
+ server_qr_counter_.inc(QR_RESPONSE);
+
+ // response truncated
+ if (qrattrs.res_is_truncated_) {
+ server_qr_counter_.inc(QR_RESPONSE_TRUNCATED);
+ }
+
+ // response EDNS
+ ConstEDNSPtr response_edns = response.getEDNS();
+ if (response_edns != NULL && response_edns->getVersion() == 0) {
+ server_qr_counter_.inc(QR_RESPONSE_EDNS0);
+ }
+
+ // response TSIG
+ if (qrattrs.req_is_tsig_) {
+ // assume response is TSIG signed if request is TSIG signed
+ server_qr_counter_.inc(QR_RESPONSE_TSIG);
+ }
+
+ // response SIG(0) is currently not implemented
+
+ // RCODE
+ const unsigned int rcode = response.getRcode().getCode();
+ unsigned int rcode_type = QR_RCODE_OTHER;
+ if (rcode < 23) {
+ // rcode 0..22
+ rcode_type = QRRCodeToQRCounterType[rcode];
+ } else {
+ // opcode larger than 22 is reserved or unassigned
+ rcode_type = QR_RCODE_OTHER;
+ }
+ server_qr_counter_.inc(rcode_type);
+
+ // compound attributes
+ const unsigned int answer_rrs =
+ response.getRRCount(Message::SECTION_ANSWER);
+ const bool is_aa_set = response.getHeaderFlag(Message::HEADERFLAG_AA);
+
+ if (is_aa_set) {
+ // QryAuthAns
+ server_qr_counter_.inc(QR_QRYAUTHANS);
+ } else {
+ // QryNoAuthAns
+ server_qr_counter_.inc(QR_QRYNOAUTHANS);
+ }
+
+ if (rcode == Rcode::NOERROR_CODE) {
+ if (answer_rrs > 0) {
+ // QrySuccess
+ server_qr_counter_.inc(QR_QRYSUCCESS);
+ } else {
+ if (is_aa_set) {
+ // QryNxrrset
+ server_qr_counter_.inc(QR_QRYNXRRSET);
+ } else {
+ // QryReferral
+ server_qr_counter_.inc(QR_QRYREFERRAL);
+ }
+ }
+ } else if (rcode == Rcode::REFUSED_CODE) {
+ // AuthRej
+ server_qr_counter_.inc(QR_QRYREJECT);
+ }
+ }
}
isc::data::ConstElementPtr
-AuthCountersImpl::getStatistics() const {
+CountersImpl::getStatistics() const {
std::stringstream statistics_string;
statistics_string << "{ \"queries.udp\": "
- << server_counter_.get(AuthCounters::SERVER_UDP_QUERY)
+ << server_qr_counter_.get(QR_REQUEST_UDP)
<< ", \"queries.tcp\": "
- << server_counter_.get(AuthCounters::SERVER_TCP_QUERY);
+ << server_qr_counter_.get(QR_REQUEST_TCP);
// Insert non 0 Opcode counters.
- for (int i = 0; i < NUM_OPCODES; ++i) {
- const Counter::Type counter = opcode_counter_.get(i);
+ for (int i = QR_OPCODE_QUERY; i <= QR_OPCODE_OTHER; ++i) {
+ const Counter::Type counter = server_qr_counter_.get(i);
if (counter != 0) {
- // The counter item name should be derived lower-cased textual
- // representation of the code.
- std::string opcode_txt = Opcode(i).toText();
- std::transform(opcode_txt.begin(), opcode_txt.end(),
- opcode_txt.begin(), ::tolower);
- statistics_string << ", \"opcode." << opcode_txt << "\": "
+ statistics_string << ", \"" << QRCounterItemName[i] << "\": "
<< counter;
}
}
// Insert non 0 Rcode counters.
- for (int i = 0; i < NUM_RCODES; ++i) {
- const Counter::Type counter = rcode_counter_.get(i);
+ for (int i = QR_RCODE_NOERROR; i <= QR_RCODE_OTHER; ++i) {
+ const Counter::Type counter = server_qr_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 << "\": "
+ statistics_string << ", \"" << QRCounterItemName[i] << "\": "
<< counter;
}
}
@@ -150,61 +256,34 @@ AuthCountersImpl::getStatistics() const {
}
void
-AuthCountersImpl::registerStatisticsValidator
- (AuthCounters::validator_type validator)
+CountersImpl::registerStatisticsValidator
+ (Counters::validator_type validator)
{
validator_ = validator;
}
-// Currently for testing purpose only
-uint64_t
-AuthCountersImpl::getCounter(const AuthCounters::ServerCounterType type) const {
- return (server_counter_.get(type));
-}
-
-AuthCounters::AuthCounters() : impl_(new AuthCountersImpl())
+Counters::Counters() : impl_(new CountersImpl())
{}
-AuthCounters::~AuthCounters() {}
+Counters::~Counters() {}
void
-AuthCounters::inc(const AuthCounters::ServerCounterType type) {
- impl_->inc(type);
-}
-
-void
-AuthCounters::inc(const Opcode opcode) {
- impl_->inc(opcode);
-}
-
-void
-AuthCounters::inc(const Rcode rcode) {
- impl_->inc(rcode);
+Counters::inc(const QRAttributes& qrattrs, const Message& response) {
+ impl_->inc(qrattrs, response);
}
isc::data::ConstElementPtr
-AuthCounters::getStatistics() const {
+Counters::getStatistics() const {
return (impl_->getStatistics());
}
-uint64_t
-AuthCounters::getCounter(const AuthCounters::ServerCounterType type) const {
- return (impl_->getCounter(type));
-}
-
-uint64_t
-AuthCounters::getCounter(const Opcode opcode) const {
- return (impl_->getCounter(opcode));
-}
-
-uint64_t
-AuthCounters::getCounter(const Rcode rcode) const {
- return (impl_->getCounter(rcode));
-}
-
void
-AuthCounters::registerStatisticsValidator
- (AuthCounters::validator_type validator) const
+Counters::registerStatisticsValidator
+ (Counters::validator_type validator) const
{
return (impl_->registerStatisticsValidator(validator));
}
+
+} // namespace statistics
+} // namespace auth
+} // namespace isc
diff --git a/src/bin/auth/statistics.h b/src/bin/auth/statistics.h
index 0ca8da4..f3efa7d 100644
--- a/src/bin/auth/statistics.h
+++ b/src/bin/auth/statistics.h
@@ -15,19 +15,170 @@
#ifndef __STATISTICS_H
#define __STATISTICS_H 1
-#include <dns/opcode.h>
-#include <dns/rcode.h>
#include <cc/session.h>
#include <cc/data.h>
+#include <dns/message.h>
+
+#include <string>
+
#include <stdint.h>
#include <boost/scoped_ptr.hpp>
-class AuthCountersImpl;
+namespace isc {
+namespace auth {
+namespace statistics {
+
+class CountersImpl;
+
+class QRAttributes {
+/// \brief Query/Response attributes for statistics.
+///
+/// This class holds some attributes related to a query/response
+/// for statistics data collection.
+///
+/// This class does not have getter methods since it exposes private members
+/// to \c CountersImpl directly.
+friend class CountersImpl;
+private:
+ // request attributes
+ int req_ip_version_; // IP version
+ int req_transport_protocol_; // Transport layer protocol
+ int req_opcode_; // OpCode
+ bool req_is_edns_0_; // EDNS ver.0
+ bool req_is_edns_badver_; // other EDNS version
+ bool req_is_dnssec_ok_; // DO bit
+ bool req_is_tsig_; // signed with valid TSIG
+ bool req_is_sig0_; // signed with valid SIG(0)
+ bool req_is_badsig_; // signed but bad signature
+ // zone origin
+ std::string zone_origin_; // zone origin
+ // response attributes
+ bool answer_sent_; // DNS message has sent
+ bool res_is_truncated_; // DNS message is truncated
+public:
+ /// The constructor.
+ ///
+ /// This constructor is mostly exception free. But it may still throw
+ /// a standard exception if memory allocation fails inside the method.
+ ///
+ inline QRAttributes();
+ /// The destructor.
+ ///
+ /// This method never throws an exception.
+ ///
+ inline ~QRAttributes();
+ /// \brief Set query opcode.
+ /// \throw None
+ inline void setQueryOpCode(const int opcode);
+ /// \brief Set IP version carrying a query.
+ /// \throw None
+ inline void setQueryIPVersion(const int ip_version);
+ /// \brief Set transport protocol carrying a query.
+ /// \throw None
+ inline void setQueryTransportProtocol(const int transport_protocol);
+ /// \brief Set query EDNS attributes.
+ /// \throw None
+ inline void setQueryEDNS(const bool is_edns_0, const bool is_edns_badver);
+ /// \brief Set query DO bit.
+ /// \throw None
+ inline void setQueryDO(const bool is_dnssec_ok);
+ /// \brief Set query TSIG attributes.
+ /// \throw None
+ inline void setQuerySig(const bool is_tsig, const bool is_sig0,
+ const bool is_badsig);
+ /// \brief Set zone origin.
+ /// \throw None
+ inline void setOrigin(const std::string& origin);
+ /// \brief Set if the answer has sent.
+ /// \throw None
+ inline void answerWasSent();
+ /// \brief Set if the response is truncated.
+ /// \throw None
+ inline void setResponseTruncated(const bool is_truncated);
+ /// \brief Reset attributes.
+ /// \throw None
+ inline void reset();
+};
+
+inline QRAttributes::QRAttributes() :
+ req_ip_version_(0), req_transport_protocol_(0),
+ req_opcode_(0),
+ req_is_edns_0_(false), req_is_edns_badver_(false),
+ req_is_dnssec_ok_(false),
+ req_is_tsig_(false), req_is_sig0_(false), req_is_badsig_(false),
+ zone_origin_(),
+ answer_sent_(false),
+ res_is_truncated_(false)
+{}
+
+inline QRAttributes::~QRAttributes()
+{}
+
+inline void
+QRAttributes::setQueryIPVersion(const int ip_version) {
+ req_ip_version_ = ip_version;
+}
+
+inline void
+QRAttributes::setQueryTransportProtocol(const int transport_protocol) {
+ req_transport_protocol_ = transport_protocol;
+}
+
+inline void
+QRAttributes::setQueryOpCode(const int opcode) {
+ req_opcode_ = opcode;
+}
+
+inline void
+QRAttributes::setQueryEDNS(const bool is_edns_0, const bool is_edns_badver) {
+ req_is_edns_0_ = is_edns_0;
+ req_is_edns_badver_ = is_edns_badver;
+}
+
+inline void
+QRAttributes::setQueryDO(const bool is_dnssec_ok) {
+ req_is_dnssec_ok_ = is_dnssec_ok;
+}
+
+inline void
+QRAttributes::setQuerySig(const bool is_tsig, const bool is_sig0,
+ const bool is_badsig)
+{
+ req_is_tsig_ = is_tsig;
+ req_is_sig0_ = is_sig0;
+ req_is_badsig_ = is_badsig;
+}
+
+inline void
+QRAttributes::answerWasSent() {
+ answer_sent_ = true;
+}
+
+inline void
+QRAttributes::setResponseTruncated(const bool is_truncated) {
+ res_is_truncated_ = is_truncated;
+}
+
+inline void
+QRAttributes::reset() {
+ req_ip_version_ = 0;
+ req_transport_protocol_ = 0;
+ req_opcode_ = 0;
+ req_is_edns_0_ = false;
+ req_is_edns_badver_ = false;
+ req_is_dnssec_ok_ = false;
+ req_is_tsig_ = false;
+ req_is_sig0_ = false;
+ req_is_badsig_ = false;
+ zone_origin_.clear();
+ answer_sent_ = false;
+ res_is_truncated_ = false;
+}
/// \brief Set of query counters.
///
-/// \c AuthCounters is set of query counters class. It holds query counters
+/// \c Counters is set of query counters class. It holds query counters
/// and provides an interface to increment the counter of specified type
/// (e.g. UDP query, TCP query).
///
@@ -35,9 +186,7 @@ class AuthCountersImpl;
/// statistics module.
///
/// This class is designed to be a part of \c AuthSrv.
-/// Call \c inc() to increment a counter for specific type of query in
-/// the query processing function. use \c enum \c CounterType to specify
-/// the type of query.
+/// Call \c inc() to increment a counter for the query.
/// Call \c getStatistics() to answer statistics information to statistics
/// module with statistics_session, when the command \c getstats is received.
///
@@ -50,61 +199,31 @@ class AuthCountersImpl;
/// construction overhead of this approach should be acceptable.
///
/// \todo Hold counters for each query types (Notify, Axfr, Ixfr, Normal)
-/// \todo Consider overhead of \c AuthCounters::inc()
-class AuthCounters {
+/// \todo Consider overhead of \c Counters::inc()
+class Counters {
private:
- boost::scoped_ptr<AuthCountersImpl> impl_;
+ boost::scoped_ptr<CountersImpl> impl_;
public:
- // Enum for the type of counter
- enum ServerCounterType {
- SERVER_UDP_QUERY, ///< SERVER_UDP_QUERY: counter for UDP queries
- SERVER_TCP_QUERY, ///< SERVER_TCP_QUERY: counter for TCP queries
- SERVER_COUNTER_TYPES ///< The number of defined counters
- };
- enum PerZoneCounterType {
- ZONE_UDP_QUERY, ///< ZONE_UDP_QUERY: counter for UDP queries
- ZONE_TCP_QUERY, ///< ZONE_TCP_QUERY: counter for TCP queries
- PER_ZONE_COUNTER_TYPES ///< The number of defined counters
- };
/// The constructor.
///
/// This constructor is mostly exception free. But it may still throw
/// a standard exception if memory allocation fails inside the method.
///
- AuthCounters();
+ Counters();
/// The destructor.
///
/// This method never throws an exception.
///
- ~AuthCounters();
-
- /// \brief Increment the counter specified by the parameter.
- ///
- /// \param type Type of a counter to increment.
- ///
- /// \throw std::out_of_range \a type is unknown.
- ///
- /// usage: counter.inc(AuthCounters::SERVER_UDP_QUERY);
- ///
- void inc(const ServerCounterType type);
+ ~Counters();
- /// \brief Increment the counter of a per opcode counter.
+ /// \brief Increment counters according to the parameters.
///
- /// \note This is a tentative interface. See \c getCounter().
- ///
- /// \param opcode The opcode of the counter to increment.
+ /// \param qrattrs Query/Response attributes.
+ /// \param response DNS response message.
///
/// \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);
+ void inc(const QRAttributes& qrattrs, const isc::dns::Message& response);
/// \brief Answers statistics counters to statistics module.
///
@@ -116,47 +235,6 @@ public:
///
isc::data::ConstElementPtr getStatistics() const;
- /// \brief Get the value of a counter in the AuthCounters.
- ///
- /// This function returns a value of the counter specified by \a type.
- /// This method never throws an exception.
- ///
- /// Note: Currently this function is for testing purpose only.
- ///
- /// \param type Type of a counter to get the value of
- ///
- /// \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.
- ///
- /// This method returns the value of the per opcode counter for the
- /// specified \c opcode.
- ///
- /// \note 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 opcode The opcode of the counter to get the value of
- /// \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.
///
@@ -168,16 +246,20 @@ public:
validator_type;
/// \brief Register a function type of the statistics validation
- /// function for AuthCounters.
+ /// function for Counters.
///
/// This method never throws an exception.
///
/// \param validator A function type of the validation of
/// statistics specification.
///
- void registerStatisticsValidator(AuthCounters::validator_type validator) const;
+ void registerStatisticsValidator(Counters::validator_type validator) const;
};
+} // namespace statistics
+} // namespace auth
+} // namespace isc
+
#endif // __STATISTICS_H
// Local Variables:
diff --git a/src/bin/auth/statistics_items.h b/src/bin/auth/statistics_items.h
new file mode 100644
index 0000000..9404576
--- /dev/null
+++ b/src/bin/auth/statistics_items.h
@@ -0,0 +1,682 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __STATISTICS_ITEMS_H
+#define __STATISTICS_ITEMS_H 1
+
+/// This file defines a set of statistics items in Auth module for internal
+/// use. This file is intended to be included in statistics.cc.
+
+namespace {
+
+// enum for socket statistics
+enum SocketCounterType {
+ // Socket statistics
+ SOCKET_IPV4_UDP_BINDFAIL, ///< IPv4 UDP sockets bind failures
+ SOCKET_IPV4_UDP_CLOSE, ///< IPv4 UDP sockets closed
+ SOCKET_IPV4_UDP_CONN, ///< IPv4 UDP connections established successfully
+ SOCKET_IPV4_UDP_CONNFAIL, ///< IPv4 UDP sockets connection failures
+ SOCKET_IPV4_UDP_OPEN, ///< IPv4 UDP sockets opened successfully
+ SOCKET_IPV4_UDP_OPENFAIL, ///< IPv4 UDP sockets open failures
+ SOCKET_IPV4_UDP_RECVERR, ///< IPv4 UDP sockets receive errors
+ SOCKET_IPV4_UDP_SENDERR, ///< IPv4 UDP sockets send errors
+ SOCKET_IPV4_TCP_ACCEPT, ///< IPv4 TCP incoming connections successfully accepted
+ SOCKET_IPV4_TCP_ACCEPTFAIL, ///< IPv4 TCP incoming accept failures
+ SOCKET_IPV4_TCP_BINDFAIL, ///< IPv4 TCP sockets bind failures
+ SOCKET_IPV4_TCP_CLOSE, ///< IPv4 TCP sockets closed
+ SOCKET_IPV4_TCP_CONN, ///< IPv4 TCP connections established successfully
+ SOCKET_IPV4_TCP_CONNFAIL, ///< IPv4 TCP sockets connection failures
+ SOCKET_IPV4_TCP_OPEN, ///< IPv4 TCP sockets opened successfully
+ SOCKET_IPV4_TCP_OPENFAIL, ///< IPv4 TCP sockets open failures
+ SOCKET_IPV4_TCP_RECVERR, ///< IPv4 TCP sockets receive errors
+ SOCKET_IPV4_TCP_SENDERR, ///< IPv4 TCP sockets send errors
+ SOCKET_IPV6_UDP_BINDFAIL, ///< IPv6 UDP sockets bind failures
+ SOCKET_IPV6_UDP_CLOSE, ///< IPv6 UDP sockets closed
+ SOCKET_IPV6_UDP_CONN, ///< IPv6 UDP connections established successfully
+ SOCKET_IPV6_UDP_CONNFAIL, ///< IPv6 UDP sockets connection failures
+ SOCKET_IPV6_UDP_OPEN, ///< IPv6 UDP sockets opened successfully
+ SOCKET_IPV6_UDP_OPENFAIL, ///< IPv6 UDP sockets open failures
+ SOCKET_IPV6_UDP_RECVERR, ///< IPv6 UDP sockets receive errors
+ SOCKET_IPV6_UDP_SENDERR, ///< IPv6 UDP sockets send errors
+ SOCKET_IPV6_TCP_ACCEPT, ///< IPv6 TCP incoming connections successfully accepted
+ SOCKET_IPV6_TCP_ACCEPTFAIL, ///< IPv6 TCP incoming accept failures
+ SOCKET_IPV6_TCP_BINDFAIL, ///< IPv6 TCP sockets bind failures
+ SOCKET_IPV6_TCP_CLOSE, ///< IPv6 TCP sockets closed
+ SOCKET_IPV6_TCP_CONN, ///< IPv6 TCP connections established successfully
+ SOCKET_IPV6_TCP_CONNFAIL, ///< IPv6 TCP sockets connection failures
+ SOCKET_IPV6_TCP_OPEN, ///< IPv6 TCP sockets opened successfully
+ SOCKET_IPV6_TCP_OPENFAIL, ///< IPv6 TCP sockets open failures
+ SOCKET_IPV6_TCP_RECVERR, ///< IPv6 TCP sockets receive errors
+ SOCKET_IPV6_TCP_SENDERR, ///< IPv6 TCP sockets send errors
+ SOCKET_UNIXDOMAIN_ACCEPT, ///< Unix Domain sockets incoming connections successfully accepted
+ SOCKET_UNIXDOMAIN_ACCEPTFAIL, ///< Unix Domain sockets incoming accept failures
+ SOCKET_UNIXDOMAIN_BINDFAIL, ///< Unix Domain sockets bind failures
+ SOCKET_UNIXDOMAIN_CLOSE, ///< Unix Domain sockets closed
+ SOCKET_UNIXDOMAIN_CONN, ///< Unix Domain connections established successfully
+ SOCKET_UNIXDOMAIN_CONNFAIL, ///< Unix Domain sockets connection failures
+ SOCKET_UNIXDOMAIN_OPEN, ///< Unix Domain sockets opened successfully
+ SOCKET_UNIXDOMAIN_OPENFAIL, ///< Unix Domain sockets open failures
+ SOCKET_UNIXDOMAIN_RECVERR, ///< Unix Domain sockets receive errors
+ SOCKET_UNIXDOMAIN_SENDERR, ///< Unix Domain sockets send errors
+ SOCKET_COUNTER_TYPES ///< The number of defined counters
+};
+// item names for socket statistics
+const char* const SocketCounterItemName[SOCKET_COUNTER_TYPES] = {
+ "ipv4.udp.bindfail",
+ "ipv4.udp.close",
+ "ipv4.udp.conn",
+ "ipv4.udp.connfail",
+ "ipv4.udp.open",
+ "ipv4.udp.openfail",
+ "ipv4.udp.recverr",
+ "ipv4.udp.senderr",
+ "ipv4.tcp.accept",
+ "ipv4.tcp.acceptfail",
+ "ipv4.tcp.bindfail",
+ "ipv4.tcp.close",
+ "ipv4.tcp.conn",
+ "ipv4.tcp.connfail",
+ "ipv4.tcp.open",
+ "ipv4.tcp.openfail",
+ "ipv4.tcp.recverr",
+ "ipv4.tcp.senderr",
+ "ipv6.udp.bindfail",
+ "ipv6.udp.close",
+ "ipv6.udp.conn",
+ "ipv6.udp.connfail",
+ "ipv6.udp.open",
+ "ipv6.udp.openfail",
+ "ipv6.udp.recverr",
+ "ipv6.udp.senderr",
+ "ipv6.tcp.accept",
+ "ipv6.tcp.acceptfail",
+ "ipv6.tcp.bindfail",
+ "ipv6.tcp.close",
+ "ipv6.tcp.conn",
+ "ipv6.tcp.connfail",
+ "ipv6.tcp.open",
+ "ipv6.tcp.openfail",
+ "ipv6.tcp.recverr",
+ "ipv6.tcp.senderr",
+ "unixdomain.accept",
+ "unixdomain.acceptfail",
+ "unixdomain.bindfail",
+ "unixdomain.close",
+ "unixdomain.conn",
+ "unixdomain.connfail",
+ "unixdomain.open",
+ "unixdomain.openfail",
+ "unixdomain.recverr",
+ "unixdomain.senderr"
+};
+
+// enum for query/response counters
+enum QRCounterType {
+ // Request Attributes
+ QR_REQUEST_IPV4, ///< Number of IPv4 requests received
+ QR_REQUEST_IPV6, ///< Number of IPv6 requests received
+ QR_REQUEST_EDNS0, ///< Number of requests with EDNS(0) received
+ QR_REQUEST_BADEDNSVER, ///< Number of requests with unsupported EDNS version received
+ QR_REQUEST_TSIG, ///< Number of requests with TSIG received
+ QR_REQUEST_SIG0, ///< Number of requests with SIG(0) received; not implemented in BIND 10
+ QR_REQUEST_BADSIG, ///< Number of requests with invalid TSIG or SIG(0) signature received
+ QR_REQUEST_UDP, ///< Number of UDP requests received
+ QR_REQUEST_TCP, ///< Number of TCP requests received
+ QR_REQUEST_DNSSEC_OK, ///< Number of requests with DO bit
+ // Request Opcodes
+ QR_OPCODE_QUERY, ///< Number of Opcode=QUERY requests received
+ QR_OPCODE_IQUERY, ///< Number of Opcode=IQUERY requests received
+ QR_OPCODE_STATUS, ///< Number of Opcode=STATUS requests received
+ QR_OPCODE_NOTIFY, ///< Number of Opcode=NOTIFY requests received
+ QR_OPCODE_UPDATE, ///< Number of Opcode=UPDATE requests received
+ QR_OPCODE_OTHER, ///< Number of requests in other OpCode received
+ // Query Types
+ QR_QTYPE_A, ///< Number of QTYPE = A queries received
+ QR_QTYPE_NS, ///< Number of QTYPE = NS queries received
+ QR_QTYPE_MD, ///< Number of QTYPE = MD queries received
+ QR_QTYPE_MF, ///< Number of QTYPE = MF queries received
+ QR_QTYPE_CNAME, ///< Number of QTYPE = CNAME queries received
+ QR_QTYPE_SOA, ///< Number of QTYPE = SOA queries received
+ QR_QTYPE_MB, ///< Number of QTYPE = MB queries received
+ QR_QTYPE_MG, ///< Number of QTYPE = MG queries received
+ QR_QTYPE_MR, ///< Number of QTYPE = MR queries received
+ QR_QTYPE_NULL, ///< Number of QTYPE = NULL queries received
+ QR_QTYPE_WKS, ///< Number of QTYPE = WKS queries received
+ QR_QTYPE_PTR, ///< Number of QTYPE = PTR queries received
+ QR_QTYPE_HINFO, ///< Number of QTYPE = HINFO queries received
+ QR_QTYPE_MINFO, ///< Number of QTYPE = MINFO queries received
+ QR_QTYPE_MX, ///< Number of QTYPE = MX queries received
+ QR_QTYPE_TXT, ///< Number of QTYPE = TXT queries received
+ QR_QTYPE_RP, ///< Number of QTYPE = RP queries received
+ QR_QTYPE_AFSDB, ///< Number of QTYPE = AFSDB queries received
+ QR_QTYPE_X25, ///< Number of QTYPE = X25 queries received
+ QR_QTYPE_ISDN, ///< Number of QTYPE = ISDN queries received
+ QR_QTYPE_RT, ///< Number of QTYPE = RT queries received
+ QR_QTYPE_NSAP, ///< Number of QTYPE = NSAP queries received
+ QR_QTYPE_NSAP_PTR, ///< Number of QTYPE = NSAP-PTR queries received
+ QR_QTYPE_SIG, ///< Number of QTYPE = SIG queries received
+ QR_QTYPE_KEY, ///< Number of QTYPE = KEY queries received
+ QR_QTYPE_PX, ///< Number of QTYPE = PX queries received
+ QR_QTYPE_GPOS, ///< Number of QTYPE = GPOS queries received
+ QR_QTYPE_AAAA, ///< Number of QTYPE = AAAA queries received
+ QR_QTYPE_LOC, ///< Number of QTYPE = LOC queries received
+ QR_QTYPE_NXT, ///< Number of QTYPE = NXT queries received
+ QR_QTYPE_EID, ///< Number of QTYPE = EID queries received
+ QR_QTYPE_NIMLOC, ///< Number of QTYPE = NIMLOC queries received
+ QR_QTYPE_SRV, ///< Number of QTYPE = SRV queries received
+ QR_QTYPE_ATMA, ///< Number of QTYPE = ATMA queries received
+ QR_QTYPE_NAPTR, ///< Number of QTYPE = NAPTR queries received
+ QR_QTYPE_KX, ///< Number of QTYPE = KX queries received
+ QR_QTYPE_CERT, ///< Number of QTYPE = CERT queries received
+ QR_QTYPE_A6, ///< Number of QTYPE = A6 queries received
+ QR_QTYPE_DNAME, ///< Number of QTYPE = DNAME queries received
+ QR_QTYPE_SINK, ///< Number of QTYPE = SINK queries received
+ QR_QTYPE_OPT, ///< Number of QTYPE = OPT queries received
+ QR_QTYPE_APL, ///< Number of QTYPE = APL queries received
+ QR_QTYPE_DS, ///< Number of QTYPE = DS queries received
+ QR_QTYPE_SSHFP, ///< Number of QTYPE = SSHFP queries received
+ QR_QTYPE_IPSECKEY, ///< Number of QTYPE = IPSECKEY queries received
+ QR_QTYPE_RRSIG, ///< Number of QTYPE = RRSIG queries received
+ QR_QTYPE_NSEC, ///< Number of QTYPE = NSEC queries received
+ QR_QTYPE_DNSKEY, ///< Number of QTYPE = DNSKEY queries received
+ QR_QTYPE_DHCID, ///< Number of QTYPE = DHCID queries received
+ QR_QTYPE_NSEC3, ///< Number of QTYPE = NSEC3 queries received
+ QR_QTYPE_NSEC3PARAM, ///< Number of QTYPE = NSEC3PARAM queries received
+ QR_QTYPE_HIP, ///< Number of QTYPE = HIP queries received
+ QR_QTYPE_NINFO, ///< Number of QTYPE = NINFO queries received
+ QR_QTYPE_RKEY, ///< Number of QTYPE = RKEY queries received
+ QR_QTYPE_TALINK, ///< Number of QTYPE = TALINK queries received
+ QR_QTYPE_SPF, ///< Number of QTYPE = SPF queries received
+ QR_QTYPE_UINFO, ///< Number of QTYPE = UINFO queries received
+ QR_QTYPE_UID, ///< Number of QTYPE = UID queries received
+ QR_QTYPE_GID, ///< Number of QTYPE = GID queries received
+ QR_QTYPE_UNSPEC, ///< Number of QTYPE = UNSPEC queries received
+ QR_QTYPE_TKEY, ///< Number of QTYPE = TKEY queries received
+ QR_QTYPE_TSIG, ///< Number of QTYPE = TSIG queries received
+ QR_QTYPE_IXFR, ///< Number of QTYPE = IXFR queries received
+ QR_QTYPE_AXFR, ///< Number of QTYPE = AXFR queries received
+ QR_QTYPE_MAILB, ///< Number of QTYPE = MAILB queries received
+ QR_QTYPE_MAILA, ///< Number of QTYPE = MAILA queries received
+ QR_QTYPE_URI, ///< Number of QTYPE = URI queries received
+ QR_QTYPE_CAA, ///< Number of QTYPE = CAA queries received
+ QR_QTYPE_TA, ///< Number of QTYPE = TA queries received
+ QR_QTYPE_DLV, ///< Number of QTYPE = DLV queries received
+ QR_QTYPE_OTHER, ///< Number of queries in other QTYPE received
+ // Respose Attributes
+ QR_RESPONSE, ///< Number of responses sent
+ QR_RESPONSE_TRUNCATED, ///< Number of truncated responses sent
+ QR_RESPONSE_EDNS0, ///< Number of responses with EDNS0; not implemented in BIND 10
+ QR_RESPONSE_TSIG, ///< Number of responses with TSIG
+ QR_RESPONSE_SIG0, ///< Number of responses with SIG(0); not implemented in BIND 10
+ QR_QRYSUCCESS, ///< Number of queries resulted in rcode = NOERROR and answer RR >= 1
+ QR_QRYAUTHANS, ///< Number of queries resulted in authoritative answer
+ QR_QRYNOAUTHANS, ///< Number of queries resulted in non-authoritative answer
+ QR_QRYREFERRAL, ///< Number of queries resulted in referral answer
+ QR_QRYNXRRSET, ///< Number of queries resulted in NOERROR but answer RR == 0
+ QR_QRYREJECT, ///< Number of queries rejected
+ // Response Rcodes
+ QR_RCODE_NOERROR, ///< Number of queries resulted in RCODE = 0 (NoError)
+ QR_RCODE_FORMERR, ///< Number of queries resulted in RCODE = 1 (FormErr)
+ QR_RCODE_SERVFAIL, ///< Number of queries resulted in RCODE = 2 (ServFail)
+ QR_RCODE_NXDOMAIN, ///< Number of queries resulted in RCODE = 3 (NXDomain)
+ QR_RCODE_NOTIMP, ///< Number of queries resulted in RCODE = 4 (NotImp)
+ QR_RCODE_REFUSED, ///< Number of queries resulted in RCODE = 5 (Refused)
+ QR_RCODE_YXDOMAIN, ///< Number of queries resulted in RCODE = 6 (YXDomain)
+ QR_RCODE_YXRRSET, ///< Number of queries resulted in RCODE = 7 (YXRRSet)
+ QR_RCODE_NXRRSET, ///< Number of queries resulted in RCODE = 8 (NXRRSet)
+ QR_RCODE_NOTAUTH, ///< Number of queries resulted in RCODE = 9 (NotAuth)
+ QR_RCODE_NOTZONE, ///< Number of queries resulted in RCODE = 10 (NotZone)
+ QR_RCODE_BADSIGVERS, ///< Number of queries resulted in RCODE = 16 (BADVERS, BADSIG)
+ QR_RCODE_BADKEY, ///< Number of queries resulted in RCODE = 17 (BADKEY)
+ QR_RCODE_BADTIME, ///< Number of queries resulted in RCODE = 18 (BADTIME)
+ QR_RCODE_BADMODE, ///< Number of queries resulted in RCODE = 19 (BADMODE)
+ QR_RCODE_BADNAME, ///< Number of queries resulted in RCODE = 20 (BADNAME)
+ QR_RCODE_BADALG, ///< Number of queries resulted in RCODE = 21 (BADALG)
+ QR_RCODE_BADTRUNC, ///< Number of queries resulted in RCODE = 22 (BADTRUNC)
+ QR_RCODE_OTHER, ///< Number of queries resulted in other RCODEs
+ // End of counter types
+ QR_COUNTER_TYPES ///< The number of defined counters
+};
+// item names for query/response counters
+const char* const QRCounterItemName[QR_COUNTER_TYPES] = {
+ "request.v4",
+ "request.v6",
+ "request.edns0",
+ "request.badednsver",
+ "request.tsig",
+ "request.sig0",
+ "request.badsig",
+ "request.udp",
+ "request.tcp",
+ "request.dnssec_ok",
+ "opcode.query",
+ "opcode.iquery",
+ "opcode.status",
+ "opcode.notify",
+ "opcode.update",
+ "opcode.other",
+ "qtype.a",
+ "qtype.ns",
+ "qtype.md",
+ "qtype.mf",
+ "qtype.cname",
+ "qtype.soa",
+ "qtype.mb",
+ "qtype.mg",
+ "qtype.mr",
+ "qtype.null",
+ "qtype.wks",
+ "qtype.ptr",
+ "qtype.hinfo",
+ "qtype.minfo",
+ "qtype.mx",
+ "qtype.txt",
+ "qtype.rp",
+ "qtype.afsdb",
+ "qtype.x25",
+ "qtype.isdn",
+ "qtype.rt",
+ "qtype.nsap",
+ "qtype.nsap-ptr",
+ "qtype.sig",
+ "qtype.key",
+ "qtype.px",
+ "qtype.gpos",
+ "qtype.aaaa",
+ "qtype.loc",
+ "qtype.nxt",
+ "qtype.eid",
+ "qtype.nimloc",
+ "qtype.srv",
+ "qtype.atma",
+ "qtype.naptr",
+ "qtype.kx",
+ "qtype.cert",
+ "qtype.a6",
+ "qtype.dname",
+ "qtype.sink",
+ "qtype.opt",
+ "qtype.apl",
+ "qtype.ds",
+ "qtype.sshfp",
+ "qtype.ipseckey",
+ "qtype.rrsig",
+ "qtype.nsec",
+ "qtype.dnskey",
+ "qtype.dhcid",
+ "qtype.nsec3",
+ "qtype.nsec3param",
+ "qtype.hip",
+ "qtype.ninfo",
+ "qtype.rkey",
+ "qtype.talink",
+ "qtype.spf",
+ "qtype.uinfo",
+ "qtype.uid",
+ "qtype.gid",
+ "qtype.unspec",
+ "qtype.tkey",
+ "qtype.tsig",
+ "qtype.ixfr",
+ "qtype.axfr",
+ "qtype.mailb",
+ "qtype.maila",
+ "qtype.uri",
+ "qtype.caa",
+ "qtype.ta",
+ "qtype.dlv",
+ "qtype.other",
+ "response",
+ "response.truncated",
+ "response.edns0",
+ "response.tsig",
+ "response.sig0",
+ "qrysuccess",
+ "qryauthans",
+ "qrynoauthans",
+ "qryreferral",
+ "qrynxrrset",
+ "authqryrej",
+ "rcode.noerror",
+ "rcode.formerr",
+ "rcode.servfail",
+ "rcode.nxdomain",
+ "rcode.notimp",
+ "rcode.refused",
+ "rcode.yxdomain",
+ "rcode.yxrrset",
+ "rcode.nxrrset",
+ "rcode.notauth",
+ "rcode.notzone",
+ "rcode.badsigvers",
+ "rcode.badkey",
+ "rcode.badtime",
+ "rcode.badmode",
+ "rcode.badname",
+ "rcode.badalg",
+ "rcode.badtrunc",
+ "rcode.other"
+};
+
+const int QROpCodeToQRCounterType[16] = {
+ QR_OPCODE_QUERY,
+ QR_OPCODE_IQUERY,
+ QR_OPCODE_STATUS,
+ QR_OPCODE_OTHER,
+ QR_OPCODE_NOTIFY,
+ QR_OPCODE_UPDATE,
+ QR_OPCODE_OTHER,
+ QR_OPCODE_OTHER,
+ QR_OPCODE_OTHER,
+ QR_OPCODE_OTHER,
+ QR_OPCODE_OTHER,
+ QR_OPCODE_OTHER,
+ QR_OPCODE_OTHER,
+ QR_OPCODE_OTHER,
+ QR_OPCODE_OTHER,
+ QR_OPCODE_OTHER
+};
+const int QRQTypeToQRCounterType[258] = {
+ QR_QTYPE_OTHER,
+ QR_QTYPE_A,
+ QR_QTYPE_NS,
+ QR_QTYPE_MD,
+ QR_QTYPE_MF,
+ QR_QTYPE_CNAME,
+ QR_QTYPE_SOA,
+ QR_QTYPE_MB,
+ QR_QTYPE_MG,
+ QR_QTYPE_MR,
+ QR_QTYPE_NULL,
+ QR_QTYPE_WKS,
+ QR_QTYPE_PTR,
+ QR_QTYPE_HINFO,
+ QR_QTYPE_MINFO,
+ QR_QTYPE_MX,
+ QR_QTYPE_TXT,
+ QR_QTYPE_RP,
+ QR_QTYPE_AFSDB,
+ QR_QTYPE_X25,
+ QR_QTYPE_ISDN,
+ QR_QTYPE_RT,
+ QR_QTYPE_NSAP,
+ QR_QTYPE_NSAP_PTR,
+ QR_QTYPE_SIG,
+ QR_QTYPE_KEY,
+ QR_QTYPE_PX,
+ QR_QTYPE_GPOS,
+ QR_QTYPE_AAAA,
+ QR_QTYPE_LOC,
+ QR_QTYPE_NXT,
+ QR_QTYPE_EID,
+ QR_QTYPE_NIMLOC,
+ QR_QTYPE_SRV,
+ QR_QTYPE_ATMA,
+ QR_QTYPE_NAPTR,
+ QR_QTYPE_KX,
+ QR_QTYPE_CERT,
+ QR_QTYPE_A6,
+ QR_QTYPE_DNAME,
+ QR_QTYPE_SINK,
+ QR_QTYPE_OPT,
+ QR_QTYPE_APL,
+ QR_QTYPE_DS,
+ QR_QTYPE_SSHFP,
+ QR_QTYPE_IPSECKEY,
+ QR_QTYPE_RRSIG,
+ QR_QTYPE_NSEC,
+ QR_QTYPE_DNSKEY,
+ QR_QTYPE_DHCID,
+ QR_QTYPE_NSEC3,
+ QR_QTYPE_NSEC3PARAM,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_HIP,
+ QR_QTYPE_NINFO,
+ QR_QTYPE_RKEY,
+ QR_QTYPE_TALINK,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_SPF,
+ QR_QTYPE_UINFO,
+ QR_QTYPE_UID,
+ QR_QTYPE_GID,
+ QR_QTYPE_UNSPEC,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_TKEY,
+ QR_QTYPE_TSIG,
+ QR_QTYPE_IXFR,
+ QR_QTYPE_AXFR,
+ QR_QTYPE_MAILB,
+ QR_QTYPE_MAILA,
+ QR_QTYPE_OTHER,
+ QR_QTYPE_URI,
+ QR_QTYPE_CAA
+};
+const int QRRCodeToQRCounterType[23] = {
+ QR_RCODE_NOERROR,
+ QR_RCODE_FORMERR,
+ QR_RCODE_SERVFAIL,
+ QR_RCODE_NXDOMAIN,
+ QR_RCODE_NOTIMP,
+ QR_RCODE_REFUSED,
+ QR_RCODE_YXDOMAIN,
+ QR_RCODE_YXRRSET,
+ QR_RCODE_NXRRSET,
+ QR_RCODE_NOTAUTH,
+ QR_RCODE_NOTZONE,
+ QR_RCODE_OTHER,
+ QR_RCODE_OTHER,
+ QR_RCODE_OTHER,
+ QR_RCODE_OTHER,
+ QR_RCODE_OTHER,
+ QR_RCODE_BADSIGVERS,
+ QR_RCODE_BADKEY,
+ QR_RCODE_BADTIME,
+ QR_RCODE_BADMODE,
+ QR_RCODE_BADNAME,
+ QR_RCODE_BADALG,
+ QR_RCODE_BADTRUNC
+};
+
+} // anonymous namespace
+
+#endif // __STATISTICS_ITEMS_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/bin/auth/tests/Makefile.am b/src/bin/auth/tests/Makefile.am
index 75e4a27..482a4f7 100644
--- a/src/bin/auth/tests/Makefile.am
+++ b/src/bin/auth/tests/Makefile.am
@@ -41,7 +41,7 @@ run_unittests_SOURCES += ../query.h ../query.cc
run_unittests_SOURCES += ../auth_config.h ../auth_config.cc
run_unittests_SOURCES += ../command.h ../command.cc
run_unittests_SOURCES += ../common.h ../common.cc
-run_unittests_SOURCES += ../statistics.h ../statistics.cc
+run_unittests_SOURCES += ../statistics.h ../statistics.cc ../statistics_items.h
run_unittests_SOURCES += datasrc_util.h datasrc_util.cc
run_unittests_SOURCES += auth_srv_unittest.cc
run_unittests_SOURCES += config_unittest.cc
@@ -71,7 +71,6 @@ run_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
run_unittests_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
run_unittests_LDADD += $(top_builddir)/src/lib/nsas/libb10-nsas.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
-run_unittests_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
run_unittests_LDADD += $(top_builddir)/src/lib/config/tests/libfake_session.la
run_unittests_LDADD += $(GTEST_LDADD)
run_unittests_LDADD += $(SQLITE_LIBS)
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index e7b4ca7..e59db6d 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -36,6 +36,7 @@
#include <auth/command.h>
#include <auth/common.h>
#include <auth/statistics.h>
+#include <auth/statistics_items.h>
#include <auth/datasrc_configurator.h>
#include <util/unittests/mock_socketsession.h>
@@ -74,6 +75,7 @@ using namespace isc::testutils;
using namespace isc::server_common::portconfig;
using isc::UnitTestUtil;
using boost::scoped_ptr;
+using isc::auth::statistics::Counters;
namespace {
const char* const CONFIG_TESTDB =
@@ -118,29 +120,58 @@ protected:
// Helper for checking Rcode statistic counters;
// Checks for one specific Rcode statistics counter value
- void checkRcodeCounter(const Rcode& rcode, int expected_value) const {
- EXPECT_EQ(expected_value, server.getCounter(rcode)) <<
- "Expected Rcode count for " << rcode.toText() <<
- " " << expected_value << ", was: " <<
- server.getCounter(rcode);
+ void checkRcodeCounter(const std::string& rcode_name, const int rcode_value,
+ const int expected_value) const
+ {
+ EXPECT_EQ(expected_value, rcode_value) <<
+ "Expected Rcode count for " << rcode_name <<
+ " " << expected_value << ", was: " <<
+ rcode_value;
}
// Checks whether all Rcode counters are set to zero
void checkAllRcodeCountersZero() const {
- for (int i = 0; i < 17; i++) {
- checkRcodeCounter(Rcode(i), 0);
+ const std::map<std::string, ConstElementPtr>
+ stats_map(server.getStatistics()->mapValue());
+
+ const std::string rcode_prefix("rcode.");
+ for (std::map<std::string, ConstElementPtr>::const_iterator
+ i = stats_map.begin(), e = stats_map.end();
+ i != e;
+ ++i)
+ {
+ if (i->first.compare(0, rcode_prefix.size(), rcode_prefix) == 0) {
+ checkRcodeCounter(i->first, i->second->intValue(), 0);
+ }
}
}
// Checks whether all Rcode counters are set to zero except the given
// rcode (it is checked to be set to 'value')
void checkAllRcodeCountersZeroExcept(const Rcode& rcode, int value) const {
- for (int i = 0; i < 17; i++) {
- const Rcode rc(i);
- if (rc == rcode) {
- checkRcodeCounter(Rcode(i), value);
- } else {
- checkRcodeCounter(Rcode(i), 0);
+ std::string target_rcode_name = rcode.toText();
+ std::transform(target_rcode_name.begin(), target_rcode_name.end(),
+ target_rcode_name.begin(), ::tolower);
+ // rcode 16 is registered as both BADVERS and BADSIG
+ if (target_rcode_name == "badvers") {
+ target_rcode_name = "badsigvers";
+ }
+
+ const std::map<std::string, ConstElementPtr>
+ stats_map(server.getStatistics()->mapValue());
+
+ const std::string rcode_prefix("rcode.");
+ for (std::map<std::string, ConstElementPtr>::const_iterator
+ i = stats_map.begin(), e = stats_map.end();
+ i != e;
+ ++i)
+ {
+ if (i->first.compare(0, rcode_prefix.size(), rcode_prefix) == 0) {
+ if (i->first.compare(rcode_prefix + target_rcode_name) == 0) {
+ checkRcodeCounter(i->first, i->second->intValue(), value);
+ } else {
+ checkRcodeCounter(i->first, i->second->intValue(), 0);
+ }
}
}
}
@@ -217,6 +248,20 @@ createBuiltinVersionResponse(const qid_t qid, vector<uint8_t>& data) {
renderer.getLength());
}
+void
+expectCounterItem(ConstElementPtr stats,
+ const std::string& item, const int expected) {
+ ConstElementPtr value(Element::create(0));
+ if (item == "queries.udp" || item == "queries.tcp" || expected != 0) {
+ ASSERT_TRUE(stats->find(item, value)) << " Item: " << item;
+ value = stats->find(item);
+ EXPECT_EQ(expected, value->intValue()) << " Item: " << item;
+ } else {
+ ASSERT_FALSE(stats->find(item, value)) << " Item: " << item <<
+ std::endl << " Value: " << value->intValue();
+ }
+}
+
// We did not configure any client lists. Therefore it should be REFUSED
TEST_F(AuthSrvTest, noClientList) {
UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
@@ -400,7 +445,9 @@ TEST_F(AuthSrvTest, TSIGCheckFirst) {
"It should be unsigned with this error";
// TSIG should have failed, and so the per opcode counter shouldn't be
// incremented.
- EXPECT_EQ(0, server.getCounter(Opcode::RESERVED14()));
+ ConstElementPtr stats = server.getStatistics();
+ expectCounterItem(stats, "opcode.normal", 0);
+ expectCounterItem(stats, "opcode.other", 0);
checkAllRcodeCountersZeroExcept(Rcode::NOTAUTH(), 1);
}
@@ -1028,8 +1075,12 @@ TEST_F(AuthSrvTest,
// Submit UDP normal query and check query counter
TEST_F(AuthSrvTest, queryCounterUDPNormal) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_UDP_QUERY));
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics();
+ expectCounterItem(stats_init, "queries.udp", 0);
+ expectCounterItem(stats_init, "queries.tcp", 0);
+ expectCounterItem(stats_init, "opcode.query", 0);
+ expectCounterItem(stats_init, "rcode.refused", 0);
// Create UDP message and process.
UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
default_qid, Name("example.com"),
@@ -1037,18 +1088,25 @@ TEST_F(AuthSrvTest, queryCounterUDPNormal) {
createRequestPacket(request_message, IPPROTO_UDP);
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
- // After processing UDP query, the counter should be 1.
- EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_UDP_QUERY));
- // The counter for opcode Query should also be one
- EXPECT_EQ(1, server.getCounter(Opcode::QUERY()));
- // The counter for REFUSED responses should also be one, the rest zero
- checkAllRcodeCountersZeroExcept(Rcode::REFUSED(), 1);
+ // After processing the UDP query, these counters should be incremented:
+ // request.tcp, opcode.query, qtype.ns, rcode.refused, response
+ // and these counters should not be incremented:
+ // request.tcp
+ ConstElementPtr stats_after = server.getStatistics();
+ expectCounterItem(stats_after, "queries.udp", 1);
+ expectCounterItem(stats_after, "queries.tcp", 0);
+ expectCounterItem(stats_after, "opcode.query", 1);
+ expectCounterItem(stats_after, "rcode.refused", 1);
}
// Submit TCP normal query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPNormal) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics();
+ expectCounterItem(stats_init, "queries.udp", 0);
+ expectCounterItem(stats_init, "queries.tcp", 0);
+ expectCounterItem(stats_init, "opcode.query", 0);
+ expectCounterItem(stats_init, "rcode.refused", 0);
// Create TCP message and process.
UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
default_qid, Name("example.com"),
@@ -1056,18 +1114,24 @@ TEST_F(AuthSrvTest, queryCounterTCPNormal) {
createRequestPacket(request_message, IPPROTO_TCP);
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
- // After processing TCP query, the counter should be 1.
- EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
- // The counter for SUCCESS responses should also be one
- EXPECT_EQ(1, server.getCounter(Opcode::QUERY()));
- // The counter for REFUSED responses should also be one, the rest zero
- checkAllRcodeCountersZeroExcept(Rcode::REFUSED(), 1);
+ // After processing the TCP query, these counters should be incremented:
+ // request.tcp, opcode.query, qtype.ns, rcode.refused, response
+ // and these counters should not be incremented:
+ // request.udp
+ ConstElementPtr stats_after = server.getStatistics();
+ expectCounterItem(stats_after, "queries.udp", 0);
+ expectCounterItem(stats_after, "queries.tcp", 1);
+ expectCounterItem(stats_after, "opcode.query", 1);
+ expectCounterItem(stats_after, "rcode.refused", 1);
}
// Submit TCP AXFR query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics();
+ expectCounterItem(stats_init, "queries.udp", 0);
+ expectCounterItem(stats_init, "queries.tcp", 0);
+ expectCounterItem(stats_init, "opcode.query", 0);
UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Name("example.com"), RRClass::IN(), RRType::AXFR());
createRequestPacket(request_message, IPPROTO_TCP);
@@ -1076,16 +1140,24 @@ TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
- // After processing TCP AXFR query, the counter should be 1.
- EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
- // No rcodes should be incremented
- checkAllRcodeCountersZero();
+ // After processing the TCP AXFR query, these counters should be
+ // incremented:
+ // request.tcp, opcode.query, qtype.axfr
+ // and these counters should not be incremented:
+ // request.udp, response
+ ConstElementPtr stats_after = server.getStatistics();
+ expectCounterItem(stats_after, "queries.udp", 0);
+ expectCounterItem(stats_after, "queries.tcp", 1);
+ expectCounterItem(stats_after, "opcode.query", 1);
}
// Submit TCP IXFR query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics();
+ expectCounterItem(stats_init, "queries.udp", 0);
+ expectCounterItem(stats_init, "queries.tcp", 0);
+ expectCounterItem(stats_init, "opcode.query", 0);
UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Name("example.com"), RRClass::IN(), RRType::IXFR());
createRequestPacket(request_message, IPPROTO_TCP);
@@ -1094,14 +1166,24 @@ TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
- // After processing TCP IXFR query, the counter should be 1.
- EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+ // After processing the TCP IXFR query, these counters should be
+ // incremented:
+ // request.tcp, opcode.query, qtype.ixfr
+ // and these counters should not be incremented:
+ // request.udp, response
+ ConstElementPtr stats_after = server.getStatistics();
+ expectCounterItem(stats_after, "queries.udp", 0);
+ expectCounterItem(stats_after, "queries.tcp", 1);
+ expectCounterItem(stats_after, "opcode.query", 1);
}
TEST_F(AuthSrvTest, queryCounterOpcodes) {
- for (int i = 0; i < 16; ++i) {
+ // Check for 0..2, 3(=other), 4..5
+ // The counter should be initialized to 0.
+ for (int i = 0; i < 6; ++i) {
// The counter should be initialized to 0.
- EXPECT_EQ(0, server.getCounter(Opcode(i)));
+ expectCounterItem(server.getStatistics(),
+ QRCounterItemName[QROpCodeToQRCounterType[i]], 0);
// For each possible opcode, create a request message and send it
UnitTestUtil::createRequestMessage(request_message, Opcode(i),
@@ -1119,7 +1201,39 @@ TEST_F(AuthSrvTest, queryCounterOpcodes) {
}
// Confirm the counter.
- EXPECT_EQ(i + 1, server.getCounter(Opcode(i)));
+ expectCounterItem(server.getStatistics(),
+ QRCounterItemName[QROpCodeToQRCounterType[i]],
+ i + 1);
+ }
+ // Check for 6..15
+ // they are treated as the 'other' opcode
+ // the 'other' opcode counter is 4 at this point
+ int expected = 4;
+ for (int i = 6; i < 16; ++i) {
+ // The counter should be initialized to 0.
+ expectCounterItem(server.getStatistics(),
+ QRCounterItemName[QROpCodeToQRCounterType[i]],
+ expected);
+
+ // For each possible opcode, create a request message and send it
+ UnitTestUtil::createRequestMessage(request_message, Opcode(i),
+ default_qid, Name("example.com"),
+ RRClass::IN(), RRType::NS());
+ createRequestPacket(request_message, IPPROTO_UDP);
+
+ // "send" the request once
+ parse_message->clear(Message::PARSE);
+ server.processMessage(*io_message, *parse_message,
+ *response_obuffer,
+ &dnsserv);
+
+ // the 'other' opcode counter should be incremented
+ ++expected;
+
+ // Confirm the counter.
+ expectCounterItem(server.getStatistics(),
+ QRCounterItemName[QROpCodeToQRCounterType[i]],
+ expected);
}
}
diff --git a/src/bin/auth/tests/statistics_unittest.cc b/src/bin/auth/tests/statistics_unittest.cc
index d2f5a5a..a845aaa 100644
--- a/src/bin/auth/tests/statistics_unittest.cc
+++ b/src/bin/auth/tests/statistics_unittest.cc
@@ -27,345 +27,116 @@
#include <cc/session.h>
#include <auth/statistics.h>
+#include <auth/statistics_items.h>
#include <dns/tests/unittest_util.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
using namespace std;
using namespace isc::cc;
using namespace isc::dns;
using namespace isc::data;
+using isc::auth::statistics::Counters;
+using isc::auth::statistics::QRAttributes;
namespace {
-class AuthCountersTest : public ::testing::Test {
-private:
- class MockSession : public AbstractSession {
- public:
- MockSession() :
- // by default we return a simple "success" message.
- msg_(Element::fromJSON("{\"result\": [0, \"SUCCESS\"]}")),
- throw_session_error_(false), throw_session_timeout_(false)
- {}
- virtual void establish(const char* socket_file);
- virtual void disconnect();
- virtual int group_sendmsg(ConstElementPtr msg, string group,
- string instance, string to);
- virtual bool group_recvmsg(ConstElementPtr& envelope,
- ConstElementPtr& msg,
- bool nonblock, int seq);
- virtual void subscribe(string group, string instance);
- virtual void unsubscribe(string group, string instance);
- virtual void startRead(boost::function<void()> read_callback);
- virtual int reply(ConstElementPtr envelope, ConstElementPtr newmsg);
- virtual bool hasQueuedMsgs() const;
- virtual void setTimeout(size_t) {}
- virtual size_t getTimeout() const { return (0); };
-
- void setThrowSessionError(bool flag);
- void setThrowSessionTimeout(bool flag);
-
- void setMessage(ConstElementPtr msg) { msg_ = msg; }
-
- ConstElementPtr sent_msg;
- string msg_destination;
- private:
- ConstElementPtr msg_;
- bool throw_session_error_;
- bool throw_session_timeout_;
- };
-
+class CountersTest : public ::testing::Test {
protected:
- AuthCountersTest() : counters() {
- }
- ~AuthCountersTest() {
- }
- AuthCounters counters;
- // no need to be inherited from the original class here.
- class MockModuleSpec {
- public:
- bool validateStatistics(ConstElementPtr, const bool valid) const
- { return (valid); }
- };
- MockModuleSpec module_spec_;
+ CountersTest() : counters() {}
+ ~CountersTest() {}
+ Counters counters;
};
-void
-AuthCountersTest::MockSession::establish(const char*) {}
-
-void
-AuthCountersTest::MockSession::disconnect() {}
-
-void
-AuthCountersTest::MockSession::subscribe(string, string)
-{}
-
-void
-AuthCountersTest::MockSession::unsubscribe(string, string)
-{}
-
-void
-AuthCountersTest::MockSession::startRead(boost::function<void()>)
-{}
-
-int
-AuthCountersTest::MockSession::reply(ConstElementPtr, ConstElementPtr) {
- return (-1);
-}
-
-bool
-AuthCountersTest::MockSession::hasQueuedMsgs() const {
- return (false);
-}
-
-int
-AuthCountersTest::MockSession::group_sendmsg(ConstElementPtr msg,
- string group, string, string)
-{
- if (throw_session_error_) {
- isc_throw(SessionError, "Session Error");
- }
- sent_msg = msg;
- msg_destination = group;
- return (0);
-}
-
bool
-AuthCountersTest::MockSession::group_recvmsg(ConstElementPtr&,
- ConstElementPtr& msg, bool, int)
-{
- if (throw_session_timeout_) {
- isc_throw(SessionTimeout, "Session Timeout");
- }
- msg = msg_;
- return (true);
-}
-
-void
-AuthCountersTest::MockSession::setThrowSessionError(bool flag) {
- throw_session_error_ = flag;
-}
-
-void
-AuthCountersTest::MockSession::setThrowSessionTimeout(bool flag) {
- throw_session_timeout_ = flag;
-}
-
-TEST_F(AuthCountersTest, incrementUDPCounter) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
- EXPECT_NO_THROW(counters.inc(AuthCounters::SERVER_UDP_QUERY));
- // After increment, the counter should be 1.
- EXPECT_EQ(1, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
-}
-
-TEST_F(AuthCountersTest, incrementTCPCounter) {
- // The counter should be initialized to 0.
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
- EXPECT_NO_THROW(counters.inc(AuthCounters::SERVER_TCP_QUERY));
- // After increment, the counter should be 1.
- EXPECT_EQ(1, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
-}
-
-TEST_F(AuthCountersTest, incrementInvalidCounter) {
- // Expect to throw an isc::OutOfRange
- EXPECT_THROW(counters.inc(AuthCounters::SERVER_COUNTER_TYPES),
- isc::OutOfRange);
-}
-
-TEST_F(AuthCountersTest, incrementOpcodeCounter) {
- // The counter should be initialized to 0. If we increment it by 1
- // the counter should be 1.
- for (int i = 0; i < 16; ++i) {
- EXPECT_EQ(0, counters.getCounter(Opcode(i)));
- counters.inc(Opcode(i));
- EXPECT_EQ(1, counters.getCounter(Opcode(i)));
- }
-}
-
-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)));
- }
-}
-
-void
-opcodeDataCheck(ConstElementPtr data, const int expected[16]) {
- const char* item_names[] = {
- "query", "iquery", "status", "reserved3", "notify", "update",
- "reserved6", "reserved7", "reserved8", "reserved9", "reserved10",
- "reserved11", "reserved12", "reserved13", "reserved14", "reserved15",
- NULL
- };
- int i;
- for (i = 0; i < 16; ++i) {
- ASSERT_NE(static_cast<const char*>(NULL), item_names[i]);
- const string item_name = "opcode." + string(item_names[i]);
- if (expected[i] == 0) {
- EXPECT_FALSE(data->get(item_name));
- } else {
- EXPECT_EQ(expected[i], data->get(item_name)->intValue());
+checkCountersAllZeroExcept(const isc::data::ConstElementPtr counters,
+ const std::set<std::string>& except_for) {
+ std::map<std::string, ConstElementPtr> stats_map = counters->mapValue();
+
+ for (std::map<std::string, ConstElementPtr>::const_iterator
+ i = stats_map.begin(), e = stats_map.end();
+ i != e;
+ ++i)
+ {
+ int expect = 0;
+ if (except_for.count(i->first) != 0) {
+ expect = 1;
}
+ EXPECT_EQ(expect, i->second->intValue()) << "Expected counter "
+ << i->first << " = " << expect << ", actual: "
+ << i->second->intValue();
}
- // We should have examined all names
- 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]);
+ return false;
}
-TEST_F(AuthCountersTest, getStatisticsWithoutValidator) {
- // Get statistics data.
- // Validate if it answers correct data.
+TEST_F(CountersTest, incrementNormalQuery) {
+ Message response(Message::RENDER);
+ QRAttributes qrattrs;
+ std::set<std::string> expect_nonzero;
- // Counters should be initialized to 0.
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
+ expect_nonzero.clear();
+ checkCountersAllZeroExcept(counters.getStatistics(), expect_nonzero);
- // UDP query counter is set to 2.
- counters.inc(AuthCounters::SERVER_UDP_QUERY);
- counters.inc(AuthCounters::SERVER_UDP_QUERY);
- // TCP query counter is set to 1.
- counters.inc(AuthCounters::SERVER_TCP_QUERY);
- ConstElementPtr statistics_data = counters.getStatistics();
+ qrattrs.setQueryIPVersion(AF_INET6);
+ qrattrs.setQueryTransportProtocol(IPPROTO_UDP);
+ qrattrs.setQueryOpCode(Opcode::QUERY_CODE);
+ qrattrs.setQueryEDNS(true, false);
+ qrattrs.setQueryDO(true);
+ qrattrs.answerWasSent();
- // UDP query counter is 2 and TCP query counter is 1.
- EXPECT_EQ(2, statistics_data->get("queries.udp")->intValue());
- EXPECT_EQ(1, statistics_data->get("queries.tcp")->intValue());
+ response.setRcode(Rcode::REFUSED());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::AAAA()));
- // By default opcode counters are all 0 and omitted
- 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);
-}
+ counters.inc(qrattrs, response);
-void
-updateOpcodeCounters(AuthCounters &counters, const int expected[16]) {
- for (int i = 0; i < 16; ++i) {
- for (int j = 0; j < expected[i]; ++j) {
- counters.inc(Opcode(i));
- }
- }
+ expect_nonzero.clear();
+ expect_nonzero.insert("opcode.query");
+ expect_nonzero.insert("queries.udp");
+ expect_nonzero.insert("rcode.refused");
+ checkCountersAllZeroExcept(counters.getStatistics(), expect_nonzero);
}
-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(CountersTest, getStatistics) {
+ std::map<std::string, ConstElementPtr> stats_map =
+ counters.getStatistics()->mapValue();
+ for (std::map<std::string, ConstElementPtr>::const_iterator
+ i = stats_map.begin(), e = stats_map.end();
+ i != e;
+ ++i)
+ {
+ // item type check
+ EXPECT_NO_THROW(i->second->intValue())
+ << "Item " << i->first << " is not IntElement";
}
}
-TEST_F(AuthCountersTest, getStatisticsWithOpcodeCounters) {
- // Increment some of the opcode counters. Then they should appear in the
- // submitted data; others shouldn't
- const int opcode_results[16] = { 1, 2, 3, 0, 4, 5, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 };
- updateOpcodeCounters(counters, opcode_results);
- ConstElementPtr statistics_data = counters.getStatistics();
- opcodeDataCheck(statistics_data, opcode_results);
-}
-
-TEST_F(AuthCountersTest, getStatisticsWithAllOpcodeCounters) {
- // Increment all opcode counters. Then they should appear in the
- // submitted data.
- const int opcode_results[16] = { 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1 };
- updateOpcodeCounters(counters, opcode_results);
- ConstElementPtr statistics_data = counters.getStatistics();
- opcodeDataCheck(statistics_data, opcode_results);
+TEST(StatisticsItemsTest, QRItemNamesCheck) {
+ // check the number of elements in the array
+ EXPECT_EQ(sizeof(QRCounterItemName) / sizeof(QRCounterItemName[0]),
+ QR_COUNTER_TYPES);
+ // check the name of the first enum element
+ EXPECT_EQ(QRCounterItemName[QR_REQUEST_IPV4], "request.v4");
+ // check the name of the last enum element
+ EXPECT_EQ(QRCounterItemName[QR_RCODE_OTHER], "rcode.other");
}
-TEST_F(AuthCountersTest, getStatisticsWithRcodeCounters) {
- // Increment some of the rcode 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);
- ConstElementPtr statistics_data = counters.getStatistics();
- rcodeDataCheck(statistics_data, rcode_results);
+TEST(StatisticsItemsTest, SocketItemNamesCheck) {
+ // check the number of elements in the array
+ EXPECT_EQ(sizeof(SocketCounterItemName) / sizeof(SocketCounterItemName[0]),
+ SOCKET_COUNTER_TYPES);
+ // check the name of the first enum element
+ EXPECT_EQ(SocketCounterItemName[SOCKET_IPV4_UDP_BINDFAIL],
+ "ipv4.udp.bindfail");
+ // check the name of the last enum element
+ EXPECT_EQ(SocketCounterItemName[SOCKET_UNIXDOMAIN_SENDERR],
+ "unixdomain.senderr");
}
-TEST_F(AuthCountersTest, getStatisticsWithAllRcodeCounters) {
- // Increment all rcode 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);
- ConstElementPtr statistics_data = counters.getStatistics();
- opcodeDataCheck(statistics_data, rcode_results);
-}
-
-TEST_F(AuthCountersTest, getStatisticsWithValidator) {
-
- //a validator for the unittest
- AuthCounters::validator_type validator;
- ConstElementPtr el;
-
- // Get statistics data with correct statistics validator.
- validator = boost::bind(
- &AuthCountersTest::MockModuleSpec::validateStatistics,
- &module_spec_, _1, true);
-
- EXPECT_TRUE(validator(el));
-
- // register validator to AuthCounters
- counters.registerStatisticsValidator(validator);
-
- // Counters should be initialized to 0.
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
- EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
-
- // UDP query counter is set to 2.
- counters.inc(AuthCounters::SERVER_UDP_QUERY);
- counters.inc(AuthCounters::SERVER_UDP_QUERY);
- // TCP query counter is set to 1.
- counters.inc(AuthCounters::SERVER_TCP_QUERY);
-
- // checks the value returned by getStatistics
- ConstElementPtr statistics_data = counters.getStatistics();
-
- // UDP query counter is 2 and TCP query counter is 1.
- EXPECT_EQ(2, statistics_data->get("queries.udp")->intValue());
- EXPECT_EQ(1, statistics_data->get("queries.tcp")->intValue());
-
- // Get statistics data with incorrect statistics validator.
- validator = boost::bind(
- &AuthCountersTest::MockModuleSpec::validateStatistics,
- &module_spec_, _1, false);
-
- EXPECT_FALSE(validator(el));
-
- counters.registerStatisticsValidator(validator);
-
- // checks the value returned by getStatistics
- EXPECT_FALSE(counters.getStatistics());
-}
}
diff --git a/src/lib/statistics/Makefile.am b/src/lib/statistics/Makefile.am
index 206b527..e3543a2 100644
--- a/src/lib/statistics/Makefile.am
+++ b/src/lib/statistics/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = . tests
+SUBDIRS = tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG)
@@ -17,8 +17,4 @@ if USE_CLANGPP
AM_CXXFLAGS += -Wno-unused-parameter
endif
-lib_LTLIBRARIES = libb10-statistics.la
-libb10_statistics_la_SOURCES = counter.h counter.cc
-libb10_statistics_la_SOURCES += counter_dict.h counter_dict.cc
-
CLEANFILES = *.gcno *.gcda
diff --git a/src/lib/statistics/counter.cc b/src/lib/statistics/counter.cc
deleted file mode 100644
index 53dc58e..0000000
--- a/src/lib/statistics/counter.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <vector>
-
-#include <boost/noncopyable.hpp>
-
-#include <statistics/counter.h>
-
-namespace {
-const unsigned int InitialValue = 0;
-} // namespace
-
-namespace isc {
-namespace statistics {
-
-class CounterImpl : boost::noncopyable {
- private:
- std::vector<Counter::Value> counters_;
- public:
- CounterImpl(const size_t nelements);
- ~CounterImpl();
- void inc(const Counter::Type&);
- const Counter::Value& get(const Counter::Type&) const;
-};
-
-CounterImpl::CounterImpl(const size_t items) :
- counters_(items, InitialValue)
-{
- if (items == 0) {
- isc_throw(isc::InvalidParameter, "Items must not be 0");
- }
-}
-
-CounterImpl::~CounterImpl() {}
-
-void
-CounterImpl::inc(const Counter::Type& type) {
- if(type >= counters_.size()) {
- isc_throw(isc::OutOfRange, "Counter type is out of range");
- }
- ++counters_.at(type);
- return;
-}
-
-const Counter::Value&
-CounterImpl::get(const Counter::Type& type) const {
- if(type >= counters_.size()) {
- isc_throw(isc::OutOfRange, "Counter type is out of range");
- }
- return (counters_.at(type));
-}
-
-Counter::Counter(const size_t items) : impl_(new CounterImpl(items))
-{}
-
-Counter::~Counter() {}
-
-void
-Counter::inc(const Type& type) {
- impl_->inc(type);
- return;
-}
-
-const Counter::Value&
-Counter::get(const Type& type) const {
- return (impl_->get(type));
-}
-
-} // namespace statistics
-} // namespace isc
diff --git a/src/lib/statistics/counter.h b/src/lib/statistics/counter.h
index 9e467ce..ed5c276 100644
--- a/src/lib/statistics/counter.h
+++ b/src/lib/statistics/counter.h
@@ -15,24 +15,29 @@
#ifndef __COUNTER_H
#define __COUNTER_H 1
+#include <exceptions/exceptions.h>
+
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
-#include <exceptions/exceptions.h>
+#include <vector>
+
+namespace {
+const unsigned int InitialValue = 0;
+} // anonymous namespace
namespace isc {
namespace statistics {
-// forward declaration for pImpl idiom
-class CounterImpl;
-
class Counter : boost::noncopyable {
-private:
- boost::scoped_ptr<CounterImpl> impl_;
public:
typedef unsigned int Type;
typedef unsigned int Value;
+private:
+ std::vector<Counter::Value> counters_;
+
+public:
/// The constructor.
///
/// This constructor is mostly exception free. But it may still throw
@@ -41,29 +46,56 @@ public:
/// \param items A number of counter items to hold (greater than 0)
///
/// \throw isc::InvalidParameter \a items is 0
- Counter(const size_t items);
+ explicit inline Counter(const size_t items);
/// The destructor.
///
/// This method never throws an exception.
- ~Counter();
+ inline ~Counter();
/// \brief Increment a counter item specified with \a type.
///
/// \param type %Counter item to increment
///
/// \throw isc::OutOfRange \a type is invalid
- void inc(const Type& type);
+ inline void inc(const Counter::Type);
/// \brief Get the value of a counter item specified with \a type.
///
/// \param type %Counter item to get the value of
///
/// \throw isc::OutOfRange \a type is invalid
- const Value& get(const Type& type) const;
+ inline const Counter::Value& get(const Counter::Type) const;
};
+inline Counter::Counter(const size_t items) :
+ counters_(items, InitialValue)
+{
+ if (items == 0) {
+ isc_throw(isc::InvalidParameter, "Items must not be 0");
+ }
+}
+
+inline Counter::~Counter() {}
+
+inline void
+Counter::inc(const Counter::Type type) {
+ if(type >= counters_.size()) {
+ isc_throw(isc::OutOfRange, "Counter type is out of range");
+ }
+ ++counters_.at(type);
+ return;
+}
+
+inline const Counter::Value&
+Counter::get(const Counter::Type type) const {
+ if(type >= counters_.size()) {
+ isc_throw(isc::OutOfRange, "Counter type is out of range");
+ }
+ return (counters_.at(type));
+}
+
} // namespace statistics
} // namespace isc
-#endif
+#endif // __COUNTER_H
diff --git a/src/lib/statistics/counter_dict.cc b/src/lib/statistics/counter_dict.cc
deleted file mode 100644
index 55353b2..0000000
--- a/src/lib/statistics/counter_dict.cc
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <cassert>
-#include <stdexcept>
-#include <iterator>
-#include <map>
-#include <boost/noncopyable.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <statistics/counter_dict.h>
-
-namespace {
-typedef boost::shared_ptr<isc::statistics::Counter> CounterPtr;
-typedef std::map<std::string, CounterPtr> DictionaryMap;
-}
-
-namespace isc {
-namespace statistics {
-
-// Implementation detail class for CounterDictionary::ConstIterator
-class CounterDictionaryConstIteratorImpl;
-
-class CounterDictionaryImpl : boost::noncopyable {
-private:
- DictionaryMap dictionary_;
- std::vector<std::string> elements_;
- const size_t items_;
- // Default constructor is forbidden; number of counter items must be
- // specified at the construction of this class.
- CounterDictionaryImpl();
-public:
- CounterDictionaryImpl(const size_t items);
- ~CounterDictionaryImpl();
- void addElement(const std::string& name);
- void deleteElement(const std::string& name);
- Counter& getElement(const std::string& name);
-public:
- CounterDictionaryConstIteratorImpl begin() const;
- CounterDictionaryConstIteratorImpl end() const;
-};
-
-// Constructor with number of items
-CounterDictionaryImpl::CounterDictionaryImpl(const size_t items) :
- items_(items)
-{
- // The number of items must not be 0
- if (items == 0) {
- isc_throw(isc::InvalidParameter, "Items must not be 0");
- }
-}
-
-// Destructor
-CounterDictionaryImpl::~CounterDictionaryImpl() {}
-
-void
-CounterDictionaryImpl::addElement(const std::string& name) {
- // throw if the element already exists
- if (dictionary_.count(name) != 0) {
- isc_throw(isc::InvalidParameter,
- "Element " << name << " already exists");
- }
- assert(items_ != 0);
- // Create a new Counter and add to the map
- dictionary_.insert(
- DictionaryMap::value_type(name, CounterPtr(new Counter(items_))));
-}
-
-void
-CounterDictionaryImpl::deleteElement(const std::string& name) {
- size_t result = dictionary_.erase(name);
- if (result != 1) {
- // If an element with specified name does not exist, throw
- // isc::OutOfRange.
- isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
- }
-}
-
-Counter&
-CounterDictionaryImpl::getElement(const std::string& name) {
- DictionaryMap::const_iterator i = dictionary_.find(name);
- if (i != dictionary_.end()) {
- // the key was found. return the element.
- return (*(i->second));
- } else {
- // If an element with specified name does not exist, throw
- // isc::OutOfRange.
- isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
- }
-}
-
-// Constructor
-// Initialize impl_
-CounterDictionary::CounterDictionary(const size_t items) :
- impl_(new CounterDictionaryImpl(items))
-{}
-
-// Destructor
-// impl_ will be freed automatically with scoped_ptr
-CounterDictionary::~CounterDictionary() {}
-
-void
-CounterDictionary::addElement(const std::string& name) {
- impl_->addElement(name);
-}
-
-void
-CounterDictionary::deleteElement(const std::string& name) {
- impl_->deleteElement(name);
-}
-
-Counter&
-CounterDictionary::getElement(const std::string& name) const {
- return (impl_->getElement(name));
-}
-
-Counter&
-CounterDictionary::operator[](const std::string& name) const {
- return (impl_->getElement(name));
-}
-
-// Implementation detail class for CounterDictionary::ConstIterator
-class CounterDictionaryConstIteratorImpl {
- public:
- CounterDictionaryConstIteratorImpl();
- ~CounterDictionaryConstIteratorImpl();
- CounterDictionaryConstIteratorImpl(
- const CounterDictionaryConstIteratorImpl &other);
- CounterDictionaryConstIteratorImpl &operator=(
- const CounterDictionaryConstIteratorImpl &source);
- CounterDictionaryConstIteratorImpl(
- DictionaryMap::const_iterator iterator);
- public:
- void increment();
- const CounterDictionary::ConstIterator::value_type&
- dereference() const;
- bool equal(const CounterDictionaryConstIteratorImpl& other) const;
- private:
- DictionaryMap::const_iterator iterator_;
-};
-
-CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl() {}
-
-CounterDictionaryConstIteratorImpl::~CounterDictionaryConstIteratorImpl() {}
-
-// Copy constructor: deep copy of iterator_
-CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl(
- const CounterDictionaryConstIteratorImpl &other) :
- iterator_(other.iterator_)
-{}
-
-// Assignment operator: deep copy of iterator_
-CounterDictionaryConstIteratorImpl &
-CounterDictionaryConstIteratorImpl::operator=(
- const CounterDictionaryConstIteratorImpl &source)
-{
- iterator_ = source.iterator_;
- return (*this);
-}
-
-// Constructor from implementation detail DictionaryMap::const_iterator
-CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl(
- DictionaryMap::const_iterator iterator) :
- iterator_(iterator)
-{}
-
-CounterDictionaryConstIteratorImpl
-CounterDictionaryImpl::begin() const {
- return (CounterDictionaryConstIteratorImpl(dictionary_.begin()));
-}
-
-CounterDictionaryConstIteratorImpl
-CounterDictionaryImpl::end() const {
- return (CounterDictionaryConstIteratorImpl(dictionary_.end()));
-}
-
-void
-CounterDictionaryConstIteratorImpl::increment() {
- ++iterator_;
- return;
-}
-
-const CounterDictionary::ConstIterator::value_type&
-CounterDictionaryConstIteratorImpl::dereference() const {
- return (iterator_->first);
-}
-
-bool
-CounterDictionaryConstIteratorImpl::equal(
- const CounterDictionaryConstIteratorImpl& other) const
-{
- return (iterator_ == other.iterator_);
-}
-
-CounterDictionary::ConstIterator
-CounterDictionary::begin() const {
- return (CounterDictionary::ConstIterator(
- CounterDictionaryConstIteratorImpl(impl_->begin())));
-}
-
-CounterDictionary::ConstIterator
-CounterDictionary::end() const {
- return (CounterDictionary::ConstIterator(
- CounterDictionaryConstIteratorImpl(impl_->end())));
-}
-
-CounterDictionary::ConstIterator::ConstIterator() :
- impl_(new CounterDictionaryConstIteratorImpl())
-{}
-
-CounterDictionary::ConstIterator::~ConstIterator() {}
-
-// Copy constructor: deep copy of impl_
-CounterDictionary::ConstIterator::ConstIterator(
- const CounterDictionary::ConstIterator& source) :
- impl_(new CounterDictionaryConstIteratorImpl(*(source.impl_)))
-{}
-
-// Assignment operator: deep copy of impl_
-CounterDictionary::ConstIterator &
-CounterDictionary::ConstIterator::operator=(
- const CounterDictionary::ConstIterator &source)
-{
- *impl_ = *source.impl_;
- return (*this);
-}
-
-// The constructor from implementation detail
-CounterDictionary::ConstIterator::ConstIterator(
- const CounterDictionaryConstIteratorImpl& source) :
- impl_(new CounterDictionaryConstIteratorImpl(source))
-{}
-
-const CounterDictionary::ConstIterator::value_type&
-CounterDictionary::ConstIterator::dereference() const
-{
- return (impl_->dereference());
-}
-
-bool
-CounterDictionary::ConstIterator::equal(
- CounterDictionary::ConstIterator const& other) const
-{
- return (impl_->equal(*(other.impl_)));
-}
-
-void
-CounterDictionary::ConstIterator::increment() {
- impl_->increment();
- return;
-}
-
-} // namespace statistics
-} // namespace isc
diff --git a/src/lib/statistics/counter_dict.h b/src/lib/statistics/counter_dict.h
index e322119..3715fc2 100644
--- a/src/lib/statistics/counter_dict.h
+++ b/src/lib/statistics/counter_dict.h
@@ -15,67 +15,45 @@
#ifndef __COUNTER_DICT_H
#define __COUNTER_DICT_H 1
-#include <string>
-#include <vector>
-#include <utility>
+#include <statistics/counter.h>
+#include <exceptions/exceptions.h>
+
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
#include <boost/iterator/iterator_facade.hpp>
-#include <exceptions/exceptions.h>
-#include <statistics/counter.h>
+#include <cassert>
+#include <stdexcept>
+#include <string>
+#include <vector>
+#include <map>
+#include <iterator>
+#include <utility>
+
+namespace {
+typedef boost::shared_ptr<isc::statistics::Counter> CounterPtr;
+typedef std::map<std::string, CounterPtr> DictionaryMap;
+}
namespace isc {
namespace statistics {
-class CounterDictionaryImpl;
-class CounterDictionaryConstIteratorImpl;
-
class CounterDictionary : boost::noncopyable {
private:
- boost::scoped_ptr<CounterDictionaryImpl> impl_;
+ DictionaryMap dictionary_;
+ std::vector<std::string> elements_;
+ const size_t items_;
// Default constructor is forbidden; number of counter items must be
// specified at the construction of this class.
CounterDictionary();
public:
- /// The constructor.
- /// This constructor is mostly exception free. But it may still throw
- /// a standard exception if memory allocation fails inside the method.
- ///
- /// \param items A number of counter items to hold (greater than 0)
- ///
- /// \throw isc::InvalidParameter \a items is 0
- CounterDictionary(const size_t items);
-
- /// The destructor.
- ///
- /// This method never throws an exception.
- ~CounterDictionary();
-
- /// \brief Add an element
- ///
- /// \throw isc::InvalidParameter \a element already exists.
- ///
- /// \param name A name of the element to append
- void addElement(const std::string& name);
-
- /// \brief Delete
- ///
- /// \throw isc::OutOfRange \a element does not exist.
- ///
- /// \param name A name of the element to delete
- void deleteElement(const std::string& name);
-
- /// \brief Lookup
- ///
- /// \throw isc::OutOfRange \a element does not exist.
- ///
- /// \param name A name of the element to get the counters
- Counter& getElement(const std::string &name) const;
-
- /// Same as getElement()
- Counter& operator[](const std::string &name) const;
-
+ explicit inline CounterDictionary(const size_t items);
+ inline ~CounterDictionary();
+ inline void addElement(const std::string& name);
+ inline void deleteElement(const std::string& name);
+ inline Counter& getElement(const std::string& name);
+ inline Counter& operator[](const std::string& name);
/// \brief \c ConstIterator is a constant iterator that provides an
/// interface for enumerating name of zones stored in CounterDictionary.
///
@@ -90,68 +68,134 @@ public:
const std::string,
boost::forward_traversal_tag>
{
- private:
- boost::scoped_ptr<CounterDictionaryConstIteratorImpl> impl_;
public:
/// The constructor.
///
/// This constructor is mostly exception free. But it may still
/// throw a standard exception if memory allocation fails
/// inside the method.
- ConstIterator();
+ inline ConstIterator() {}
/// The destructor.
///
/// This method never throws an exception.
- ~ConstIterator();
+ inline ~ConstIterator() {}
/// The assignment operator.
///
/// This method is mostly exception free. But it may still
/// throw a standard exception if memory allocation fails
/// inside the method.
- ConstIterator& operator=(const ConstIterator &source);
+ inline ConstIterator& operator=(const ConstIterator& source) {
+ iterator_ = source.iterator_;
+ return (*this);
+ }
+
/// The copy constructor.
///
/// This constructor is mostly exception free. But it may still
/// throw a standard exception if memory allocation fails
/// inside the method.
- ConstIterator(const ConstIterator& source);
- /// The constructor from implementation detail.
- ///
- /// This method is used to create an instance of ConstIterator
- /// by CounterDict::begin() and CounterDict::end().
- ///
- /// This constructor is mostly exception free. But it may still
- /// throw a standard exception if memory allocation fails
- /// inside the method.
- ConstIterator(
- const CounterDictionaryConstIteratorImpl& source);
+ inline ConstIterator(const ConstIterator& source) :
+ iterator_(source.iterator_)
+ {}
+ //
+ // Constructor from implementation detail DictionaryMap::const_iterator
+ inline ConstIterator(
+ DictionaryMap::const_iterator iterator) :
+ iterator_(iterator)
+ {}
+
private:
/// \brief An internal method to increment this iterator.
- void increment();
+ inline void increment() {
+ ++iterator_;
+ return;
+ }
+
/// \brief An internal method to check equality.
- bool equal(const ConstIterator& other) const;
+ inline bool equal(const ConstIterator& other) const {
+ return (iterator_ == other.iterator_);
+ }
+
/// \brief An internal method to dereference this iterator.
- const value_type& dereference() const;
+ inline const value_type& dereference() const {
+ return (iterator_->first);
+ }
+
private:
friend class boost::iterator_core_access;
+ DictionaryMap::const_iterator iterator_;
};
+ inline ConstIterator begin() const;
+ inline ConstIterator end() const;
+
typedef ConstIterator const_iterator;
+};
- /// \brief Return an iterator corresponding to the beginning of the
- /// elements stored in CounterDictionary.
- ///
- /// This method is mostly exception free. But it may still throw a
- /// standard exception if memory allocation fails inside the method.
- const_iterator begin() const;
- /// \brief Return an iterator corresponding to the end of the elements
- /// stored in CounterDictionary.
- ///
- /// This method is mostly exception free. But it may still throw a
- /// standard exception if memory allocation fails inside the method.
- const_iterator end() const;
-};
+inline CounterDictionary::ConstIterator
+CounterDictionary::begin() const {
+ return (CounterDictionary::ConstIterator(dictionary_.begin()));
+}
+
+inline CounterDictionary::ConstIterator
+CounterDictionary::end() const {
+ return (CounterDictionary::ConstIterator(dictionary_.end()));
+}
+
+// Constructor with number of items
+inline CounterDictionary::CounterDictionary(const size_t items) :
+ items_(items)
+{
+ // The number of items must not be 0
+ if (items == 0) {
+ isc_throw(isc::InvalidParameter, "Items must not be 0");
+ }
+}
+
+// Destructor
+inline CounterDictionary::~CounterDictionary() {}
+
+inline void
+CounterDictionary::addElement(const std::string& name) {
+ // throw if the element already exists
+ if (dictionary_.count(name) != 0) {
+ isc_throw(isc::InvalidParameter,
+ "Element " << name << " already exists");
+ }
+ assert(items_ != 0);
+ // Create a new Counter and add to the map
+ dictionary_.insert(
+ DictionaryMap::value_type(name, CounterPtr(new Counter(items_))));
+}
+
+inline void
+CounterDictionary::deleteElement(const std::string& name) {
+ size_t result = dictionary_.erase(name);
+ if (result != 1) {
+ // If an element with specified name does not exist, throw
+ // isc::OutOfRange.
+ isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
+ }
+}
+
+inline Counter&
+CounterDictionary::getElement(const std::string& name) {
+ DictionaryMap::const_iterator i = dictionary_.find(name);
+ if (i != dictionary_.end()) {
+ // the key was found. return the element.
+ return (*(i->second));
+ } else {
+ // If an element with specified name does not exist, throw
+ // isc::OutOfRange.
+ isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
+ }
+}
+
+inline Counter&
+CounterDictionary::operator[](const std::string& name) {
+ return (getElement(name));
+}
} // namespace statistics
} // namespace isc
diff --git a/src/lib/statistics/tests/Makefile.am b/src/lib/statistics/tests/Makefile.am
index 007c8b0..25a3db2 100644
--- a/src/lib/statistics/tests/Makefile.am
+++ b/src/lib/statistics/tests/Makefile.am
@@ -28,7 +28,6 @@ run_unittests_SOURCES += counter_dict_unittest.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDADD = $(GTEST_LDADD)
-run_unittests_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
run_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
More information about the bind10-changes
mailing list