BIND 10 trac2157_2, updated. 4c3dc79c413854edcf660874f8bd58d626b808c8 [2157] add ChangeLog
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Nov 22 05:54:13 UTC 2012
The branch, trac2157_2 has been updated
via 4c3dc79c413854edcf660874f8bd58d626b808c8 (commit)
via 9b47527a3fd00d3504dbdecc5e6b073834825c66 (commit)
via db2a410da1fb7553909b47ddbc7ce34456081f47 (commit)
via efbe16c46b234712eaa7629ffda12b1a906542af (commit)
via 4d9785cd658ba91b5f01c90c1855d239596c5f53 (commit)
via 7d02b9cc8837e089433be66f7973ba578e72ee39 (commit)
via 91a81c3b9a1ed47103c00e50fe3d141a2e9929b9 (commit)
via ab7f77f9ea18ce289ccc7484c4a40dc73548bca0 (commit)
via cb5a5f6e3c043b2f94884f5cb9101b661a084fc6 (commit)
via d5d8fa746c2cb23166e93f76423ae7ca645ef6a3 (commit)
via 3e2516ee09187b5c9af57e0cd6552bb298ebf02d (commit)
via 8c169e9a6032d69dd852f49d567eda1ecd7de706 (commit)
via a1107af9f039334d628220553229476beb41143f (commit)
via a0f35ebd59dee9b3f9b87c6b16d9185766f1d1be (commit)
via 6f61065e702d8ccd5b3b2da2c5e07803270ed120 (commit)
via a44025da797abe06f2d1b1a7de98f68b37e0c5d4 (commit)
via 34dd2565e959d9307cd17a1664d514ba76b68e24 (commit)
via 50c6b204fe5c51af7bed0f5538b8d6817b654a24 (commit)
via 5abc52b3f407f042b7fd189aa42a6a23228c0be7 (commit)
via 92cf23f15e80e32f2983eb69d7c5ca13c336ebc4 (commit)
from 7a821cf7fe79d72a294053865a65fe52b29394ee (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 -----------------------------------------------------------------
commit 4c3dc79c413854edcf660874f8bd58d626b808c8
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Thu Nov 22 14:53:22 2012 +0900
[2157] add ChangeLog
commit 9b47527a3fd00d3504dbdecc5e6b073834825c66
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Thu Nov 22 14:46:21 2012 +0900
[2157] update systest
commit db2a410da1fb7553909b47ddbc7ce34456081f47
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Thu Nov 22 13:05:31 2012 +0900
[2157] update lettuce feature
commit efbe16c46b234712eaa7629ffda12b1a906542af
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Wed Nov 21 21:57:03 2012 +0900
[2157] add testcase
commit 4d9785cd658ba91b5f01c90c1855d239596c5f53
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Wed Nov 21 21:48:17 2012 +0900
[2157] corrected condition for "request.badednsver"
commit 7d02b9cc8837e089433be66f7973ba578e72ee39
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Tue Nov 20 20:28:32 2012 +0900
[2157] add testcase
commit 91a81c3b9a1ed47103c00e50fe3d141a2e9929b9
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Mon Nov 19 17:00:28 2012 +0900
[2157] use ADD_FAILURE instead of ASSERT_FALSE("string")
commit ab7f77f9ea18ce289ccc7484c4a40dc73548bca0
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Mon Nov 19 16:11:30 2012 +0900
[2157] opcode is unsigned
commit cb5a5f6e3c043b2f94884f5cb9101b661a084fc6
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Mon Nov 19 15:56:52 2012 +0900
[2157] corrected conditions for compound attributes
commit d5d8fa746c2cb23166e93f76423ae7ca645ef6a3
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Mon Nov 19 15:26:57 2012 +0900
[2157] renamed statistics items generator
commit 3e2516ee09187b5c9af57e0cd6552bb298ebf02d
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Mon Nov 19 15:18:54 2012 +0900
[2157] add notes for fillNodes
commit 8c169e9a6032d69dd852f49d567eda1ecd7de706
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Mon Nov 19 14:51:16 2012 +0900
[2157] add description for CounterSpec
commit a1107af9f039334d628220553229476beb41143f
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Mon Nov 19 13:36:24 2012 +0900
[2157] renamed CounterTypeTree to CounterSpec
commit a0f35ebd59dee9b3f9b87c6b16d9185766f1d1be
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Mon Nov 19 13:25:59 2012 +0900
[2157] add documentation
commit 6f61065e702d8ccd5b3b2da2c5e07803270ed120
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Mon Nov 19 11:03:49 2012 +0900
[2157] remove per-zone statistics code
commit a44025da797abe06f2d1b1a7de98f68b37e0c5d4
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Fri Nov 16 19:49:09 2012 +0900
[2157] use std::bitset, add notes
commit 34dd2565e959d9307cd17a1664d514ba76b68e24
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Fri Nov 16 19:18:41 2012 +0900
[2157] add getter method
commit 50c6b204fe5c51af7bed0f5538b8d6817b654a24
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Fri Nov 16 18:11:42 2012 +0900
[2157] renamed according to coding style, moved to anonymous namespace
commit 5abc52b3f407f042b7fd189aa42a6a23228c0be7
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Fri Nov 16 16:41:12 2012 +0900
[2157] use a constant instead of a magic number, typo fix
commit 92cf23f15e80e32f2983eb69d7c5ca13c336ebc4
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date: Fri Nov 16 15:01:57 2012 +0900
[2157] rename following the naming policy
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 8 +
configure.ac | 3 +-
src/bin/auth/Makefile.am | 26 +-
src/bin/auth/auth_srv.cc | 21 +-
...ems.py.pre.in => gen-statisticsitems.py.pre.in} | 118 +++-
src/bin/auth/statistics.cc.pre | 236 +++----
src/bin/auth/statistics.h | 183 ++++--
src/bin/auth/statistics_items.h.pre | 16 +-
src/bin/auth/statistics_msg_items.def | 48 ++
src/bin/auth/statistics_qr_items.def | 48 --
src/bin/auth/tests/auth_srv_unittest.cc | 322 ++++++++--
src/bin/auth/tests/statistics_unittest.cc.pre | 658 ++++++++++++++++++--
.../configurations/example.org.inmem.config | 3 +
tests/lettuce/features/queries.feature | 501 ++++++++++++++-
tests/lettuce/features/terrain/bind10_control.py | 18 +-
tests/system/bindctl/tests.sh | 109 ++--
16 files changed, 1913 insertions(+), 405 deletions(-)
rename src/bin/auth/{gen-statistics_items.py.pre.in => gen-statisticsitems.py.pre.in} (68%)
create mode 100644 src/bin/auth/statistics_msg_items.def
delete mode 100644 src/bin/auth/statistics_qr_items.def
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 84d4378..6838bc7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+TBD. [func] y-aharen
+ Added statistics items in b10-auth based on
+ http://bind10.isc.org/wiki/StatisticsItems. Qtype counters are
+ dropped as it requires further spec design discussion.
+ (Trac #2154, Trac #2155,
+ git 61d7c3959eb991b22bc1c0ef8f4ecb96b65d9325)
+ (Trac #2157, git TBD)
+
482. [func] team
Memory footprint of the in-memory data source has been
substantially improved. For example, b10-auth now requires much
diff --git a/configure.ac b/configure.ac
index 2241067..2d294eb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1279,7 +1279,7 @@ AC_OUTPUT([doc/version.ent
src/bin/msgq/run_msgq.sh
src/bin/auth/auth.spec.pre
src/bin/auth/spec_config.h.pre
- src/bin/auth/gen-statistics_items.py.pre
+ src/bin/auth/gen-statisticsitems.py.pre
src/bin/dhcp4/spec_config.h.pre
src/bin/dhcp6/spec_config.h.pre
src/bin/tests/process_rename_test.py
@@ -1342,7 +1342,6 @@ AC_OUTPUT([doc/version.ent
chmod +x src/bin/usermgr/run_b10-cmdctl-usermgr.sh
chmod +x src/bin/msgq/run_msgq.sh
chmod +x src/bin/msgq/tests/msgq_test
- chmod +x src/bin/auth/gen-statistics_items.py.pre
chmod +x src/lib/dns/gen-rdatacode.py
chmod +x src/lib/log/tests/console_test.sh
chmod +x src/lib/log/tests/destination_test.sh
diff --git a/src/bin/auth/Makefile.am b/src/bin/auth/Makefile.am
index 1362498..df9a354 100644
--- a/src/bin/auth/Makefile.am
+++ b/src/bin/auth/Makefile.am
@@ -18,8 +18,8 @@ pkglibexecdir = $(libexecdir)/@PACKAGE@
CLEANFILES = *.gcno *.gcda auth.spec spec_config.h
CLEANFILES += auth_messages.h auth_messages.cc
-CLEANFILES += gen-statistics_items.py
-# auto-generated by gen-statistics_items.py
+CLEANFILES += gen-statisticsitems.py
+# auto-generated by gen-statisticsitems.py
CLEANFILES += statistics.cc statistics_items.h b10-auth.xml tests/statistics_unittest.cc
man_MANS = b10-auth.8
@@ -39,18 +39,18 @@ $(man_MANS):
endif
-auth.spec: auth.spec.pre statistics_qr_items.def
-b10-auth.xml: b10-auth.xml.pre statistics_qr_items.def
-statistics_items.h: statistics_items.h.pre statistics_qr_items.def
-statistics.cc: statistics.cc.pre statistics_qr_items.def
-tests/statistics_unittest.cc: tests/statistics_unittest.cc.pre statistics_qr_items.def
+auth.spec: auth.spec.pre statistics_msg_items.def
+b10-auth.xml: b10-auth.xml.pre statistics_msg_items.def
+statistics_items.h: statistics_items.h.pre statistics_msg_items.def
+statistics.cc: statistics.cc.pre statistics_msg_items.def
+tests/statistics_unittest.cc: tests/statistics_unittest.cc.pre statistics_msg_items.def
-gen-statistics_items.py: gen-statistics_items.py.pre
- $(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" gen-statistics_items.py.pre >$@
+gen-statisticsitems.py: gen-statisticsitems.py.pre
+ $(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" gen-statisticsitems.py.pre >$@
chmod +x $@
-auth.spec b10-auth.xml statistics_items.h statistics.cc tests/statistics_unittest.cc: Makefile gen-statistics_items.py
- ./gen-statistics_items.py
+auth.spec b10-auth.xml statistics_items.h statistics.cc tests/statistics_unittest.cc: Makefile gen-statisticsitems.py
+ ./gen-statisticsitems.py
spec_config.h: spec_config.h.pre
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
@@ -59,7 +59,7 @@ auth_messages.h auth_messages.cc: auth_messages.mes
$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/bin/auth/auth_messages.mes
BUILT_SOURCES = spec_config.h auth_messages.h auth_messages.cc
-# auto-generated by gen-statistics_items.py
+# auto-generated by gen-statisticsitems.py
BUILT_SOURCES += statistics_items.h statistics.cc
pkglibexec_PROGRAMS = b10-auth
@@ -76,7 +76,7 @@ b10_auth_SOURCES += main.cc
nodist_b10_auth_SOURCES = auth_messages.h auth_messages.cc
nodist_b10_auth_SOURCES += statistics.cc statistics_items.h
EXTRA_DIST += auth_messages.mes
-EXTRA_DIST += statistics_qr_items.def
+EXTRA_DIST += statistics_msg_items.def
EXTRA_DIST += b10-auth.xml.pre
EXTRA_DIST += statistics_items.h.pre statistics.cc.pre
EXTRA_DIST += tests/statistics_unittest.cc.pre
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index 5c3de37..74c2984 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -83,7 +83,7 @@ using namespace isc::asiolink;
using namespace isc::asiodns;
using namespace isc::server_common::portconfig;
using isc::auth::statistics::Counters;
-using isc::auth::statistics::QRAttributes;
+using isc::auth::statistics::MessageAttributes;
namespace {
// A helper class for cleaning up message renderer.
@@ -272,8 +272,8 @@ public:
std::map<RRClass, boost::shared_ptr<ConfigurableClientList> >
client_lists_;
- /// Query / Response attributes
- QRAttributes stats_attrs_;
+ /// Message attributes
+ MessageAttributes stats_attrs_;
boost::shared_ptr<ConfigurableClientList> getClientList(const RRClass&
rrclass)
@@ -494,9 +494,9 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
{
InputBuffer request_buffer(io_message.getData(), io_message.getDataSize());
- impl_->stats_attrs_.setQueryIPVersion(
+ impl_->stats_attrs_.setRequestIPVersion(
io_message.getRemoteEndpoint().getFamily());
- impl_->stats_attrs_.setQueryTransportProtocol(
+ impl_->stats_attrs_.setRequestTransportProtocol(
io_message.getRemoteEndpoint().getProtocol());
// First, check the header part. If we fail even for the base header,
@@ -553,8 +553,8 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
**impl_->keyring_));
tsig_error = tsig_context->verify(tsig_record, io_message.getData(),
io_message.getDataSize());
- impl_->stats_attrs_.setQuerySig(true, false,
- tsig_error != TSIGError::NOERROR());
+ impl_->stats_attrs_.setRequestSig(true, false,
+ tsig_error != TSIGError::NOERROR());
}
if (tsig_error != TSIGError::NOERROR()) {
@@ -570,13 +570,12 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
// note: This can only be reliable after TSIG check succeeds.
ConstEDNSPtr edns = message.getEDNS();
if (edns) {
- impl_->stats_attrs_.setQueryEDNS(edns->getVersion() == 0,
- edns->getVersion() != 0);
- impl_->stats_attrs_.setQueryDO(edns->getDNSSECAwareness());
+ impl_->stats_attrs_.setRequestEDNS0(true);
+ impl_->stats_attrs_.setRequestDO(edns->getDNSSECAwareness());
}
// note: This can only be reliable after TSIG check succeeds.
- impl_->stats_attrs_.setQueryOpCode(opcode.getCode());
+ impl_->stats_attrs_.setRequestOpCode(opcode.getCode());
if (opcode == Opcode::NOTIFY()) {
send_answer = impl_->processNotify(io_message, message, buffer,
diff --git a/src/bin/auth/gen-statistics_items.py.pre.in b/src/bin/auth/gen-statistics_items.py.pre.in
deleted file mode 100755
index 816e426..0000000
--- a/src/bin/auth/gen-statistics_items.py.pre.in
+++ /dev/null
@@ -1,279 +0,0 @@
-#!@PYTHON@
-
-# 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.
-
-import os
-import re
-import sys
-import json
-from xml.etree import ElementTree
-
-item_list = []
-localstatedir = '@@LOCALSTATEDIR@@'
-builddir = '@builddir@'
-srcdir = '@srcdir@'
-pre_suffix = '.pre'
-
-xmldocument_command_name = 'b10-auth'
-
-def need_generate(filepath, mtime):
- '''Check if we need to generate the specified file.
-
- To avoid unnecessary compilation, we skip (re)generating the file when
- the file already exists and newer than the base file.
- '''
- if os.path.exists(filepath) and\
- (os.path.getmtime(filepath) > mtime or
- os.path.getmtime(filepath) > os.path.getmtime(filepath+pre_suffix)):
- return False
- return True
-
-def import_definitions():
- global item_list
-
- items_definition_file = srcdir + os.sep + 'statistics_qr_items.def'
- item_definition = open(items_definition_file, 'r')
-
- re_splitter = re.compile('\t+')
- l = item_list
- lp = None
- for line in item_definition.readlines():
- element = re_splitter.split(line.rstrip())
- if element[0] == '':
- element.pop(0)
-
- if element[-1] == '=':
- l.append({'name': element[0], 'child': [], 'index': element[1],
- 'description': element[2], 'parent': lp})
- lp = l
- l = l[-1]['child']
- elif element[-1] == ';':
- l = lp
- lp = l[-1]['parent']
- else:
- l.append({'name': element[0], 'child': None, 'index': element[1],
- 'description': element[2], 'parent': lp})
-
- item_definition.close()
- return os.path.getmtime(items_definition_file)
-
-def generate_specfile(specfile, def_mtime):
- global item_list
-
- def convert_list(items, prefix = ''):
- spec_list = []
- default_map = {}
- for item in items:
- full_item_name = prefix + item['name']
- if item['child'] is None:
- default_map[item['name']] = 0
- spec_list.append({
- 'item_name': item['name'],
- 'item_optional': False,
- 'item_type': 'integer',
- 'item_default': 0,
- 'item_title': full_item_name,
- 'item_description': item['description'],
- })
- else:
- child_spec_list, child_default_map = \
- convert_list(item['child'], full_item_name + '.')
- spec_list.append({
- 'item_name': item['name'],
- 'item_type': 'map',
- 'item_optional': False,
- 'item_title': full_item_name,
- 'item_description': item['description'],
- 'item_default': child_default_map,
- 'map_item_spec': child_spec_list,
- })
- default_map[item['name']] = child_default_map
- return spec_list, default_map
-
- item_spec_list, item_default_map = convert_list(item_list)
-
- statistics_spec_list = [{
- 'item_name': 'zones',
- 'item_type': 'named_set',
- 'item_optional': False,
- 'item_title': 'Zone statistics',
- 'item_description':
- 'Zone statistics items. ' +
- "Items for all zones are stored in '_SERVER_'.",
- 'item_default': { '_SERVER_': item_default_map },
- 'named_set_item_spec': {
- 'item_name': 'zone',
- 'item_type': 'map',
- 'item_optional': False,
- 'item_default': {},
- 'map_item_spec': item_spec_list,
- },
- }]
-
- if need_generate(builddir+os.sep+specfile, def_mtime):
- stats_pre = open(builddir+os.sep+specfile+pre_suffix, 'r')
- stats_pre_json = json.loads(stats_pre.read().replace('@@LOCAL'+'STATEDIR@@',
- localstatedir))
- stats_pre.close()
- stats_pre_json['module_spec']['statistics'] = statistics_spec_list
- statistics_spec_json = json.dumps(stats_pre_json, sort_keys = True,
- indent = 2)
- stats_spec = open(builddir+os.sep+specfile, 'w')
- stats_spec.write(statistics_spec_json)
- stats_spec.close()
- else:
- print('skip generating ' + specfile)
- return
-
-def generate_docfile(docfile, def_mtime):
- global item_list
-
- def convert_list(items, tree, prefix = ''):
- for item in items:
- full_item_name = prefix + item['name']
- if item['child'] is None:
- child_element = ElementTree.SubElement(tree, 'varlistentry')
- term = ElementTree.SubElement(child_element, 'term')
- term.text = full_item_name
- list_item = ElementTree.SubElement(child_element, 'listitem')
- sim_para = ElementTree.SubElement(list_item, 'simpara')
- sim_para.text = ''
- prev = None
- for word in item['description'].split():
- if word == xmldocument_command_name:
- command = ElementTree.SubElement(sim_para, 'command')
- command.text = word
- para_tail = command
- command.tail = ' '
- prev = command
- else:
- if prev is None:
- sim_para.text += word + ' '
- else:
- prev.tail += word + ' '
- else:
- convert_list(item['child'], tree, full_item_name + '.')
- return
-
- if need_generate(builddir+os.sep+docfile, def_mtime):
- doc_pre = open(srcdir+os.sep+docfile+pre_suffix, 'r')
- doc_pre_xml = doc_pre.read().replace('@@LOCAL'+'STATEDIR@@',
- localstatedir)
- doc_pre.close
-
- variable_tree = ElementTree.Element('variablelist')
- convert_list(item_list, variable_tree)
- doc = open(builddir+os.sep+docfile, 'w')
- doc.write(doc_pre_xml.replace(
- '<!-- ### STATISTICS DATA PLACEHOLDER ### -->',
- str(ElementTree.tostring(variable_tree))))
- doc.close()
- else:
- print('skip generating ' + docfile)
- return
-
-def generate_cxx(itemsfile, ccfile, utfile, def_mtime):
- global item_list
-
- qr_counter_types = 'enum QRCounterType {\n'
- item_names = []
-
- def convert_list(items, qr_counter_types, item_names_current, item_names):
- for item in items:
- if item['child'] is None:
- qr_counter_types += ' ' + item['index'] + ', ' +\
- '///< ' + item['description'] + '\n'
- item_names_current.append(' { "' + item['name'] +
- '", NULL, ' + item['index'] + ' },\n'
- )
- else:
- item_names_current_ = ['const struct CounterTypeTree ' +
- item['index'] + '[] = {\n']
- qr_counter_types, item_names_current_, item_names = \
- convert_list(item['child'], qr_counter_types,
- item_names_current_, item_names)
- item_names_current_.append(' { NULL, NULL, -1 }\n' +
- '};\n')
- item_names.extend(item_names_current_)
- item_names_current.append(' { "' + item['name'] + '", ' +
- item['index'] + ', -1 },\n')
- return qr_counter_types, item_names_current, item_names
-
- qr_counter_types, item_names_current, item_names = \
- convert_list(item_list, qr_counter_types, [], item_names)
- item_names.append('const struct CounterTypeTree QRCounterTree[] = {\n')
- item_names.extend(item_names_current)
- item_names.append(' { NULL, NULL, -1 }\n' +
- '};\n')
-
- qr_counter_types += \
- ' // End of counter types\n' +\
- ' QR_COUNTER_TYPES ///< The number of defined counters\n' +\
- '};\n'
-
- item_defs = qr_counter_types
- item_decls = ''.join(item_names)
-
- if need_generate(builddir+os.sep+itemsfile, def_mtime):
- statistics_items_h_pre = open(srcdir+os.sep+itemsfile+pre_suffix, 'r')
- items_pre = statistics_items_h_pre.read()
- statistics_items_h_pre.close
-
- statistics_items_h = open(builddir+os.sep+itemsfile, 'w')
- statistics_items_h.write(items_pre.replace(
- '// ### STATISTICS ITEMS DECLARATION ###', item_defs))
- statistics_items_h.close()
- else:
- print('skip generating ' + itemsfile)
-
- if need_generate(builddir+os.sep+ccfile, def_mtime):
- statistics_cc_pre = open(srcdir+os.sep+ccfile+pre_suffix, 'r')
- items_pre = statistics_cc_pre.read()
- statistics_cc_pre.close
-
- statistics_cc = open(builddir+os.sep+ccfile, 'w')
- statistics_cc.write(items_pre.replace(
- '// ### STATISTICS ITEMS DEFINITION ###', item_decls))
- statistics_cc.close()
- else:
- print('skip generating ' + ccfile)
-
- if need_generate(builddir+os.sep+utfile, def_mtime):
- statistics_ut_cc_pre = open(srcdir+os.sep+utfile+pre_suffix, 'r')
- items_pre = statistics_ut_cc_pre.read()
- statistics_ut_cc_pre.close
-
- statistics_ut_cc = open(builddir+os.sep+utfile, 'w')
- statistics_ut_cc.write(items_pre.replace(
- '// ### STATISTICS ITEMS DEFINITION ###', item_decls))
- statistics_ut_cc.close()
- else:
- print('skip generating ' + utfile)
-
- return
-
-if __name__ == "__main__":
- try:
- def_mtime = import_definitions()
- generate_specfile('auth.spec', def_mtime)
- generate_docfile('b10-auth.xml', def_mtime)
- generate_cxx('statistics_items.h',
- 'statistics.cc',
- 'tests'+os.sep+'statistics_unittest.cc',
- def_mtime)
- except:
- sys.stderr.write('Code generation failed due to exception: %s\n' %
- sys.exc_info()[1])
- exit(1)
diff --git a/src/bin/auth/gen-statisticsitems.py.pre.in b/src/bin/auth/gen-statisticsitems.py.pre.in
new file mode 100755
index 0000000..5908554
--- /dev/null
+++ b/src/bin/auth/gen-statisticsitems.py.pre.in
@@ -0,0 +1,343 @@
+#!@PYTHON@
+
+# 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.
+
+"""\
+This script generates spec file, docbook XML and some part of statistics code
+from statistics_msg_items.def.
+"""
+
+import os
+import re
+import sys
+import json
+from xml.etree import ElementTree
+
+item_list = []
+localstatedir = '@@LOCALSTATEDIR@@'
+builddir = '@builddir@'
+srcdir = '@srcdir@'
+pre_suffix = '.pre'
+
+xmldocument_command_name = 'b10-auth'
+
+def need_generate(filepath, mtime):
+ '''Check if we need to generate the specified file.
+
+ To avoid unnecessary compilation, we skip (re)generating the file when
+ the file already exists and newer than the base file, and definition file
+ specified with mtime.
+ '''
+ if os.path.exists(filepath) and\
+ (os.path.getmtime(filepath) > mtime and
+ os.path.getmtime(filepath) > os.path.getmtime(filepath+pre_suffix)):
+ return False
+ return True
+
+def import_definitions():
+ '''Load statsitics items definitions from statistics_msg_items.def.
+
+ statistics_msg_items.def defines a tree of message statistics items.
+ Syntax:
+ Each line describes a node; branch node for subset of counters,
+ leaf node for a counter item.
+ Each fields are separated with one or more field separator (Tab).
+ Field separator in the head of a line is ignored.
+
+ branch node:
+ (item name)\t+(internal branch name)\t+(description of the item)\t+'='
+ leaf node:
+ (item name)\t+(internal item counter name)\t+(description of the item)
+
+ Branch nodes contains leaf nodes and/or branch nodes. The end of
+ a branch node is indicated with ';' as item name (first column).
+
+ Internal branch name and internal item counter name must be unique.
+
+ Returns mtime of statistics_msg_items.def. It will be used to check
+ auto-generated files need to be regenerated.
+ '''
+ global item_list
+
+ items_definition_file = srcdir + os.sep + 'statistics_msg_items.def'
+ item_definition = open(items_definition_file, 'r')
+
+ re_splitter = re.compile('\t+')
+ l = item_list
+ lp = None
+ for line in item_definition.readlines():
+ element = re_splitter.split(line.rstrip())
+ if element[0] == '':
+ element.pop(0)
+
+ if element[-1] == '=':
+ l.append({'name': element[0], 'child': [], 'index': element[1],
+ 'description': element[2], 'parent': lp})
+ lp = l
+ l = l[-1]['child']
+ elif element[-1] == ';':
+ l = lp
+ lp = l[-1]['parent']
+ else:
+ l.append({'name': element[0], 'child': None, 'index': element[1],
+ 'description': element[2], 'parent': lp})
+
+ item_definition.close()
+ return os.path.getmtime(items_definition_file)
+
+def generate_specfile(specfile, def_mtime):
+ '''Generate spec in specfile from skeleton (specfille+'.pre').
+ If the specfile is newer than both sleketon and def_mtime, file generation
+ will be skipped.
+
+ This method reads the content of skeleton and repaces
+ <!-- ### STATISTICS DATA PLACEHOLDER ### --> with statistics items
+ definition. LOCALSTATEDIR is also expanded.
+
+ Returns nothing.
+ '''
+ global item_list
+
+ def convert_list(items, prefix = ''):
+ spec_list = []
+ default_map = {}
+ for item in items:
+ full_item_name = prefix + item['name']
+ if item['child'] is None:
+ default_map[item['name']] = 0
+ spec_list.append({
+ 'item_name': item['name'],
+ 'item_optional': False,
+ 'item_type': 'integer',
+ 'item_default': 0,
+ 'item_title': full_item_name,
+ 'item_description': item['description'],
+ })
+ else:
+ child_spec_list, child_default_map = \
+ convert_list(item['child'], full_item_name + '.')
+ spec_list.append({
+ 'item_name': item['name'],
+ 'item_type': 'map',
+ 'item_optional': False,
+ 'item_title': full_item_name,
+ 'item_description': item['description'],
+ 'item_default': child_default_map,
+ 'map_item_spec': child_spec_list,
+ })
+ default_map[item['name']] = child_default_map
+ return spec_list, default_map
+
+ item_spec_list, item_default_map = convert_list(item_list)
+
+ statistics_spec_list = [{
+ 'item_name': 'zones',
+ 'item_type': 'named_set',
+ 'item_optional': False,
+ 'item_title': 'Zone statistics',
+ 'item_description':
+ 'Zone statistics items. ' +
+ "Items for all zones are stored in '_SERVER_'.",
+ 'item_default': { '_SERVER_': item_default_map },
+ 'named_set_item_spec': {
+ 'item_name': 'zone',
+ 'item_type': 'map',
+ 'item_optional': False,
+ 'item_default': {},
+ 'map_item_spec': item_spec_list,
+ },
+ }]
+
+ if need_generate(builddir+os.sep+specfile, def_mtime):
+ stats_pre = open(builddir+os.sep+specfile+pre_suffix, 'r')
+ stats_pre_json = \
+ json.loads(stats_pre.read().replace('@@LOCAL'+'STATEDIR@@',
+ localstatedir))
+ stats_pre.close()
+ stats_pre_json['module_spec']['statistics'] = statistics_spec_list
+ statistics_spec_json = json.dumps(stats_pre_json, sort_keys = True,
+ indent = 2)
+ stats_spec = open(builddir+os.sep+specfile, 'w')
+ stats_spec.write(statistics_spec_json)
+ stats_spec.close()
+ else:
+ print('skip generating ' + specfile)
+ return
+
+def generate_docfile(docfile, def_mtime):
+ '''Generate docbook XML in docfile from skeleton (docfile+'.pre').
+ If the docfile is newer than both sleketon and def_mtime, file generation
+ will be skipped.
+
+ This method reads the content of skeleton and repaces
+ <!-- ### STATISTICS DATA PLACEHOLDER ### --> with statistics items
+ definition. LOCALSTATEDIR is also expanded.
+
+ Returns nothing.
+ '''
+ global item_list
+
+ def convert_list(items, tree, prefix = ''):
+ for item in items:
+ full_item_name = prefix + item['name']
+ if item['child'] is None:
+ child_element = ElementTree.SubElement(tree, 'varlistentry')
+ term = ElementTree.SubElement(child_element, 'term')
+ term.text = full_item_name
+ list_item = ElementTree.SubElement(child_element, 'listitem')
+ sim_para = ElementTree.SubElement(list_item, 'simpara')
+ sim_para.text = ''
+ prev = None
+ for word in item['description'].split():
+ if word == xmldocument_command_name:
+ command = ElementTree.SubElement(sim_para, 'command')
+ command.text = word
+ para_tail = command
+ command.tail = ' '
+ prev = command
+ else:
+ if prev is None:
+ sim_para.text += word + ' '
+ else:
+ prev.tail += word + ' '
+ else:
+ convert_list(item['child'], tree, full_item_name + '.')
+ return
+
+ if need_generate(builddir+os.sep+docfile, def_mtime):
+ doc_pre = open(srcdir+os.sep+docfile+pre_suffix, 'r')
+ doc_pre_xml = doc_pre.read().replace('@@LOCAL'+'STATEDIR@@',
+ localstatedir)
+ doc_pre.close
+
+ variable_tree = ElementTree.Element('variablelist')
+ convert_list(item_list, variable_tree)
+ doc = open(builddir+os.sep+docfile, 'w')
+ doc.write(doc_pre_xml.replace(
+ '<!-- ### STATISTICS DATA PLACEHOLDER ### -->',
+ str(ElementTree.tostring(variable_tree))))
+ doc.close()
+ else:
+ print('skip generating ' + docfile)
+ return
+
+def generate_cxx(itemsfile, ccfile, utfile, def_mtime):
+ '''Generate some part of statistics code in itemsfile, ccfile, utfile from
+ skeleton (itemsfile+'.pre', ccfile+'.pre', utfile+'.pre').
+ If the file is newer than both sleketon and def_mtime, file generation
+ will be skipped.
+
+ This method reads the content of skeleton and repaces
+ // ### STATISTICS ITEMS DEFINITION ### with statistics items definition in
+ ccfile and utfile,
+ // ### STATISTICS ITEMS DECLARATION ### with statistics items declaration
+ in itemsfile.
+
+ Returns nothing.
+ '''
+ global item_list
+
+ msg_counter_types = 'enum MSGCounterType {\n'
+ item_names = ['// using -1 as counter_id to state it is not a '
+ + 'counter item\n']
+ item_names += ['const int NOT_ITEM = -1;\n', '\n']
+
+ def convert_list(items, msg_counter_types, item_names_current, item_names):
+ for item in items:
+ if item['child'] is None:
+ msg_counter_types += ' ' + item['index'] + ', ' +\
+ '///< ' + item['description'] + '\n'
+ item_names_current.append(' { "' + item['name'] +
+ '", NULL, ' + item['index'] + ' },\n'
+ )
+ else:
+ item_names_current_ = ['const struct CounterSpec ' +
+ item['index'] + '[] = {\n']
+ msg_counter_types, item_names_current_, item_names = \
+ convert_list(item['child'], msg_counter_types,
+ item_names_current_, item_names)
+ item_names_current_.append(' { NULL, NULL, NOT_ITEM }\n' +
+ '};\n')
+ item_names.extend(item_names_current_)
+ item_names_current.append(' { "' + item['name'] + '", ' +
+ item['index'] + ', NOT_ITEM },\n')
+ return msg_counter_types, item_names_current, item_names
+
+ msg_counter_types, item_names_current, item_names = \
+ convert_list(item_list, msg_counter_types, [], item_names)
+ item_names.append('const struct CounterSpec msg_counter_tree[] = {\n')
+ item_names.extend(item_names_current)
+ item_names.append(' { NULL, NULL, NOT_ITEM }\n' +
+ '};\n')
+
+ msg_counter_types += \
+ ' // End of counter types\n' +\
+ ' MSG_COUNTER_TYPES ///< The number of defined counters\n' +\
+ '};\n'
+
+ item_decls = msg_counter_types
+ item_defs = ''.join(item_names)
+
+ if need_generate(builddir+os.sep+itemsfile, def_mtime):
+ statistics_items_h_pre = open(srcdir+os.sep+itemsfile+pre_suffix, 'r')
+ items_pre = statistics_items_h_pre.read()
+ statistics_items_h_pre.close
+
+ statistics_items_h = open(builddir+os.sep+itemsfile, 'w')
+ statistics_items_h.write(items_pre.replace(
+ '// ### STATISTICS ITEMS DECLARATION ###', item_decls))
+ statistics_items_h.close()
+ else:
+ print('skip generating ' + itemsfile)
+
+ if need_generate(builddir+os.sep+ccfile, def_mtime):
+ statistics_cc_pre = open(srcdir+os.sep+ccfile+pre_suffix, 'r')
+ items_pre = statistics_cc_pre.read()
+ statistics_cc_pre.close
+
+ statistics_cc = open(builddir+os.sep+ccfile, 'w')
+ statistics_cc.write(items_pre.replace(
+ '// ### STATISTICS ITEMS DEFINITION ###', item_defs))
+ statistics_cc.close()
+ else:
+ print('skip generating ' + ccfile)
+
+ if need_generate(builddir+os.sep+utfile, def_mtime):
+ statistics_ut_cc_pre = open(srcdir+os.sep+utfile+pre_suffix, 'r')
+ items_pre = statistics_ut_cc_pre.read()
+ statistics_ut_cc_pre.close
+
+ statistics_ut_cc = open(builddir+os.sep+utfile, 'w')
+ statistics_ut_cc.write(items_pre.replace(
+ '// ### STATISTICS ITEMS DEFINITION ###', item_defs))
+ statistics_ut_cc.close()
+ else:
+ print('skip generating ' + utfile)
+
+ return
+
+if __name__ == "__main__":
+ try:
+ def_mtime = import_definitions()
+ generate_specfile('auth.spec', def_mtime)
+ generate_docfile('b10-auth.xml', def_mtime)
+ generate_cxx('statistics_items.h',
+ 'statistics.cc',
+ 'tests'+os.sep+'statistics_unittest.cc',
+ def_mtime)
+ except:
+ sys.stderr.write('File generation failed due to exception: %s\n' %
+ sys.exc_info()[1])
+ exit(1)
diff --git a/src/bin/auth/statistics.cc.pre b/src/bin/auth/statistics.cc.pre
index d84eeb1..5ead3a2 100644
--- a/src/bin/auth/statistics.cc.pre
+++ b/src/bin/auth/statistics.cc.pre
@@ -38,22 +38,27 @@
using namespace isc::dns;
using namespace isc::auth;
using namespace isc::statistics;
+using namespace isc::auth::statistics;
namespace {
+/// \brief Fill ItemTreePtr with given counter.
+/// \param counter Counter which stores values to fill
+/// \param type_tree CounterSpec corresponding to counter for building item name
+/// \param trees ItemTreePtr to be filled in; caller has ownership of ItemTreePtr
void
fillNodes(const Counter& counter,
- const struct isc::auth::statistics::CounterTypeTree type_tree[],
+ const struct isc::auth::statistics::CounterSpec type_tree[],
isc::auth::statistics::Counters::ItemTreePtr& trees)
{
using namespace isc::data;
for (int i = 0; type_tree[i].name != NULL; ++i) {
- if (type_tree[i].sub_tree != NULL) {
- isc::auth::statistics::Counters::ItemTreePtr sub_tree =
+ if (type_tree[i].sub_counters != NULL) {
+ isc::auth::statistics::Counters::ItemTreePtr sub_counters =
Element::createMap();
- trees->set(type_tree[i].name, sub_tree);
- fillNodes(counter, type_tree[i].sub_tree, sub_tree);
+ trees->set(type_tree[i].name, sub_counters);
+ fillNodes(counter, type_tree[i].sub_counters, sub_counters);
} else {
trees->set(type_tree[i].name,
Element::create(static_cast<long int>(
@@ -63,130 +68,127 @@ fillNodes(const Counter& counter,
}
}
+// ### STATISTICS ITEMS DEFINITION ###
+
} // anonymous namespace
namespace isc {
namespace auth {
namespace statistics {
-// ### STATISTICS ITEMS DEFINITION ###
-
// Note: opcode in this array must be start with 0 and be sequential
-const int opcode_to_qrcounter[] = {
- QR_OPCODE_QUERY, // Opcode = 0: Query
- QR_OPCODE_IQUERY, // Opcode = 1: Iquery
- QR_OPCODE_STATUS, // Opcode = 2: STATUS
- QR_OPCODE_OTHER, // Opcode = 3: (Unassigned)
- QR_OPCODE_NOTIFY, // Opcode = 4: Notify
- QR_OPCODE_UPDATE, // Opcode = 5: Update
- QR_OPCODE_OTHER, // Opcode = 6: (Unassigned)
- QR_OPCODE_OTHER, // Opcode = 7: (Unassigned)
- QR_OPCODE_OTHER, // Opcode = 8: (Unassigned)
- QR_OPCODE_OTHER, // Opcode = 9: (Unassigned)
- QR_OPCODE_OTHER, // Opcode = 10: (Unassigned)
- QR_OPCODE_OTHER, // Opcode = 11: (Unassigned)
- QR_OPCODE_OTHER, // Opcode = 12: (Unassigned)
- QR_OPCODE_OTHER, // Opcode = 13: (Unassigned)
- QR_OPCODE_OTHER, // Opcode = 14: (Unassigned)
- QR_OPCODE_OTHER // Opcode = 15: (Unassigned)
+const int opcode_to_msgcounter[] = {
+ MSG_OPCODE_QUERY, // Opcode = 0: Query
+ MSG_OPCODE_IQUERY, // Opcode = 1: Iquery
+ MSG_OPCODE_STATUS, // Opcode = 2: STATUS
+ MSG_OPCODE_OTHER, // Opcode = 3: (Unassigned)
+ MSG_OPCODE_NOTIFY, // Opcode = 4: Notify
+ MSG_OPCODE_UPDATE, // Opcode = 5: Update
+ MSG_OPCODE_OTHER, // Opcode = 6: (Unassigned)
+ MSG_OPCODE_OTHER, // Opcode = 7: (Unassigned)
+ MSG_OPCODE_OTHER, // Opcode = 8: (Unassigned)
+ MSG_OPCODE_OTHER, // Opcode = 9: (Unassigned)
+ MSG_OPCODE_OTHER, // Opcode = 10: (Unassigned)
+ MSG_OPCODE_OTHER, // Opcode = 11: (Unassigned)
+ MSG_OPCODE_OTHER, // Opcode = 12: (Unassigned)
+ MSG_OPCODE_OTHER, // Opcode = 13: (Unassigned)
+ MSG_OPCODE_OTHER, // Opcode = 14: (Unassigned)
+ MSG_OPCODE_OTHER // Opcode = 15: (Unassigned)
};
-const size_t num_opcode_to_qrcounter =
- sizeof(opcode_to_qrcounter) / sizeof(opcode_to_qrcounter[0]);
+const size_t num_opcode_to_msgcounter =
+ sizeof(opcode_to_msgcounter) / sizeof(opcode_to_msgcounter[0]);
// Note: rcode in this array must be start with 0 and be sequential
-const int rcode_to_qrcounter[] = {
- QR_RCODE_NOERROR, // Rcode = 0: NoError
- QR_RCODE_FORMERR, // Rcode = 1: FormErr
- QR_RCODE_SERVFAIL, // Rcode = 2: ServFail
- QR_RCODE_NXDOMAIN, // Rcode = 3: NXDomain
- QR_RCODE_NOTIMP, // Rcode = 4: NotImp
- QR_RCODE_REFUSED, // Rcode = 5: Refused
- QR_RCODE_YXDOMAIN, // Rcode = 6: YXDomain
- QR_RCODE_YXRRSET, // Rcode = 7: YXRRSet
- QR_RCODE_NXRRSET, // Rcode = 8: NXRRSet
- QR_RCODE_NOTAUTH, // Rcode = 9: NotAuth
- QR_RCODE_NOTZONE, // Rcode = 10: NotZone
- QR_RCODE_OTHER, // Rcode = 11: (Unassigned)
- QR_RCODE_OTHER, // Rcode = 12: (Unassigned)
- QR_RCODE_OTHER, // Rcode = 13: (Unassigned)
- QR_RCODE_OTHER, // Rcode = 14: (Unassigned)
- QR_RCODE_OTHER, // Rcode = 15: (Unassigned)
- QR_RCODE_BADVERS // Rcode = 16: (BADVERS)
+const int rcode_to_msgcounter[] = {
+ MSG_RCODE_NOERROR, // Rcode = 0: NoError
+ MSG_RCODE_FORMERR, // Rcode = 1: FormErr
+ MSG_RCODE_SERVFAIL, // Rcode = 2: ServFail
+ MSG_RCODE_NXDOMAIN, // Rcode = 3: NXDomain
+ MSG_RCODE_NOTIMP, // Rcode = 4: NotImp
+ MSG_RCODE_REFUSED, // Rcode = 5: Refused
+ MSG_RCODE_YXDOMAIN, // Rcode = 6: YXDomain
+ MSG_RCODE_YXRRSET, // Rcode = 7: YXRRSet
+ MSG_RCODE_NXRRSET, // Rcode = 8: NXRRSet
+ MSG_RCODE_NOTAUTH, // Rcode = 9: NotAuth
+ MSG_RCODE_NOTZONE, // Rcode = 10: NotZone
+ MSG_RCODE_OTHER, // Rcode = 11: (Unassigned)
+ MSG_RCODE_OTHER, // Rcode = 12: (Unassigned)
+ MSG_RCODE_OTHER, // Rcode = 13: (Unassigned)
+ MSG_RCODE_OTHER, // Rcode = 14: (Unassigned)
+ MSG_RCODE_OTHER, // Rcode = 15: (Unassigned)
+ MSG_RCODE_BADVERS // Rcode = 16: BADVERS
};
-const size_t num_rcode_to_qrcounter =
- sizeof(rcode_to_qrcounter) / sizeof(rcode_to_qrcounter[0]);
+const size_t num_rcode_to_msgcounter =
+ sizeof(rcode_to_msgcounter) / sizeof(rcode_to_msgcounter[0]);
Counters::Counters() :
- // size of server_qr_counter_, zone_qr_counters_: QR_COUNTER_TYPES
- server_qr_counter_(QR_COUNTER_TYPES),
- zone_qr_counters_(QR_COUNTER_TYPES)
+ server_msg_counter_(MSG_COUNTER_TYPES)
{}
void
-Counters::incRequest(const QRAttributes& qrattrs) {
+Counters::incRequest(const MessageAttributes& msgattrs) {
// 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 (msgattrs.getRequestIPVersion() == AF_INET) {
+ server_msg_counter_.inc(MSG_REQUEST_IPV4);
+ } else if (msgattrs.getRequestIPVersion() == AF_INET6) {
+ server_msg_counter_.inc(MSG_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);
+ if (msgattrs.getRequestTransportProtocol() == IPPROTO_UDP) {
+ server_msg_counter_.inc(MSG_REQUEST_UDP);
+ } else if (msgattrs.getRequestTransportProtocol() == IPPROTO_TCP) {
+ server_msg_counter_.inc(MSG_REQUEST_TCP);
}
- // query TSIG
- if (qrattrs.req_is_tsig_) {
- server_qr_counter_.inc(QR_REQUEST_TSIG);
+ // request TSIG
+ if (msgattrs.getRequestSigTSIG()) {
+ server_msg_counter_.inc(MSG_REQUEST_TSIG);
}
- if (qrattrs.req_is_sig0_) {
- server_qr_counter_.inc(QR_REQUEST_SIG0);
+ if (msgattrs.getRequestSigSIG0()) {
+ server_msg_counter_.inc(MSG_REQUEST_SIG0);
}
- if (qrattrs.req_is_badsig_) {
- server_qr_counter_.inc(QR_REQUEST_BADSIG);
+ if (msgattrs.getRequestSigBadSig()) {
+ server_msg_counter_.inc(MSG_REQUEST_BADSIG);
// If signature validation is failed, no other query attributes are
// reliable. Skip processing of the rest of query counters.
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);
+ // request EDNS
+ if (msgattrs.getRequestEDNS0()) {
+ server_msg_counter_.inc(MSG_REQUEST_EDNS0);
}
- // query DNSSEC
- if (qrattrs.req_is_dnssec_ok_) {
- server_qr_counter_.inc(QR_REQUEST_DNSSEC_OK);
+ // request DNSSEC
+ if (msgattrs.getRequestDO()) {
+ server_msg_counter_.inc(MSG_REQUEST_DNSSEC_OK);
}
// OPCODE
- server_qr_counter_.inc(opcode_to_qrcounter[qrattrs.req_opcode_]);
+ server_msg_counter_.inc(opcode_to_msgcounter[msgattrs.getRequestOpCode()]);
}
void
-Counters::incResponse(const QRAttributes& qrattrs, const Message& response) {
+Counters::incResponse(const MessageAttributes& msgattrs,
+ const Message& response)
+{
// responded
- server_qr_counter_.inc(QR_RESPONSE);
+ server_msg_counter_.inc(MSG_RESPONSE);
// response truncated
- if (qrattrs.res_is_truncated_) {
- server_qr_counter_.inc(QR_RESPONSE_TRUNCATED);
+ if (msgattrs.getResponseTruncated()) {
+ server_msg_counter_.inc(MSG_RESPONSE_TRUNCATED);
}
// response EDNS
ConstEDNSPtr response_edns = response.getEDNS();
if (response_edns && response_edns->getVersion() == 0) {
- server_qr_counter_.inc(QR_RESPONSE_EDNS0);
+ server_msg_counter_.inc(MSG_RESPONSE_EDNS0);
}
// response TSIG
- if (qrattrs.req_is_tsig_) {
+ if (msgattrs.getRequestSigTSIG()) {
// assume response is TSIG signed if request is TSIG signed
- server_qr_counter_.inc(QR_RESPONSE_TSIG);
+ server_msg_counter_.inc(MSG_RESPONSE_TSIG);
}
// response SIG(0) is currently not implemented
@@ -194,52 +196,60 @@ Counters::incResponse(const QRAttributes& qrattrs, const Message& response) {
// RCODE
const unsigned int rcode = response.getRcode().getCode();
const unsigned int rcode_type =
- rcode < num_rcode_to_qrcounter ?
- rcode_to_qrcounter[rcode] : 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);
+ rcode < num_rcode_to_msgcounter ?
+ rcode_to_msgcounter[rcode] : MSG_RCODE_OTHER;
+ server_msg_counter_.inc(rcode_type);
+ // Unsupported EDNS version
+ if (rcode == Rcode::BADVERS().getCode()) {
+ server_msg_counter_.inc(MSG_REQUEST_BADEDNSVER);
}
- if (rcode == Rcode::NOERROR_CODE) {
- if (answer_rrs > 0) {
- // QrySuccess
- server_qr_counter_.inc(QR_QRYSUCCESS);
+ if (msgattrs.getRequestOpCode() == Opcode::QUERY_CODE) {
+ // 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_msg_counter_.inc(MSG_QRYAUTHANS);
} else {
- if (is_aa_set) {
- // QryNxrrset
- server_qr_counter_.inc(QR_QRYNXRRSET);
+ // QryNoAuthAns
+ server_msg_counter_.inc(MSG_QRYNOAUTHANS);
+ }
+
+ if (rcode == Rcode::NOERROR_CODE) {
+ if (answer_rrs > 0) {
+ // QrySuccess
+ server_msg_counter_.inc(MSG_QRYSUCCESS);
} else {
- // QryReferral
- server_qr_counter_.inc(QR_QRYREFERRAL);
+ if (is_aa_set) {
+ // QryNxrrset
+ server_msg_counter_.inc(MSG_QRYNXRRSET);
+ } else {
+ // QryReferral
+ server_msg_counter_.inc(MSG_QRYREFERRAL);
+ }
+ }
+ } else if (rcode == Rcode::REFUSED_CODE) {
+ if (!response.getHeaderFlag(Message::HEADERFLAG_RD)) {
+ // AuthRej
+ server_msg_counter_.inc(MSG_QRYREJECT);
}
}
- } else if (rcode == Rcode::REFUSED_CODE) {
- // AuthRej
- server_qr_counter_.inc(QR_QRYREJECT);
}
}
void
-Counters::inc(const QRAttributes& qrattrs, const Message& response,
+Counters::inc(const MessageAttributes& msgattrs, const Message& response,
const bool done)
{
// increment request counters
- incRequest(qrattrs);
+ incRequest(msgattrs);
if (done) {
// increment response counters if answer was sent
- incResponse(qrattrs, response);
+ incResponse(msgattrs, response);
}
}
@@ -253,7 +263,7 @@ Counters::get() const {
item_tree->set("zones", zones);
Counters::ItemTreePtr server = Element::createMap();
- fillNodes(server_qr_counter_, QRCounterTree, server);
+ fillNodes(server_msg_counter_, msg_counter_tree, server);
zones->set("_SERVER_", server);
return (item_tree);
diff --git a/src/bin/auth/statistics.h b/src/bin/auth/statistics.h
index 5b8134d..313e99f 100644
--- a/src/bin/auth/statistics.h
+++ b/src/bin/auth/statistics.h
@@ -25,7 +25,7 @@
#include <boost/noncopyable.hpp>
-#include <string>
+#include <bitset>
#include <stdint.h>
@@ -33,83 +33,154 @@ namespace isc {
namespace auth {
namespace statistics {
-/// \brief Query/Response attributes for statistics.
+/// \brief DNS Message attributes for statistics.
///
-/// This class holds some attributes related to a query/response
+/// This class holds some attributes related to a DNS message
/// for statistics data collection.
-///
-/// This class does not have getter methods since it exposes private members
-/// to \c Counters directly.
-class QRAttributes {
-friend class Counters;
+class MessageAttributes {
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
- // response attributes
- bool res_is_truncated_; // DNS message is truncated
+ uint8_t req_opcode_; // OpCode
+ enum BitAttributes {
+ REQ_IS_EDNS_0, // EDNS ver.0
+ REQ_IS_DNSSEC_OK, // DNSSEC OK (DO) bit is set
+ REQ_IS_TSIG, // signed with valid TSIG
+ REQ_IS_SIG0, // signed with valid SIG(0)
+ REQ_IS_BADSIG, // signed but bad signature,
+ RES_IS_TRUNCATED, // DNS message is truncated
+ BIT_ATTRIBUTES_TYPES
+ };
+ std::bitset<BIT_ATTRIBUTES_TYPES> bit_attributes_;
public:
/// \brief The constructor.
///
/// This constructor is mostly exception free. But it may still throw
/// a standard exception if memory allocation fails inside the method.
///
- QRAttributes() {
+ MessageAttributes() {
reset();
};
- /// \brief Set query opcode.
+ /// \brief Get request opcode.
+ /// \return opcode of a request
+ /// \throw None
+ uint8_t getRequestOpCode() const {
+ return (req_opcode_);
+ };
+
+ /// \brief Set request opcode.
/// \throw None
- void setQueryOpCode(const int opcode) {
+ void setRequestOpCode(const uint8_t opcode) {
req_opcode_ = opcode;
};
- /// \brief Set IP version carrying a query.
+ /// \brief Get IP version carrying a request.
+ /// \return IP version carrying a request (AF_INET or AF_INET6)
+ /// \throw None
+ int getRequestIPVersion() const {
+ return (req_ip_version_);
+ };
+
+ /// \brief Set IP version carrying a request.
+ /// \param ip_version AF_INET or AF_INET6
/// \throw None
- void setQueryIPVersion(const int ip_version) {
+ void setRequestIPVersion(const int ip_version) {
req_ip_version_ = ip_version;
};
- /// \brief Set transport protocol carrying a query.
+ /// \brief Get transport protocol carrying a request.
+ /// \return Transport protocol carrying a request
+ /// (IPPROTO_UDP or IPPROTO_TCP)
/// \throw None
- void setQueryTransportProtocol(const int transport_protocol) {
+ int getRequestTransportProtocol() const {
+ return (req_transport_protocol_);
+ };
+
+ /// \brief Set transport protocol carrying a request.
+ /// \param transport_protocol IPPROTO_UDP or IPPROTO_TCP
+ /// \throw None
+ void setRequestTransportProtocol(const int transport_protocol) {
req_transport_protocol_ = transport_protocol;
};
- /// \brief Set query EDNS attributes.
+ /// \brief Get request is EDNS version 0.
+ /// \return true if EDNS version 0
/// \throw None
- void 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;
+ bool getRequestEDNS0() const {
+ return (bit_attributes_[REQ_IS_EDNS_0]);
};
- /// \brief Set query DO bit.
+ /// \brief Set request EDNS attributes.
+ /// \param is_edns_0 true if request is EDNS version 0
+ /// \param is_edns_badver true if request is EDNS version other than 0
/// \throw None
- void setQueryDO(const bool is_dnssec_ok) {
- req_is_dnssec_ok_ = is_dnssec_ok;
+ void setRequestEDNS0(const bool is_edns_0) {
+ bit_attributes_[REQ_IS_EDNS_0] = is_edns_0;
};
- /// \brief Set query TSIG attributes.
+ /// \brief Get request DNSSEC OK (DO) bit.
+ /// \return true if DNSSEC OK (DO) bit is set
/// \throw None
- void setQuerySig(const bool is_tsig, const bool is_sig0,
- const bool is_badsig)
+ bool getRequestDO() const {
+ return (bit_attributes_[REQ_IS_DNSSEC_OK]);
+ };
+
+ /// \brief Set request DNSSEC OK (DO) bit.
+ /// \param is_dnssec_ok true if DNSSEC OK (DO) bit is set
+ /// \throw None
+ void setRequestDO(const bool is_dnssec_ok) {
+ bit_attributes_[REQ_IS_DNSSEC_OK] = is_dnssec_ok;
+ };
+
+ /// \brief Get request TSIG signed and verified.
+ /// \return true if request is TSIG signed and verified
+ /// \throw None
+ bool getRequestSigTSIG() const {
+ return (bit_attributes_[REQ_IS_TSIG]);
+ };
+
+ /// \brief Get request SIG(0) signed and verified.
+ /// \return true if request is SIG(0) signed and verified
+ /// \throw None
+ bool getRequestSigSIG0() const {
+ return (bit_attributes_[REQ_IS_SIG0]);
+ };
+
+ /// \brief Get request signature is bad.
+ /// \return true if request signature is bad
+ /// \throw None
+ bool getRequestSigBadSig() const {
+ return (bit_attributes_[REQ_IS_BADSIG]);
+ };
+
+ /// \brief Set request TSIG attributes.
+ /// \param is_tsig true if request is TSIG signed
+ /// \param is_sig0 true if request is SIG(0) signed
+ /// \param is_badsig true if request signature is bad
+ /// \throw None
+ void setRequestSig(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;
+ assert(!(is_tsig && is_sig0));
+ bit_attributes_[REQ_IS_TSIG] = is_tsig;
+ bit_attributes_[REQ_IS_SIG0] = is_sig0;
+ bit_attributes_[REQ_IS_BADSIG] = is_badsig;
+ };
+
+ /// \brief Get if the response is truncated.
+ /// \return true if the response is truncated
+ /// \throw None
+ bool getResponseTruncated() const {
+ return (bit_attributes_[RES_IS_TRUNCATED]);
};
/// \brief Set if the response is truncated.
+ /// \param is_truncated true if the response is truncated
/// \throw None
void setResponseTruncated(const bool is_truncated) {
- res_is_truncated_ = is_truncated;
+ bit_attributes_[RES_IS_TRUNCATED] = is_truncated;
};
/// \brief Reset attributes.
@@ -118,27 +189,21 @@ public:
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;
- res_is_truncated_ = false;
+ bit_attributes_.reset();
};
};
-/// \brief Set of query counters.
+/// \brief Set of DNS message 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).
+/// \c Counters is set of DNS message counters class. It holds DNS message
+/// counters and provides an interface to increment the counter of specified
+/// type (e.g. UDP message, TCP message).
///
/// This class also provides a function to send statistics information to
/// statistics module.
///
/// This class is designed to be a part of \c AuthSrv.
-/// Call \c inc() to increment a counter for the query.
+/// Call \c inc() to increment a counter for the message.
/// Call \c getStatistics() to answer statistics information to statistics
/// module with statistics_session, when the command \c getstats is received.
///
@@ -150,16 +215,14 @@ public:
/// This class is constructed on startup of the server, so
/// construction overhead of this approach should be acceptable.
///
-/// \todo Hold counters for each query types (Notify, Axfr, Ixfr, Normal)
+/// \todo Hold counters for each message types (Notify, Axfr, Ixfr, Normal)
/// \todo Consider overhead of \c Counters::inc()
class Counters : boost::noncopyable {
private:
- // counter for query/response
- isc::statistics::Counter server_qr_counter_;
- // set of counters for zones
- isc::statistics::CounterDictionary zone_qr_counters_;
- void incRequest(const QRAttributes& qrattrs);
- void incResponse(const QRAttributes& qrattrs,
+ // counter for DNS message attributes
+ isc::statistics::Counter server_msg_counter_;
+ void incRequest(const MessageAttributes& msgattrs);
+ void incResponse(const MessageAttributes& msgattrs,
const isc::dns::Message& response);
public:
/// \brief A type of statistics item tree in isc::data::MapElement.
@@ -189,14 +252,14 @@ public:
/// This constructor is mostly exception free. But it may still throw
/// a standard exception if memory allocation fails inside the method.
///
- /// \param qrattrs Query/Response attributes.
+ /// \param msgattrs DNS message attributes.
/// \param response DNS response message.
/// \param done DNS response was sent to the client.
///
/// \throw std::bad_alloc Internal resource allocation fails
///
- void inc(const QRAttributes& qrattrs, const isc::dns::Message& response,
- const bool done);
+ void inc(const MessageAttributes& msgattrs,
+ const isc::dns::Message& response, const bool done);
/// \brief Get statistics counters.
///
diff --git a/src/bin/auth/statistics_items.h.pre b/src/bin/auth/statistics_items.h.pre
index 8145378..eb76637 100644
--- a/src/bin/auth/statistics_items.h.pre
+++ b/src/bin/auth/statistics_items.h.pre
@@ -22,16 +22,24 @@ namespace isc {
namespace auth {
namespace statistics {
-struct CounterTypeTree {
+struct CounterSpec {
+ // item name: Name of this node. This appears in the spec file.
const char* const name;
- const struct CounterTypeTree* const sub_tree;
+ // sub counters: If this is a branch node, sub_counters points to
+ // CounterSpec which contains child nodes. Otherwise, for
+ // leaf nodes, sub_counters is NULL.
+ const struct CounterSpec* const sub_counters;
+ // counter id: If this is a leaf node, counter_id is an enumerator of this
+ // item. Otherwise, for branch nodes, counter_id is NOT_ITEM.
const int counter_id;
};
// ### STATISTICS ITEMS DECLARATION ###
-extern const int opcode_to_qrcounter[];
-extern const int rcode_to_qrcounter[];
+extern const int opcode_to_msgcounter[];
+extern const size_t num_opcode_to_msgcounter;
+extern const int rcode_to_msgcounter[];
+extern const size_t num_rcode_to_msgcounter;
} // namespace statistics
} // namespace auth
diff --git a/src/bin/auth/statistics_msg_items.def b/src/bin/auth/statistics_msg_items.def
new file mode 100644
index 0000000..467ead2
--- /dev/null
+++ b/src/bin/auth/statistics_msg_items.def
@@ -0,0 +1,48 @@
+request msg_counter_request Request statistics =
+ v4 MSG_REQUEST_IPV4 Number of IPv4 requests received by the b10-auth server.
+ v6 MSG_REQUEST_IPV6 Number of IPv6 requests received by the b10-auth server.
+ edns0 MSG_REQUEST_EDNS0 Number of requests with EDNS0 received by the b10-auth server.
+ badednsver MSG_REQUEST_BADEDNSVER Number of requests with unsupported EDNS version received by the b10-auth server.
+ tsig MSG_REQUEST_TSIG Number of requests with TSIG received by the b10-auth server.
+ sig0 MSG_REQUEST_SIG0 Number of requests with SIG(0) received by the b10-auth server; currently not implemented in BIND 10.
+ badsig MSG_REQUEST_BADSIG Number of requests with invalid TSIG or SIG(0) signature received by the b10-auth server.
+ udp MSG_REQUEST_UDP Number of UDP requests received by the b10-auth server.
+ tcp MSG_REQUEST_TCP Number of UDP requests received by the b10-auth server.
+ dnssec_ok MSG_REQUEST_DNSSEC_OK Number of requests with "DNSSEC OK" (DO) bit was set received by the b10-auth server.
+ ;
+opcode msg_counter_opcode Opcode statistics =
+ query MSG_OPCODE_QUERY Number of Opcode=QUERY requests received by the b10-auth server.
+ iquery MSG_OPCODE_IQUERY Number of Opcode=IQUERY requests received by the b10-auth server.
+ status MSG_OPCODE_STATUS Number of Opcode=STATUS requests received by the b10-auth server.
+ notify MSG_OPCODE_NOTIFY Number of Opcode=NOTIFY requests received by the b10-auth server.
+ update MSG_OPCODE_UPDATE Number of Opcode=UPDATE requests received by the b10-auth server.
+ other MSG_OPCODE_OTHER Number of requests in other OpCode received by the b10-auth server.
+ ;
+responses MSG_RESPONSE Number of responses sent by the b10-auth server.
+response msg_counter_response Response statistics =
+ truncated MSG_RESPONSE_TRUNCATED Number of truncated responses sent by the b10-auth server.
+ edns0 MSG_RESPONSE_EDNS0 Number of responses with EDNS0 sent by the b10-auth server.
+ tsig MSG_RESPONSE_TSIG Number of responses with TSIG sent by the b10-auth server.
+ sig0 MSG_RESPONSE_SIG0 Number of responses with SIG(0) sent by the b10-auth server; currently not implemented in BIND 10.
+ ;
+qrysuccess MSG_QRYSUCCESS Number of queries received by the b10-auth server resulted in rcode = NOERROR and the number of answer RR >= 1.
+qryauthans MSG_QRYAUTHANS Number of queries received by the b10-auth server resulted in authoritative answer.
+qrynoauthans MSG_QRYNOAUTHANS Number of queries received by the b10-auth server resulted in non-authoritative answer.
+qryreferral MSG_QRYREFERRAL Number of queries received by the b10-auth server resulted in referral answer.
+qrynxrrset MSG_QRYNXRRSET Number of queries received by the b10-auth server resulted in NOERROR but the number of answer RR == 0.
+authqryrej MSG_QRYREJECT Number of authoritative queries rejected by the b10-auth server.
+rcode msg_counter_rcode Rcode statistics =
+ noerror MSG_RCODE_NOERROR Number of requests received by the b10-auth server resulted in RCODE = 0 (NoError).
+ formerr MSG_RCODE_FORMERR Number of requests received by the b10-auth server resulted in RCODE = 1 (FormErr).
+ servfail MSG_RCODE_SERVFAIL Number of requests received by the b10-auth server resulted in RCODE = 2 (ServFail).
+ nxdomain MSG_RCODE_NXDOMAIN Number of requests received by the b10-auth server resulted in RCODE = 3 (NXDomain).
+ notimp MSG_RCODE_NOTIMP Number of requests received by the b10-auth server resulted in RCODE = 4 (NotImp).
+ refused MSG_RCODE_REFUSED Number of requests received by the b10-auth server resulted in RCODE = 5 (Refused).
+ yxdomain MSG_RCODE_YXDOMAIN Number of requests received by the b10-auth server resulted in RCODE = 6 (YXDomain).
+ yxrrset MSG_RCODE_YXRRSET Number of requests received by the b10-auth server resulted in RCODE = 7 (YXRRSet).
+ nxrrset MSG_RCODE_NXRRSET Number of requests received by the b10-auth server resulted in RCODE = 8 (NXRRSet).
+ notauth MSG_RCODE_NOTAUTH Number of requests received by the b10-auth server resulted in RCODE = 9 (NotAuth).
+ notzone MSG_RCODE_NOTZONE Number of requests received by the b10-auth server resulted in RCODE = 10 (NotZone).
+ badvers MSG_RCODE_BADVERS Number of requests received by the b10-auth server resulted in RCODE = 16 (BADVERS).
+ other MSG_RCODE_OTHER Number of requests received by the b10-auth server resulted in other RCODEs.
+ ;
diff --git a/src/bin/auth/statistics_qr_items.def b/src/bin/auth/statistics_qr_items.def
deleted file mode 100644
index c17da60..0000000
--- a/src/bin/auth/statistics_qr_items.def
+++ /dev/null
@@ -1,48 +0,0 @@
-request QRCounterRequest Request statistics =
- v4 QR_REQUEST_IPV4 Number of IPv4 requests received by the b10-auth server.
- v6 QR_REQUEST_IPV6 Number of IPv6 requests received by the b10-auth server.
- edns0 QR_REQUEST_EDNS0 Number of requests with EDNS0 received by the b10-auth server.
- badednsver QR_REQUEST_BADEDNSVER Number of requests with unsupported EDNS version received by the b10-auth server.
- tsig QR_REQUEST_TSIG Number of requests with TSIG received by the b10-auth server.
- sig0 QR_REQUEST_SIG0 Number of requests with SIG(0) received by the b10-auth server; currently not implemented in BIND 10.
- badsig QR_REQUEST_BADSIG Number of requests with invalid TSIG or SIG(0) signature received by the b10-auth server.
- udp QR_REQUEST_UDP Number of UDP requests received by the b10-auth server.
- tcp QR_REQUEST_TCP Number of UDP requests received by the b10-auth server.
- dnssec_ok QR_REQUEST_DNSSEC_OK Number of requests with "DNSSEC OK" (DO) bit was set received by the b10-auth server.
- ;
-opcode QRCounterOpcode Opcode statistics =
- query QR_OPCODE_QUERY Number of Opcode=QUERY requests received by the b10-auth server.
- iquery QR_OPCODE_IQUERY Number of Opcode=IQUERY requests received by the b10-auth server.
- status QR_OPCODE_STATUS Number of Opcode=STATUS requests received by the b10-auth server.
- notify QR_OPCODE_NOTIFY Number of Opcode=NOTIFY requests received by the b10-auth server.
- update QR_OPCODE_UPDATE Number of Opcode=UPDATE requests received by the b10-auth server.
- other QR_OPCODE_OTHER Number of requests in other OpCode received by the b10-auth server.
- ;
-responses QR_RESPONSE Number of responses sent by the b10-auth server.
-response QRCounterResponse Response statistics =
- truncated QR_RESPONSE_TRUNCATED Number of truncated responses sent by the b10-auth server.
- edns0 QR_RESPONSE_EDNS0 Number of responses with EDNS0 sent by the b10-auth server.
- tsig QR_RESPONSE_TSIG Number of responses with TSIG sent by the b10-auth server.
- sig0 QR_RESPONSE_SIG0 Number of responses with SIG(0) sent by the b10-auth server; currently not implemented in BIND 10.
- ;
-qrysuccess QR_QRYSUCCESS Number of queries received by the b10-auth server resulted in rcode = NOERROR and the number of answer RR >= 1.
-qryauthans QR_QRYAUTHANS Number of queries received by the b10-auth server resulted in authoritative answer.
-qrynoauthans QR_QRYNOAUTHANS Number of queries received by the b10-auth server resulted in non-authoritative answer.
-qryreferral QR_QRYREFERRAL Number of queries received by the b10-auth server resulted in referral answer.
-qrynxrrset QR_QRYNXRRSET Number of queries received by the b10-auth server resulted in NOERROR but the number of answer RR == 0.
-authqryrej QR_QRYREJECT Number of authoritative queries rejected by the b10-auth server.
-rcode QRCounterRcode Rcode statistics =
- noerror QR_RCODE_NOERROR Number of queries received by the b10-auth server resulted in RCODE = 0 (NoError).
- formerr QR_RCODE_FORMERR Number of queries received by the b10-auth server resulted in RCODE = 1 (FormErr).
- servfail QR_RCODE_SERVFAIL Number of queries received by the b10-auth server resulted in RCODE = 2 (ServFail).
- nxdomain QR_RCODE_NXDOMAIN Number of queries received by the b10-auth server resulted in RCODE = 3 (NXDomain).
- notimp QR_RCODE_NOTIMP Number of queries received by the b10-auth server resulted in RCODE = 4 (NotImp).
- refused QR_RCODE_REFUSED Number of queries received by the b10-auth server resulted in RCODE = 5 (Refused).
- yxdomain QR_RCODE_YXDOMAIN Number of queries received by the b10-auth server resulted in RCODE = 6 (YXDomain).
- yxrrset QR_RCODE_YXRRSET Number of queries received by the b10-auth server resulted in RCODE = 7 (YXRRSet).
- nxrrset QR_RCODE_NXRRSET Number of queries received by the b10-auth server resulted in RCODE = 8 (NXRRSet).
- notauth QR_RCODE_NOTAUTH Number of queries received by the b10-auth server resulted in RCODE = 9 (NotAuth).
- notzone QR_RCODE_NOTZONE Number of queries received by the b10-auth server resulted in RCODE = 10 (NotZone).
- badvers QR_RCODE_BADVERS Number of queries received by the b10-auth server resulted in RCODE = 16 (BADVERS).
- other QR_RCODE_OTHER Number of queries received by the b10-auth server resulted in other RCODEs.
- ;
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index 47b744b..22cd2ca 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -89,7 +89,8 @@ const char* const STATIC_DSRC_FILE = DSRC_DIR "/static.zone";
// This is a configuration that uses the in-memory data source containing
// a signed example zone.
-const char* const CONFIG_INMEMORY_EXAMPLE = TEST_DATA_DIR "/rfc5155-example.zone.signed";
+const char* const CONFIG_INMEMORY_EXAMPLE =
+ TEST_DATA_DIR "/rfc5155-example.zone.signed";
class AuthSrvTest : public SrvTestBase {
protected:
@@ -120,7 +121,8 @@ protected:
// Helper for checking Rcode statistic counters;
// Checks for one specific Rcode statistics counter value
- void checkRcodeCounter(const std::string& rcode_name, const int rcode_value,
+ void checkRcodeCounter(const std::string& rcode_name,
+ const int rcode_value,
const int expected_value) const
{
EXPECT_EQ(expected_value, rcode_value) <<
@@ -244,6 +246,13 @@ expectCounterItem(ConstElementPtr stats,
// We did not configure any client lists. Therefore it should be REFUSED
TEST_F(AuthSrvTest, noClientList) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->
+ get("zones")->get("_SERVER_");
+ expectCounterItem(stats_init->get("opcode"), "query", 0);
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init->get("rcode"), "refused", 0);
+
UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
default_qid, Name("version.bind"),
RRClass::CH(), RRType::TXT());
@@ -254,6 +263,12 @@ TEST_F(AuthSrvTest, noClientList) {
EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::REFUSED(),
opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
+
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after->get("opcode"), "query", 1);
+ expectCounterItem(stats_after, "responses", 1);
+ expectCounterItem(stats_after->get("rcode"), "refused", 1);
}
// Unsupported requests. Should result in NOTIMP.
@@ -272,15 +287,33 @@ TEST_F(AuthSrvTest, multiQuestion) {
// Incoming data doesn't even contain the complete header. Must be silently
// dropped.
TEST_F(AuthSrvTest, shortMessage) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_init, "responses", 0);
+
shortMessage();
+
checkAllRcodeCountersZero();
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after, "responses", 0);
}
// Response messages. Must be silently dropped, whether it's a valid response
// or malformed or could otherwise cause a protocol error.
TEST_F(AuthSrvTest, response) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_init, "responses", 0);
+
response();
+
checkAllRcodeCountersZero();
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after, "responses", 0);
}
// Query with a broken question
@@ -297,8 +330,19 @@ TEST_F(AuthSrvTest, shortAnswer) {
// Query with unsupported version of EDNS.
TEST_F(AuthSrvTest, ednsBadVers) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init->get("request"), "badednsver", 0);
+
ednsBadVers();
+
checkAllRcodeCountersZeroExcept(Rcode::BADVERS(), 1);
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after, "responses", 1);
+ expectCounterItem(stats_after->get("request"), "badednsver", 1);
}
TEST_F(AuthSrvTest, AXFROverUDP) {
@@ -306,6 +350,13 @@ TEST_F(AuthSrvTest, AXFROverUDP) {
}
TEST_F(AuthSrvTest, AXFRSuccess) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_init->get("opcode"), "query", 0);
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init->get("response"), "truncated", 0);
+
EXPECT_FALSE(xfrout.isConnected());
UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Name("example.com"), RRClass::IN(),
@@ -317,12 +368,26 @@ TEST_F(AuthSrvTest, AXFRSuccess) {
&dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
EXPECT_TRUE(xfrout.isConnected());
+
checkAllRcodeCountersZero();
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after->get("opcode"), "query", 1);
+ expectCounterItem(stats_after, "responses", 0);
+ expectCounterItem(stats_after->get("response"), "truncated", 0);
}
// Give the server a signed request, but don't give it the key. It will
// not be able to verify it, returning BADKEY
TEST_F(AuthSrvTest, TSIGSignedBadKey) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_init->get("request"), "tsig", 0);
+ expectCounterItem(stats_init->get("request"), "badsig", 0);
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init->get("response"), "tsig", 0);
+
TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
TSIGContext context(key);
UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
@@ -351,12 +416,27 @@ TEST_F(AuthSrvTest, TSIGSignedBadKey) {
EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
"It should be unsigned with this error";
+ // check Rcode counters and TSIG counters
checkAllRcodeCountersZeroExcept(Rcode::NOTAUTH(), 1);
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after->get("request"), "tsig", 1);
+ expectCounterItem(stats_after->get("request"), "badsig", 1);
+ expectCounterItem(stats_after, "responses", 1);
+ expectCounterItem(stats_after->get("response"), "tsig", 1);
}
// Give the server a signed request, but signed by a different key
// (with the same name). It should return BADSIG
TEST_F(AuthSrvTest, TSIGBadSig) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_init->get("request"), "tsig", 0);
+ expectCounterItem(stats_init->get("request"), "badsig", 0);
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init->get("response"), "tsig", 0);
+
TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
TSIGContext context(key);
UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
@@ -387,12 +467,27 @@ TEST_F(AuthSrvTest, TSIGBadSig) {
"It should be unsigned with this error";
checkAllRcodeCountersZeroExcept(Rcode::NOTAUTH(), 1);
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after->get("request"), "tsig", 1);
+ expectCounterItem(stats_after->get("request"), "badsig", 1);
+ expectCounterItem(stats_after, "responses", 1);
+ expectCounterItem(stats_after->get("response"), "tsig", 1);
}
// Give the server a signed unsupported request with a bad signature.
// This checks the server first verifies the signature before anything
// else.
TEST_F(AuthSrvTest, TSIGCheckFirst) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_init->get("request"), "tsig", 0);
+ expectCounterItem(stats_init->get("request"), "badsig", 0);
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init->get("response"), "tsig", 0);
+ expectCounterItem(stats_init->get("opcode"), "other", 0);
+
TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
TSIGContext context(key);
// Pass a wrong opcode there. The server shouldn't know what to do
@@ -423,12 +518,16 @@ TEST_F(AuthSrvTest, TSIGCheckFirst) {
EXPECT_EQ(TSIGError::BAD_SIG_CODE, tsig->getRdata().getError());
EXPECT_EQ(0, tsig->getRdata().getMACSize()) <<
"It should be unsigned with this error";
+
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after->get("request"), "tsig", 1);
+ expectCounterItem(stats_after->get("request"), "badsig", 1);
+ expectCounterItem(stats_after, "responses", 1);
+ expectCounterItem(stats_after->get("response"), "tsig", 1);
// TSIG should have failed, and so the per opcode counter shouldn't be
// incremented.
- ConstElementPtr stats = server.getStatistics();
- expectCounterItem(stats->get("zones")->get("_SERVER_")->get("opcode"),
- "other", 0);
-
+ expectCounterItem(stats_after->get("opcode"), "other", 0);
checkAllRcodeCountersZeroExcept(Rcode::NOTAUTH(), 1);
}
@@ -554,6 +653,12 @@ TEST_F(AuthSrvTest, IXFRDisconnectFail) {
}
TEST_F(AuthSrvTest, notify) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_init->get("opcode"), "notify", 0);
+ expectCounterItem(stats_init, "responses", 0);
+
UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
default_qid, Name("example.com"),
RRClass::IN(), RRType::SOA());
@@ -567,7 +672,8 @@ TEST_F(AuthSrvTest, notify) {
// external module. Check them.
EXPECT_EQ("Zonemgr", notify_session.getMessageDest());
EXPECT_EQ("notify",
- notify_session.getSentMessage()->get("command")->get(0)->stringValue());
+ notify_session.getSentMessage()->get("command")->get(0)->
+ stringValue());
ConstElementPtr notify_args =
notify_session.getSentMessage()->get("command")->get(1);
EXPECT_EQ("example.com.", notify_args->get("zone_name")->stringValue());
@@ -586,9 +692,19 @@ TEST_F(AuthSrvTest, notify) {
EXPECT_EQ(RRType::SOA(), question->getType());
checkAllRcodeCountersZeroExcept(Rcode::NOERROR(), 1);
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after->get("opcode"), "notify", 1);
+ expectCounterItem(stats_after, "responses", 1);
}
TEST_F(AuthSrvTest, notifyForCHClass) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_init->get("opcode"), "notify", 0);
+ expectCounterItem(stats_init, "responses", 0);
+
// Same as the previous test, but for the CH RRClass.
UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(),
default_qid, Name("example.com"),
@@ -604,9 +720,22 @@ TEST_F(AuthSrvTest, notifyForCHClass) {
ConstElementPtr notify_args =
notify_session.getSentMessage()->get("command")->get(1);
EXPECT_EQ("CH", notify_args->get("zone_class")->stringValue());
+
+ checkAllRcodeCountersZeroExcept(Rcode::NOERROR(), 1);
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after->get("opcode"), "notify", 1);
+ expectCounterItem(stats_after, "responses", 1);
}
TEST_F(AuthSrvTest, notifyEmptyQuestion) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_init->get("opcode"), "notify", 0);
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init->get("rcode"), "formerr", 0);
+
request_message.clear(Message::RENDER);
request_message.setOpcode(Opcode::NOTIFY());
request_message.setRcode(Rcode::NOERROR());
@@ -619,6 +748,12 @@ TEST_F(AuthSrvTest, notifyEmptyQuestion) {
EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
+
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after->get("opcode"), "notify", 1);
+ expectCounterItem(stats_after, "responses", 1);
+ expectCounterItem(stats_after->get("rcode"), "formerr", 1);
}
TEST_F(AuthSrvTest, notifyMultiQuestions) {
@@ -791,6 +926,15 @@ TEST_F(AuthSrvTest, DISABLED_TSIGSigned) { // Needs builtin
#else
TEST_F(AuthSrvTest, TSIGSigned) {
#endif
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_init->get("request"), "tsig", 0);
+ expectCounterItem(stats_init->get("request"), "sig0", 0);
+ expectCounterItem(stats_init->get("request"), "badsig", 0);
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init, "qryauthans", 0);
+
// Prepare key, the client message, etc
updateBuiltin(&server);
const TSIGKey key("key:c2VjcmV0Cg==:hmac-sha1");
@@ -824,6 +968,13 @@ TEST_F(AuthSrvTest, TSIGSigned) {
"The server signed the response, but it doesn't seem to be valid";
checkAllRcodeCountersZeroExcept(Rcode::NOERROR(), 1);
+ ConstElementPtr stats_after = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats_after->get("request"), "tsig", 1);
+ expectCounterItem(stats_after->get("request"), "sig0", 0);
+ expectCounterItem(stats_after->get("request"), "badsig", 0);
+ expectCounterItem(stats_after, "responses", 1);
+ expectCounterItem(stats_after, "qryauthans", 1);
}
// Same test emulating the UDPServer class behavior (defined in libasiolink).
@@ -924,8 +1075,8 @@ TEST_F(AuthSrvTest, updateConfig) {
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
EXPECT_TRUE(dnsserv.hasAnswer());
- headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
- QR_FLAG | AA_FLAG, 1, 1, 1, 0);
+ headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
+ opcode.getCode(), QR_FLAG | AA_FLAG, 1, 1, 1, 0);
}
#ifdef USE_STATIC_LINK
@@ -945,6 +1096,11 @@ TEST_F(AuthSrvTest, datasourceFail) {
EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
+
+ checkAllRcodeCountersZeroExcept(Rcode::SERVFAIL(), 1);
+ ConstElementPtr stats = server.getStatistics()->get("zones")->
+ get("_SERVER_");
+ expectCounterItem(stats, "responses", 1);
}
#ifdef USE_STATIC_LINK
@@ -1058,10 +1214,30 @@ TEST_F(AuthSrvTest, queryCounterUDPNormal) {
// The counters should be initialized to 0.
ConstElementPtr stats_init = server.getStatistics()->
get("zones")->get("_SERVER_");
+ expectCounterItem(stats_init->get("request"), "v4", 0);
+ expectCounterItem(stats_init->get("request"), "v6", 0);
expectCounterItem(stats_init->get("request"), "udp", 0);
expectCounterItem(stats_init->get("request"), "tcp", 0);
+ expectCounterItem(stats_init->get("request"), "edns0", 0);
+ expectCounterItem(stats_init->get("request"), "badednsver", 0);
+ expectCounterItem(stats_init->get("request"), "tsig", 0);
+ expectCounterItem(stats_init->get("request"), "sig0", 0);
+ expectCounterItem(stats_init->get("request"), "badsig", 0);
+ expectCounterItem(stats_init->get("request"), "dnssec_ok", 0);
expectCounterItem(stats_init->get("opcode"), "query", 0);
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init->get("response"), "truncated", 0);
+ expectCounterItem(stats_init->get("response"), "edns0", 0);
+ expectCounterItem(stats_init->get("response"), "tsig", 0);
+ expectCounterItem(stats_init->get("response"), "sig0", 0);
expectCounterItem(stats_init->get("rcode"), "refused", 0);
+ expectCounterItem(stats_init, "qrysuccess", 0);
+ expectCounterItem(stats_init, "qryauthans", 0);
+ expectCounterItem(stats_init, "qrynoauthans", 0);
+ expectCounterItem(stats_init, "qryreferral", 0);
+ expectCounterItem(stats_init, "qrynxrrset", 0);
+ expectCounterItem(stats_init, "authqryrej", 0);
+ //
// Create UDP message and process.
UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
default_qid, Name("example.com"),
@@ -1069,27 +1245,107 @@ TEST_F(AuthSrvTest, queryCounterUDPNormal) {
createRequestPacket(request_message, IPPROTO_UDP);
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
- // After processing the UDP query, these counters should be incremented:
- // request.udp, opcode.query, rcode.refused
- // and these counters should not be incremented:
- // request.tcp
+
ConstElementPtr stats_after = server.getStatistics()->
get("zones")->get("_SERVER_");
+ expectCounterItem(stats_after->get("request"), "v4", 1);
+ expectCounterItem(stats_after->get("request"), "v6", 0);
expectCounterItem(stats_after->get("request"), "udp", 1);
expectCounterItem(stats_after->get("request"), "tcp", 0);
+ expectCounterItem(stats_after->get("request"), "edns0", 0);
+ expectCounterItem(stats_after->get("request"), "badednsver", 0);
+ expectCounterItem(stats_after->get("request"), "tsig", 0);
+ expectCounterItem(stats_after->get("request"), "sig0", 0);
+ expectCounterItem(stats_after->get("request"), "badsig", 0);
+ expectCounterItem(stats_after->get("request"), "dnssec_ok", 0);
expectCounterItem(stats_after->get("opcode"), "query", 1);
+ expectCounterItem(stats_after, "responses", 1);
+ expectCounterItem(stats_after->get("response"), "truncated", 0);
+ expectCounterItem(stats_after->get("response"), "edns0", 0);
+ expectCounterItem(stats_after->get("response"), "tsig", 0);
+ expectCounterItem(stats_after->get("response"), "sig0", 0);
expectCounterItem(stats_after->get("rcode"), "refused", 1);
+ expectCounterItem(stats_after, "qrysuccess", 0);
+ expectCounterItem(stats_after, "qryauthans", 0);
+ expectCounterItem(stats_after, "qrynoauthans", 1);
+ expectCounterItem(stats_after, "qryreferral", 0);
+ expectCounterItem(stats_after, "qrynxrrset", 0);
+ expectCounterItem(stats_after, "authqryrej", 1);
}
-// Submit TCP normal query and check query counter
-TEST_F(AuthSrvTest, queryCounterTCPNormal) {
+// Submit UDP normal query with DNSSEC and check query counter
+TEST_F(AuthSrvTest, queryCounterUDPNormalWithDNSSEC) {
// The counters should be initialized to 0.
ConstElementPtr stats_init = server.getStatistics()->
get("zones")->get("_SERVER_");
+ expectCounterItem(stats_init->get("request"), "v4", 0);
+ expectCounterItem(stats_init->get("request"), "v6", 0);
expectCounterItem(stats_init->get("request"), "udp", 0);
expectCounterItem(stats_init->get("request"), "tcp", 0);
+ expectCounterItem(stats_init->get("request"), "edns0", 0);
+ expectCounterItem(stats_init->get("request"), "badednsver", 0);
+ expectCounterItem(stats_init->get("request"), "tsig", 0);
+ expectCounterItem(stats_init->get("request"), "sig0", 0);
+ expectCounterItem(stats_init->get("request"), "badsig", 0);
+ expectCounterItem(stats_init->get("request"), "dnssec_ok", 0);
expectCounterItem(stats_init->get("opcode"), "query", 0);
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init->get("response"), "truncated", 0);
+ expectCounterItem(stats_init->get("response"), "edns0", 0);
+ expectCounterItem(stats_init->get("response"), "tsig", 0);
+ expectCounterItem(stats_init->get("response"), "sig0", 0);
expectCounterItem(stats_init->get("rcode"), "refused", 0);
+ expectCounterItem(stats_init, "qrysuccess", 0);
+ expectCounterItem(stats_init, "qryauthans", 0);
+ expectCounterItem(stats_init, "qrynoauthans", 0);
+ expectCounterItem(stats_init, "qryreferral", 0);
+ expectCounterItem(stats_init, "qrynxrrset", 0);
+ expectCounterItem(stats_init, "authqryrej", 0);
+ //
+ // Create UDP message and process.
+ UnitTestUtil::createDNSSECRequestMessage(request_message, Opcode::QUERY(),
+ default_qid, Name("example.com"),
+ RRClass::IN(), RRType::NS());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, *parse_message, *response_obuffer,
+ &dnsserv);
+
+ ConstElementPtr stats_after = server.getStatistics()->
+ get("zones")->get("_SERVER_");
+ expectCounterItem(stats_after->get("request"), "v4", 1);
+ expectCounterItem(stats_after->get("request"), "v6", 0);
+ expectCounterItem(stats_after->get("request"), "udp", 1);
+ expectCounterItem(stats_after->get("request"), "tcp", 0);
+ expectCounterItem(stats_after->get("request"), "edns0", 1);
+ expectCounterItem(stats_after->get("request"), "badednsver", 0);
+ expectCounterItem(stats_after->get("request"), "tsig", 0);
+ expectCounterItem(stats_after->get("request"), "sig0", 0);
+ expectCounterItem(stats_after->get("request"), "badsig", 0);
+ expectCounterItem(stats_after->get("request"), "dnssec_ok", 1);
+ expectCounterItem(stats_after->get("opcode"), "query", 1);
+ expectCounterItem(stats_after, "responses", 1);
+ expectCounterItem(stats_after->get("response"), "truncated", 0);
+ // XXX: with the current implementation, EDNS0 is omitted in
+ // makeErrorMessage.
+ expectCounterItem(stats_after->get("response"), "edns0", 0);
+ expectCounterItem(stats_after->get("response"), "tsig", 0);
+ expectCounterItem(stats_after->get("response"), "sig0", 0);
+ expectCounterItem(stats_after->get("rcode"), "refused", 1);
+ expectCounterItem(stats_after, "qrysuccess", 0);
+ expectCounterItem(stats_after, "qryauthans", 0);
+ expectCounterItem(stats_after, "qrynoauthans", 1);
+ expectCounterItem(stats_after, "qryreferral", 0);
+ expectCounterItem(stats_after, "qrynxrrset", 0);
+ expectCounterItem(stats_after, "authqryrej", 1);
+}
+
+// Submit TCP normal query and check query counter
+TEST_F(AuthSrvTest, queryCounterTCPNormal) {
+ // The counters should be initialized to 0.
+ ConstElementPtr stats_init = server.getStatistics()->
+ get("zones")->get("_SERVER_");
+ expectCounterItem(stats_init->get("request"), "udp", 0);
+ expectCounterItem(stats_init->get("request"), "tcp", 0);
// Create TCP message and process.
UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
default_qid, Name("example.com"),
@@ -1105,8 +1361,6 @@ TEST_F(AuthSrvTest, queryCounterTCPNormal) {
get("zones")->get("_SERVER_");
expectCounterItem(stats_after->get("request"), "udp", 0);
expectCounterItem(stats_after->get("request"), "tcp", 1);
- expectCounterItem(stats_after->get("opcode"), "query", 1);
- expectCounterItem(stats_after->get("rcode"), "refused", 1);
}
// Submit TCP AXFR query and check query counter
@@ -1114,9 +1368,9 @@ TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
// The counters should be initialized to 0.
ConstElementPtr stats_init = server.getStatistics()->
get("zones")->get("_SERVER_");
- expectCounterItem(stats_init->get("request"), "udp", 0);
- expectCounterItem(stats_init->get("request"), "tcp", 0);
expectCounterItem(stats_init->get("opcode"), "query", 0);
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init->get("response"), "truncated", 0);
UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Name("example.com"), RRClass::IN(), RRType::AXFR());
createRequestPacket(request_message, IPPROTO_TCP);
@@ -1125,16 +1379,12 @@ TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
- // After processing the TCP AXFR query, these counters should be
- // incremented:
- // request.tcp, opcode.query
- // and these counters should not be incremented:
- // request.udp, response
+
ConstElementPtr stats_after = server.getStatistics()->
get("zones")->get("_SERVER_");
- expectCounterItem(stats_after->get("request"), "udp", 0);
- expectCounterItem(stats_after->get("request"), "tcp", 1);
expectCounterItem(stats_after->get("opcode"), "query", 1);
+ expectCounterItem(stats_after, "responses", 0);
+ expectCounterItem(stats_after->get("response"), "truncated", 0);
}
// Submit TCP IXFR query and check query counter
@@ -1142,9 +1392,9 @@ TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
// The counters should be initialized to 0.
ConstElementPtr stats_init = server.getStatistics()->
get("zones")->get("_SERVER_");
- expectCounterItem(stats_init->get("request"), "udp", 0);
- expectCounterItem(stats_init->get("request"), "tcp", 0);
expectCounterItem(stats_init->get("opcode"), "query", 0);
+ expectCounterItem(stats_init, "responses", 0);
+ expectCounterItem(stats_init->get("response"), "truncated", 0);
UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Name("example.com"), RRClass::IN(), RRType::IXFR());
createRequestPacket(request_message, IPPROTO_TCP);
@@ -1153,25 +1403,21 @@ TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
server.processMessage(*io_message, *parse_message, *response_obuffer,
&dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
- // After processing the TCP IXFR query, these counters should be
- // incremented:
- // request.tcp, opcode.query
- // and these counters should not be incremented:
- // request.udp, response
+
ConstElementPtr stats_after = server.getStatistics()->
get("zones")->get("_SERVER_");
- expectCounterItem(stats_after->get("request"), "udp", 0);
- expectCounterItem(stats_after->get("request"), "tcp", 1);
expectCounterItem(stats_after->get("opcode"), "query", 1);
+ expectCounterItem(stats_after, "responses", 0);
+ expectCounterItem(stats_after->get("response"), "truncated", 0);
}
TEST_F(AuthSrvTest, queryCounterOpcodes) {
int other_expected = 0;
- for (int i = 0; i < 16; ++i) {
+ for (int i = 0; i < isc::auth::statistics::num_opcode_to_msgcounter; ++i) {
std::string item_name;
int expected;
- if (isc::auth::statistics::opcode_to_qrcounter[i] ==
- isc::auth::statistics::QR_OPCODE_OTHER) {
+ if (isc::auth::statistics::opcode_to_msgcounter[i] ==
+ isc::auth::statistics::MSG_OPCODE_OTHER) {
item_name = "OTHER";
other_expected += i + 1;
expected = other_expected;
diff --git a/src/bin/auth/tests/statistics_unittest.cc.pre b/src/bin/auth/tests/statistics_unittest.cc.pre
index 22881f8..6599853 100644
--- a/src/bin/auth/tests/statistics_unittest.cc.pre
+++ b/src/bin/auth/tests/statistics_unittest.cc.pre
@@ -14,14 +14,13 @@
#include <config.h>
-#include <string>
-
#include <gtest/gtest.h>
#include <boost/bind.hpp>
#include <dns/opcode.h>
#include <dns/rcode.h>
+#include <dns/rrttl.h>
#include <cc/data.h>
#include <cc/session.h>
@@ -31,6 +30,9 @@
#include <dns/tests/unittest_util.h>
+#include <string>
+#include <map>
+
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -54,14 +56,15 @@ protected:
Counters counters;
};
+// flatten counters
void
flatten(std::map<std::string, int>& flat_map, const std::string& prefix,
const isc::data::ConstElementPtr map_element) {
std::map<std::string, ConstElementPtr> map = map_element->mapValue();
for (std::map<std::string, ConstElementPtr>::const_iterator
- i = map.begin(), e = map.end();
- i != e;
- ++i)
+ i = map.begin(), e = map.end();
+ i != e;
+ ++i)
{
switch (i->second->getType()) {
case isc::data::Element::map:
@@ -71,16 +74,17 @@ flatten(std::map<std::string, int>& flat_map, const std::string& prefix,
flat_map[prefix + i->first] = i->second->intValue();
break;
default:
- EXPECT_FALSE("Element Parse Error");
+ FAIL() << "Element Parse Error";
}
}
}
-// Test if the values of the counters are all zero except for the items
-// specified in except_for.
+// Test if the counters has expected values specified in expect and the others
+// are zero.
void
-checkCountersAllZeroExcept(const isc::data::ConstElementPtr counters,
- const std::set<std::string>& except_for) {
+checkCounters(const isc::data::ConstElementPtr counters,
+ const std::map<std::string, int>& expect)
+{
std::map<std::string, int> stats_map;
flatten(stats_map, "", counters);
@@ -89,66 +93,628 @@ checkCountersAllZeroExcept(const isc::data::ConstElementPtr counters,
i != e;
++i)
{
- int expect = 0;
- if (except_for.count(i->first) != 0) {
- expect = 1;
- }
- EXPECT_EQ(expect, i->second) << "Expected counter "
- << i->first << " = " << expect << ", actual: "
+ const int value =
+ expect.find(i->first) == expect.end() ?
+ 0 : expect.find(i->first)->second;
+ EXPECT_EQ(value, i->second) << "Expected counter "
+ << i->first << " = " << value << ", actual: "
<< i->second;
}
}
-TEST_F(CountersTest, incrementNormalQuery) {
+TEST_F(CountersTest, incrementResponse) {
+ Message response(Message::RENDER);
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
+
+ // Test response counters are incremented only if responded == true.
+ for (int i = 0; i < 2; ++i) {
+ const bool responded = i & 1;
+
+ msgattrs.setRequestIPVersion(AF_INET);
+ msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
+ msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
+ msgattrs.setRequestEDNS0(true);
+ msgattrs.setRequestDO(true);
+
+ response.setRcode(Rcode::REFUSED());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::AAAA()));
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
+
+ counters.inc(msgattrs, response, responded);
+
+ expect.clear();
+ expect["opcode.query"] = i+1;
+ expect["request.v4"] = i+1;
+ expect["request.udp"] = i+1;
+ expect["request.edns0"] = i+1;
+ expect["request.badednsver"] = 0;
+ expect["request.dnssec_ok"] = i+1;
+ expect["responses"] = responded ? 1 : 0;
+ expect["qrynoauthans"] = responded ? 1 : 0;
+ expect["rcode.refused"] = responded ? 1 : 0;
+ expect["authqryrej"] = responded ? 1 : 0;
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
+ }
+}
+
+TEST_F(CountersTest, incrementProtocolType) {
+ Message response(Message::RENDER);
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
+
+ // Test these patterns:
+ // af protocol
+ // -----------------
+ // ipv4 udp
+ // ipv6 udp
+ // ipv4 tcp
+ // ipv6 tcp
+ int count_v4 = 0, count_v6 = 0, count_udp = 0, count_tcp = 0;
+ for (int i = 0; i < 4; ++i) {
+ const int af = i & 1 ? AF_INET : AF_INET6;
+ const int proto = i & 2 ? IPPROTO_UDP : IPPROTO_TCP;
+
+ msgattrs.setRequestIPVersion(af);
+ msgattrs.setRequestTransportProtocol(proto);
+ msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
+ msgattrs.setRequestEDNS0(true);
+ msgattrs.setRequestDO(true);
+
+ response.setRcode(Rcode::REFUSED());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::AAAA()));
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
+
+ counters.inc(msgattrs, response, true);
+
+ if (af == AF_INET) {
+ ++count_v4;
+ } else {
+ ++count_v6;
+ }
+ if (proto == IPPROTO_UDP) {
+ ++count_udp;
+ } else {
+ ++count_tcp;
+ }
+
+ expect.clear();
+ expect["opcode.query"] = i+1;
+ expect["request.v4"] = count_v4;
+ expect["request.v6"] = count_v6;
+ expect["request.udp"] = count_udp;
+ expect["request.tcp"] = count_tcp;
+ expect["request.edns0"] = i+1;
+ expect["request.badednsver"] = 0;
+ expect["request.dnssec_ok"] = i+1;
+ expect["responses"] = i+1;
+ expect["qrynoauthans"] = i+1;
+ expect["rcode.refused"] = i+1;
+ expect["authqryrej"] = i+1;
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
+ }
+}
+
+TEST_F(CountersTest, incrementDO) {
+ Message response(Message::RENDER);
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
+
+ // Test these patterns:
+ // DNSSEC OK
+ // -----------
+ // false
+ // true
+ for (int i = 0; i < 2; ++i) {
+ const bool is_dnssec_ok = i & 1;
+ msgattrs.setRequestIPVersion(AF_INET);
+ msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
+ msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
+ msgattrs.setRequestEDNS0(true);
+ msgattrs.setRequestDO(is_dnssec_ok);
+
+ response.setRcode(Rcode::REFUSED());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::AAAA()));
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
+
+ counters.inc(msgattrs, response, true);
+
+ expect.clear();
+ expect["opcode.query"] = i+1;
+ expect["request.v4"] = i+1;
+ expect["request.udp"] = i+1;
+ expect["request.edns0"] = i+1;
+ expect["request.badednsver"] = 0;
+ expect["request.dnssec_ok"] = i & 1;
+ expect["responses"] = i+1;
+ expect["qrynoauthans"] = i+1;
+ expect["rcode.refused"] = i+1;
+ expect["authqryrej"] = i+1;
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
+ }
+}
+
+TEST_F(CountersTest, incrementEDNS) {
+ Message response(Message::RENDER);
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
+
+ // Test these patterns:
+ // request edns0 response edns0
+ // --------------------------------
+ // false true
+ // true false
+ //
+ // They can't be both true since edns0 and badednsver are exclusive.
+ int count_req_edns0 = 0, count_res_edns0 = 0;
+ for (int i = 0; i < 2; ++i) {
+ const bool is_edns0 = i & 1;
+ msgattrs.setRequestIPVersion(AF_INET);
+ msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
+ msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
+ msgattrs.setRequestEDNS0(is_edns0);
+ msgattrs.setRequestDO(true);
+
+ if (!is_edns0) {
+ ConstEDNSPtr edns = EDNSPtr(new EDNS(0));
+ response.setEDNS(edns);
+ } else {
+ response.setEDNS(EDNSPtr());
+ }
+ response.setRcode(Rcode::REFUSED());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::AAAA()));
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
+
+ counters.inc(msgattrs, response, true);
+
+ if (is_edns0) {
+ ++count_req_edns0;
+ } else {
+ ++count_res_edns0;
+ }
+
+ expect.clear();
+ expect["opcode.query"] = i+1;
+ expect["request.v4"] = i+1;
+ expect["request.udp"] = i+1;
+ expect["request.edns0"] = count_req_edns0;
+ expect["response.edns0"] = count_res_edns0;
+ expect["request.badednsver"] = 0;
+ expect["request.dnssec_ok"] = i+1;
+ expect["responses"] = i+1;
+ expect["qrynoauthans"] = i+1;
+ expect["rcode.refused"] = i+1;
+ expect["authqryrej"] = i+1;
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
+ }
+}
+
+TEST_F(CountersTest, incrementTSIG) {
+ Message response(Message::RENDER);
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
+
+ // Test these patterns:
+ // signature badsig
+ // -------------------
+ // (none) false
+ // TSIG false
+ // TSIG true
+ // SIG(0) false
+ // SIG(0) true
+ //
+ // badsig can't be true if the message does not have signature.
+ int count_req_tsig = 0, count_res_tsig = 0, count_req_sig0 = 0,
+ count_badsig = 0;
+ for (int i = 0; i < 5; ++i) {
+ const bool is_tsig = (i == 0 ? i : i+1) & 2;
+ const bool is_sig0 = (i == 0 ? i : i+1) & 4;
+ const bool is_badsig = (i == 0 ? i : i+1) & 1;
+ msgattrs.setRequestIPVersion(AF_INET);
+ msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
+ msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
+ msgattrs.setRequestEDNS0(true);
+ msgattrs.setRequestDO(true);
+ msgattrs.setRequestSig(is_tsig, is_sig0, is_badsig);
+
+ response.setRcode(Rcode::REFUSED());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::AAAA()));
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
+
+ // don't increment response counters if signature is bad
+ counters.inc(msgattrs, response, !is_badsig);
+
+ if (is_tsig) {
+ ++count_req_tsig;
+ if (!is_badsig) {
+ ++count_res_tsig;
+ }
+ }
+ if (is_sig0) {
+ ++count_req_sig0;
+ }
+ if (is_badsig) {
+ ++count_badsig;
+ }
+
+ expect.clear();
+ expect["request.v4"] = i+1;
+ expect["request.udp"] = i+1;
+ expect["opcode.query"] = i+1 - count_badsig;
+ expect["request.edns0"] = i+1 - count_badsig;
+ expect["request.badednsver"] = 0;
+ expect["request.dnssec_ok"] = i+1 - count_badsig;
+ expect["request.tsig"] = count_req_tsig;
+ expect["response.tsig"] = count_res_tsig;
+ expect["request.sig0"] = count_req_sig0;
+ expect["request.badsig"] = count_badsig;
+ expect["responses"] = i+1 - count_badsig;
+ expect["qrynoauthans"] = i+1 - count_badsig;
+ expect["rcode.refused"] = i+1 - count_badsig;
+ expect["authqryrej"] = i+1 - count_badsig;
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
+ }
+}
+
+TEST_F(CountersTest, incrementOpcode) {
Message response(Message::RENDER);
- QRAttributes qrattrs;
- std::set<std::string> expect_nonzero;
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
- expect_nonzero.clear();
- checkCountersAllZeroExcept(counters.get()->get("zones")->get("_SERVER_"),
- expect_nonzero);
+ // Test all opcodes (QUERY..RESERVED15)
+ int count_all = 0, count_opcode_other = 0;
+ for (uint8_t i = Opcode::QUERY().getCode(),
+ e = Opcode::RESERVED15().getCode();
+ i <= e;
+ ++i)
+ {
+ msgattrs.setRequestIPVersion(AF_INET);
+ msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
+ msgattrs.setRequestOpCode(i);
+ msgattrs.setRequestEDNS0(true);
+ msgattrs.setRequestDO(true);
+ msgattrs.setRequestSig(false, false, false);
+
+ response.setRcode(Rcode::REFUSED());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::AAAA()));
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
+
+ for (uint8_t j = 0; j < i; ++j) {
+ // count up i times for i-th opcode to identify counters
+ counters.inc(msgattrs, response, true);
+ ++count_all;
+ }
+
+ expect.clear();
+ expect["request.v4"] = count_all;
+ expect["request.udp"] = count_all;
+ expect["request.edns0"] = count_all;
+ expect["request.badednsver"] = 0;
+ expect["request.dnssec_ok"] = count_all;
+ expect["request.tsig"] = 0;
+ expect["request.sig0"] = 0;
+ expect["request.badsig"] = 0;
+ expect["responses"] = count_all;
+ expect["rcode.refused"] = count_all;
+ if (opcode_to_msgcounter[i] == MSG_OPCODE_OTHER) {
+ count_opcode_other += i;
+ }
+ for (uint8_t j = 0; j <= i; ++j) {
+ if (opcode_to_msgcounter[j] == MSG_OPCODE_OTHER) {
+ expect["opcode.other"] = count_opcode_other;
+ } else {
+ std::string code_text = Opcode(j).toText();
+ std::transform(code_text.begin(), code_text.end(),
+ code_text.begin(), ::tolower);
+ expect["opcode."+code_text] = j;
+ }
+ }
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
+ }
+}
+
+TEST_F(CountersTest, incrementRcode) {
+ Message response(Message::RENDER);
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
+
+ // Test all rcodes (NOERROR..BADVERS)
+ int count_all = 0, count_rcode_other = 0, count_ednsbadver = 0;
+ for (uint16_t i = Rcode::NOERROR().getCode(),
+ e = Rcode::BADVERS().getCode();
+ i <= e;
+ ++i)
+ {
+ msgattrs.setRequestIPVersion(AF_INET);
+ msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
+ msgattrs.setRequestOpCode(Opcode::IQUERY_CODE);
+ msgattrs.setRequestEDNS0(true);
+ msgattrs.setRequestDO(true);
+ msgattrs.setRequestSig(false, false, false);
+
+ response.setRcode(Rcode(i));
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::AAAA()));
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
+
+ for (uint16_t j = 0; j < i; ++j) {
+ // count up i times for i-th rcode to identify counters
+ counters.inc(msgattrs, response, true);
+ ++count_all;
+ }
+
+ expect.clear();
+ expect["opcode.iquery"] = count_all;
+ expect["request.v4"] = count_all;
+ expect["request.udp"] = count_all;
+ expect["request.edns0"] = count_all;
+ expect["request.dnssec_ok"] = count_all;
+ expect["request.tsig"] = 0;
+ expect["request.sig0"] = 0;
+ expect["request.badsig"] = 0;
+ expect["responses"] = count_all;
+ if (rcode_to_msgcounter[i] == MSG_RCODE_OTHER) {
+ count_rcode_other += i;
+ }
+ // "request.badednsver" counts for Rcode == BADVERS
+ if (rcode_to_msgcounter[i] == MSG_RCODE_BADVERS) {
+ count_ednsbadver += i;
+ }
+ expect["request.badednsver"] = count_ednsbadver;
+ for (uint16_t j = 0; j <= i; ++j) {
+ if (rcode_to_msgcounter[j] == MSG_RCODE_OTHER) {
+ expect["rcode.other"] = count_rcode_other;
+ } else {
+ std::string code_text = Rcode(j).toText();
+ std::transform(code_text.begin(), code_text.end(),
+ code_text.begin(), ::tolower);
+ expect["rcode."+code_text] = j;
+ }
+ }
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
+ }
+}
+
+TEST_F(CountersTest, incrementTruncated) {
+ Message response(Message::RENDER);
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
+
+ // Test these patterns:
+ // truncated
+ // -----------
+ // false
+ // true
+ int count_truncated = 0;
+ for (int i = 0; i < 2; ++i) {
+ const bool is_truncated = i & 1;
+ msgattrs.setRequestIPVersion(AF_INET);
+ msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
+ msgattrs.setRequestOpCode(Opcode::IQUERY_CODE);
+ msgattrs.setRequestEDNS0(true);
+ msgattrs.setRequestDO(true);
+ msgattrs.setRequestSig(false, false, false);
+ msgattrs.setResponseTruncated(is_truncated);
+
+ response.setRcode(Rcode::SERVFAIL());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::TXT()));
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
+
+ counters.inc(msgattrs, response, true);
+
+ if (is_truncated) {
+ ++count_truncated;
+ }
+
+ expect.clear();
+ expect["opcode.iquery"] = i+1;
+ expect["request.v4"] = i+1;
+ expect["request.udp"] = i+1;
+ expect["request.edns0"] = i+1;
+ expect["request.dnssec_ok"] = i+1;
+ expect["responses"] = i+1;
+ expect["rcode.servfail"] = i+1;
+ expect["response.truncated"] = count_truncated;
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
+ }
+}
+
+TEST_F(CountersTest, incrementQryAuthAnsAndNoAuthAns) {
+ Message response(Message::RENDER);
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
+
+ // Opcode = QUERY, ANCOUNT = 0 (don't care), Rcode = SERVFAIL (don't care)
+ // Test these patterns:
+ // AA flag
+ // -----------------------
+ // false -> QryNoAuthAns
+ // true -> QryAuthAns
+ int count_authans = 0, count_noauthans = 0;
+ for (int i = 0; i < 2; ++i) {
+ const bool is_aa_set = i & 1;
+ msgattrs.setRequestIPVersion(AF_INET);
+ msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
+ msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
+ msgattrs.setRequestEDNS0(true);
+ msgattrs.setRequestDO(true);
+ msgattrs.setRequestSig(false, false, false);
+
+ response.setRcode(Rcode::SERVFAIL());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::TXT()));
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
+ if (is_aa_set) {
+ response.setHeaderFlag(Message::HEADERFLAG_AA);
+ ++count_authans;
+ } else {
+ ++count_noauthans;
+ }
+
+ counters.inc(msgattrs, response, true);
+
+ expect.clear();
+ expect["opcode.query"] = i+1;
+ expect["request.v4"] = i+1;
+ expect["request.udp"] = i+1;
+ expect["request.edns0"] = i+1;
+ expect["request.dnssec_ok"] = i+1;
+ expect["responses"] = i+1;
+ expect["rcode.servfail"] = i+1;
+ expect["qryauthans"] = count_authans;
+ expect["qrynoauthans"] = count_noauthans;
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
+ }
+}
+
+TEST_F(CountersTest, incrementQrySuccess) {
+ Message response(Message::RENDER);
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
+
+ // Opcode = QUERY, Rcode = NOERROR, ANCOUNT > 0
+ msgattrs.setRequestIPVersion(AF_INET);
+ msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
+ msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
+ msgattrs.setRequestEDNS0(true);
+ msgattrs.setRequestDO(true);
+ msgattrs.setRequestSig(false, false, false);
+
+ response.setRcode(Rcode::NOERROR());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::TXT()));
+ RRsetPtr answer_rrset(new RRset(Name("example.com"),
+ RRClass::IN(), RRType::TXT(),
+ RRTTL(3600)));
+ answer_rrset->addRdata(rdata::createRdata(RRType::TXT(),
+ RRClass::IN(),
+ "Answer"));
+ response.addRRset(Message::SECTION_ANSWER, answer_rrset);
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
+
+ counters.inc(msgattrs, response, true);
+
+ expect.clear();
+ expect["opcode.query"] = 1;
+ expect["request.v4"] = 1;
+ expect["request.udp"] = 1;
+ expect["request.edns0"] = 1;
+ expect["request.dnssec_ok"] = 1;
+ expect["responses"] = 1;
+ expect["rcode.noerror"] = 1;
+ expect["qrysuccess"] = 1;
+ // noauthans is also incremented
+ expect["qrynoauthans"] = 1;
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
+}
+
+TEST_F(CountersTest, incrementQryReferralAndNxrrset) {
+ Message response(Message::RENDER);
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
+
+ // Opcode = QUERY, Rcode = NOERROR, ANCOUNT = 0
+ // Test these patterns:
+ // AA flag
+ // ----------------------
+ // false -> QryReferral
+ // true -> QryNxrrset
+ int count_referral = 0, count_nxrrset = 0;
+ for (int i = 0; i < 2; ++i) {
+ const bool is_aa_set = i & 1;
+ msgattrs.setRequestIPVersion(AF_INET);
+ msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
+ msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
+ msgattrs.setRequestEDNS0(true);
+ msgattrs.setRequestDO(true);
+ msgattrs.setRequestSig(false, false, false);
+
+ response.setRcode(Rcode::NOERROR());
+ response.addQuestion(Question(Name("example.com"),
+ RRClass::IN(), RRType::TXT()));
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
+ if (is_aa_set) {
+ response.setHeaderFlag(Message::HEADERFLAG_AA);
+ ++count_nxrrset;
+ } else {
+ ++count_referral;
+ }
+
+ counters.inc(msgattrs, response, true);
+
+ expect.clear();
+ expect["opcode.query"] = i+1;
+ expect["request.v4"] = i+1;
+ expect["request.udp"] = i+1;
+ expect["request.edns0"] = i+1;
+ expect["request.dnssec_ok"] = i+1;
+ expect["responses"] = i+1;
+ expect["rcode.noerror"] = i+1;
+ expect["qrynxrrset"] = count_nxrrset;
+ expect["qryreferral"] = count_referral;
+ // qryauthans or qrynoauthans is also incremented
+ expect["qryauthans"] = count_nxrrset;
+ expect["qrynoauthans"] = count_referral;
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
+ }
+}
+
+TEST_F(CountersTest, incrementAuthQryRej) {
+ Message response(Message::RENDER);
+ MessageAttributes msgattrs;
+ std::map<std::string, int> expect;
- qrattrs.setQueryIPVersion(AF_INET6);
- qrattrs.setQueryTransportProtocol(IPPROTO_UDP);
- qrattrs.setQueryOpCode(Opcode::QUERY_CODE);
- qrattrs.setQueryEDNS(true, false);
- qrattrs.setQueryDO(true);
+ // Opcode = QUERY, Rcode = REFUSED, ANCOUNT = 0 (don't care)
+ msgattrs.setRequestIPVersion(AF_INET);
+ msgattrs.setRequestTransportProtocol(IPPROTO_UDP);
+ msgattrs.setRequestOpCode(Opcode::QUERY_CODE);
+ msgattrs.setRequestEDNS0(true);
+ msgattrs.setRequestDO(true);
+ msgattrs.setRequestSig(false, false, false);
response.setRcode(Rcode::REFUSED());
response.addQuestion(Question(Name("example.com"),
- RRClass::IN(), RRType::AAAA()));
+ RRClass::IN(), RRType::TXT()));
+ response.setHeaderFlag(Message::HEADERFLAG_QR);
- counters.inc(qrattrs, response, true);
+ counters.inc(msgattrs, response, true);
- expect_nonzero.clear();
- expect_nonzero.insert("opcode.query");
- expect_nonzero.insert("request.v6");
- expect_nonzero.insert("request.udp");
- expect_nonzero.insert("request.edns0");
- expect_nonzero.insert("request.dnssec_ok");
- expect_nonzero.insert("responses");
- expect_nonzero.insert("qrynoauthans");
- expect_nonzero.insert("rcode.refused");
- expect_nonzero.insert("authqryrej");
- checkCountersAllZeroExcept(counters.get()->get("zones")->get("_SERVER_"),
- expect_nonzero);
+ expect.clear();
+ expect["opcode.query"] = 1;
+ expect["request.v4"] = 1;
+ expect["request.udp"] = 1;
+ expect["request.edns0"] = 1;
+ expect["request.dnssec_ok"] = 1;
+ expect["responses"] = 1;
+ expect["rcode.refused"] = 1;
+ expect["authqryrej"] = 1;
+ // noauthans is also incremented since AA bit is not set
+ expect["qrynoauthans"] = 1;
+ checkCounters(counters.get()->get("zones")->get("_SERVER_"), expect);
}
int
-countTreeElements(const struct CounterTypeTree* tree) {
+countTreeElements(const struct CounterSpec* tree) {
int count = 0;
for (int i = 0; tree[i].name != NULL; ++i) {
- if (tree[i].sub_tree == NULL) {
+ if (tree[i].sub_counters == NULL) {
++count;
} else {
- count += countTreeElements(tree[i].sub_tree);
+ count += countTreeElements(tree[i].sub_counters);
}
}
return (count);
}
-TEST(StatisticsItemsTest, QRItemNamesCheck) {
- EXPECT_EQ(QR_COUNTER_TYPES, countTreeElements(QRCounterTree));
+TEST(StatisticsItemsTest, MSGItemNamesCheck) {
+ EXPECT_EQ(MSG_COUNTER_TYPES, countTreeElements(msg_counter_tree));
}
}
diff --git a/tests/lettuce/configurations/example.org.inmem.config b/tests/lettuce/configurations/example.org.inmem.config
index 7ea34b3..48f4379 100644
--- a/tests/lettuce/configurations/example.org.inmem.config
+++ b/tests/lettuce/configurations/example.org.inmem.config
@@ -26,9 +26,12 @@
]
}
},
+ "Stats": {
+ },
"Boss": {
"components": {
"b10-auth": { "kind": "needed", "special": "auth" },
+ "b10-stats": { "address": "Stats", "kind": "dispensable" },
"b10-cmdctl": { "special": "cmdctl", "kind": "needed" }
}
}
diff --git a/tests/lettuce/features/queries.feature b/tests/lettuce/features/queries.feature
index 7ae2284..834b425 100644
--- a/tests/lettuce/features/queries.feature
+++ b/tests/lettuce/features/queries.feature
@@ -8,15 +8,59 @@ Feature: Querying feature
And wait for bind10 stderr message BIND10_STARTED_CC
And wait for bind10 stderr message CMDCTL_STARTED
And wait for bind10 stderr message AUTH_SERVER_STARTED
+ And wait for bind10 stderr message STATS_STARTING
bind10 module Auth should be running
+ And bind10 module Stats should be running
And bind10 module Resolver should not be running
And bind10 module Xfrout should not be running
And bind10 module Zonemgr should not be running
And bind10 module Xfrin should not be running
- And bind10 module Stats should not be running
And bind10 module StatsHttpd should not be running
+ When I query statistics zones of bind10 module Auth
+ last bindctl output should not contain "error"
+ Then the statistics counter v4 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter v6 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter udp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tcp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badednsver in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter dnssec_ok in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter query in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter iquery in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter status in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter notify in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter update in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter responses for the zone _SERVER_ should be 0
+ Then the statistics counter truncated in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter qrysuccess for the zone _SERVER_ should be 0
+ Then the statistics counter qryauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qrynoauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qryreferral for the zone _SERVER_ should be 0
+ Then the statistics counter qrynxrrset for the zone _SERVER_ should be 0
+ Then the statistics counter authqryrej for the zone _SERVER_ should be 0
+ Then the statistics counter noerror in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter formerr in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter servfail in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notimp in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter refused in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notauth in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notzone in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter badvers in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category rcode for the zone _SERVER_ should be 0
+
A query for www.example.org should have rcode NOERROR
The last query response should have flags qr aa rd
The last query response should have ancount 1
@@ -38,6 +82,53 @@ Feature: Querying feature
ns2.example.org. 3600 IN A 192.0.2.4
"""
+ And wait for new bind10 stderr message STATS_SEND_STATISTICS_REQUEST
+ And wait for new bind10 stderr message AUTH_RECEIVED_COMMAND
+
+ When I query statistics zones of bind10 module Auth
+ last bindctl output should not contain "error"
+ Then the statistics counter v4 in the category request for the zone _SERVER_ should be 1
+ Then the statistics counter v6 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter udp in the category request for the zone _SERVER_ should be 1
+ Then the statistics counter tcp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badednsver in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter dnssec_ok in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter query in the category opcode for the zone _SERVER_ should be 1
+ Then the statistics counter iquery in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter status in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter notify in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter update in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter responses for the zone _SERVER_ should be 1
+ Then the statistics counter truncated in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter qrysuccess for the zone _SERVER_ should be 1
+ Then the statistics counter qryauthans for the zone _SERVER_ should be 1
+ Then the statistics counter qrynoauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qryreferral for the zone _SERVER_ should be 0
+ Then the statistics counter qrynxrrset for the zone _SERVER_ should be 0
+ Then the statistics counter authqryrej for the zone _SERVER_ should be 0
+ Then the statistics counter noerror in the category rcode for the zone _SERVER_ should be 1
+ Then the statistics counter formerr in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter servfail in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notimp in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter refused in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notauth in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notzone in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter badvers in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category rcode for the zone _SERVER_ should be 0
+
+
# Repeat of the above
A query for www.example.org should have rcode NOERROR
The last query response should have flags qr aa rd
@@ -60,6 +151,52 @@ Feature: Querying feature
ns2.example.org. 3600 IN A 192.0.2.4
"""
+ And wait for new bind10 stderr message STATS_SEND_STATISTICS_REQUEST
+ And wait for new bind10 stderr message AUTH_RECEIVED_COMMAND
+
+ When I query statistics zones of bind10 module Auth
+ last bindctl output should not contain "error"
+ Then the statistics counter v4 in the category request for the zone _SERVER_ should be 2
+ Then the statistics counter v6 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter udp in the category request for the zone _SERVER_ should be 2
+ Then the statistics counter tcp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badednsver in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter dnssec_ok in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter query in the category opcode for the zone _SERVER_ should be 2
+ Then the statistics counter iquery in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter status in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter notify in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter update in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter responses for the zone _SERVER_ should be 2
+ Then the statistics counter truncated in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter qrysuccess for the zone _SERVER_ should be 2
+ Then the statistics counter qryauthans for the zone _SERVER_ should be 2
+ Then the statistics counter qrynoauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qryreferral for the zone _SERVER_ should be 0
+ Then the statistics counter qrynxrrset for the zone _SERVER_ should be 0
+ Then the statistics counter authqryrej for the zone _SERVER_ should be 0
+ Then the statistics counter noerror in the category rcode for the zone _SERVER_ should be 2
+ Then the statistics counter formerr in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter servfail in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notimp in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter refused in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notauth in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notzone in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter badvers in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category rcode for the zone _SERVER_ should be 0
+
# And now query something completely different
A query for nosuchname.example.org should have rcode NXDOMAIN
The last query response should have flags qr aa rd
@@ -71,6 +208,52 @@ Feature: Querying feature
example.org. 3600 IN SOA ns1.example.org. admin.example.org. 1234 3600 1800 2419200 7200
"""
+ And wait for new bind10 stderr message STATS_SEND_STATISTICS_REQUEST
+ And wait for new bind10 stderr message AUTH_RECEIVED_COMMAND
+
+ When I query statistics zones of bind10 module Auth
+ last bindctl output should not contain "error"
+ Then the statistics counter v4 in the category request for the zone _SERVER_ should be 3
+ Then the statistics counter v6 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter udp in the category request for the zone _SERVER_ should be 3
+ Then the statistics counter tcp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badednsver in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter dnssec_ok in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter query in the category opcode for the zone _SERVER_ should be 3
+ Then the statistics counter iquery in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter status in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter notify in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter update in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter responses for the zone _SERVER_ should be 3
+ Then the statistics counter truncated in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter qrysuccess for the zone _SERVER_ should be 2
+ Then the statistics counter qryauthans for the zone _SERVER_ should be 3
+ Then the statistics counter qrynoauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qryreferral for the zone _SERVER_ should be 0
+ Then the statistics counter qrynxrrset for the zone _SERVER_ should be 0
+ Then the statistics counter authqryrej for the zone _SERVER_ should be 0
+ Then the statistics counter noerror in the category rcode for the zone _SERVER_ should be 2
+ Then the statistics counter formerr in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter servfail in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxdomain in the category rcode for the zone _SERVER_ should be 1
+ Then the statistics counter notimp in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter refused in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notauth in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notzone in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter badvers in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category rcode for the zone _SERVER_ should be 0
+
Scenario: ANY query
Given I have bind10 running with configuration example.org.inmem.config
And wait for bind10 stderr message BIND10_STARTED_CC
@@ -78,13 +261,56 @@ Feature: Querying feature
And wait for bind10 stderr message AUTH_SERVER_STARTED
bind10 module Auth should be running
+ And bind10 module Stats should be running
And bind10 module Resolver should not be running
And bind10 module Xfrout should not be running
And bind10 module Zonemgr should not be running
And bind10 module Xfrin should not be running
- And bind10 module Stats should not be running
And bind10 module StatsHttpd should not be running
+ When I query statistics zones of bind10 module Auth
+ last bindctl output should not contain "error"
+ Then the statistics counter v4 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter v6 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter udp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tcp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badednsver in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter dnssec_ok in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter query in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter iquery in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter status in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter notify in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter update in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter responses for the zone _SERVER_ should be 0
+ Then the statistics counter truncated in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter qrysuccess for the zone _SERVER_ should be 0
+ Then the statistics counter qryauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qrynoauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qryreferral for the zone _SERVER_ should be 0
+ Then the statistics counter qrynxrrset for the zone _SERVER_ should be 0
+ Then the statistics counter authqryrej for the zone _SERVER_ should be 0
+ Then the statistics counter noerror in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter formerr in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter servfail in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notimp in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter refused in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notauth in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notzone in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter badvers in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category rcode for the zone _SERVER_ should be 0
+
A query for example.org type ANY should have rcode NOERROR
The last query response should have flags qr aa rd
The last query response should have ancount 4
@@ -104,11 +330,101 @@ Feature: Querying feature
mail.example.org. 3600 IN A 192.0.2.10
"""
+ And wait for new bind10 stderr message STATS_SEND_STATISTICS_REQUEST
+ And wait for new bind10 stderr message AUTH_RECEIVED_COMMAND
+
+ When I query statistics zones of bind10 module Auth
+ last bindctl output should not contain "error"
+ Then the statistics counter v4 in the category request for the zone _SERVER_ should be 1
+ Then the statistics counter v6 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter udp in the category request for the zone _SERVER_ should be 1
+ Then the statistics counter tcp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badednsver in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter dnssec_ok in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter query in the category opcode for the zone _SERVER_ should be 1
+ Then the statistics counter iquery in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter status in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter notify in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter update in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter responses for the zone _SERVER_ should be 1
+ Then the statistics counter truncated in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter qrysuccess for the zone _SERVER_ should be 1
+ Then the statistics counter qryauthans for the zone _SERVER_ should be 1
+ Then the statistics counter qrynoauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qryreferral for the zone _SERVER_ should be 0
+ Then the statistics counter qrynxrrset for the zone _SERVER_ should be 0
+ Then the statistics counter authqryrej for the zone _SERVER_ should be 0
+ Then the statistics counter noerror in the category rcode for the zone _SERVER_ should be 1
+ Then the statistics counter formerr in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter servfail in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notimp in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter refused in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notauth in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notzone in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter badvers in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category rcode for the zone _SERVER_ should be 0
+
Scenario: Delegation query for unsigned child zone
Given I have bind10 running with configuration example.org.inmem.config
And wait for bind10 stderr message BIND10_STARTED_CC
And wait for bind10 stderr message CMDCTL_STARTED
And wait for bind10 stderr message AUTH_SERVER_STARTED
+
+ When I query statistics zones of bind10 module Auth
+ last bindctl output should not contain "error"
+ Then the statistics counter v4 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter v6 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter udp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tcp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badednsver in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter dnssec_ok in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter query in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter iquery in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter status in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter notify in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter update in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter responses for the zone _SERVER_ should be 0
+ Then the statistics counter truncated in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter qrysuccess for the zone _SERVER_ should be 0
+ Then the statistics counter qryauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qrynoauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qryreferral for the zone _SERVER_ should be 0
+ Then the statistics counter qrynxrrset for the zone _SERVER_ should be 0
+ Then the statistics counter authqryrej for the zone _SERVER_ should be 0
+ Then the statistics counter noerror in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter formerr in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter servfail in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notimp in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter refused in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notauth in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notzone in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter badvers in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category rcode for the zone _SERVER_ should be 0
+
A dnssec query for www.sub.example.org type AAAA should have rcode NOERROR
The last query response should have flags qr rd
The last query response should have edns_flags do
@@ -124,6 +440,52 @@ Feature: Querying feature
ns.sub.example.org. 3600 IN A 192.0.2.101
"""
+ And wait for new bind10 stderr message STATS_SEND_STATISTICS_REQUEST
+ And wait for new bind10 stderr message AUTH_RECEIVED_COMMAND
+
+ When I query statistics zones of bind10 module Auth
+ last bindctl output should not contain "error"
+ Then the statistics counter v4 in the category request for the zone _SERVER_ should be 1
+ Then the statistics counter v6 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter udp in the category request for the zone _SERVER_ should be 1
+ Then the statistics counter tcp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category request for the zone _SERVER_ should be 1
+ Then the statistics counter badednsver in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter dnssec_ok in the category request for the zone _SERVER_ should be 1
+ Then the statistics counter query in the category opcode for the zone _SERVER_ should be 1
+ Then the statistics counter iquery in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter status in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter notify in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter update in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter responses for the zone _SERVER_ should be 1
+ Then the statistics counter truncated in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category response for the zone _SERVER_ should be 1
+ Then the statistics counter tsig in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter qrysuccess for the zone _SERVER_ should be 0
+ Then the statistics counter qryauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qrynoauthans for the zone _SERVER_ should be 1
+ Then the statistics counter qryreferral for the zone _SERVER_ should be 1
+ Then the statistics counter qrynxrrset for the zone _SERVER_ should be 0
+ Then the statistics counter authqryrej for the zone _SERVER_ should be 0
+ Then the statistics counter noerror in the category rcode for the zone _SERVER_ should be 1
+ Then the statistics counter formerr in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter servfail in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notimp in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter refused in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notauth in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notzone in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter badvers in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category rcode for the zone _SERVER_ should be 0
+
Scenario: SSHFP query
# We are testing one more RR type for a normal successful case
Given I have bind10 running with configuration example.org.inmem.config
@@ -132,18 +494,151 @@ Feature: Querying feature
And wait for bind10 stderr message AUTH_SERVER_STARTED
bind10 module Auth should be running
+ And bind10 module Stats should be running
And bind10 module Resolver should not be running
And bind10 module Xfrout should not be running
And bind10 module Zonemgr should not be running
And bind10 module Xfrin should not be running
- And bind10 module Stats should not be running
And bind10 module StatsHttpd should not be running
+ When I query statistics zones of bind10 module Auth
+ last bindctl output should not contain "error"
+ Then the statistics counter v4 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter v6 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter udp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tcp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badednsver in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter dnssec_ok in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter query in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter iquery in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter status in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter notify in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter update in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter responses for the zone _SERVER_ should be 0
+ Then the statistics counter truncated in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter qrysuccess for the zone _SERVER_ should be 0
+ Then the statistics counter qryauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qrynoauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qryreferral for the zone _SERVER_ should be 0
+ Then the statistics counter qrynxrrset for the zone _SERVER_ should be 0
+ Then the statistics counter authqryrej for the zone _SERVER_ should be 0
+ Then the statistics counter noerror in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter formerr in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter servfail in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notimp in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter refused in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notauth in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notzone in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter badvers in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category rcode for the zone _SERVER_ should be 0
+
A query for example.org type SSHFP should have rcode NOERROR
The last query response should have ancount 0
+
+ When I query statistics zones of bind10 module Auth
+ last bindctl output should not contain "error"
+ Then the statistics counter v4 in the category request for the zone _SERVER_ should be 1
+ Then the statistics counter v6 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter udp in the category request for the zone _SERVER_ should be 1
+ Then the statistics counter tcp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badednsver in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter dnssec_ok in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter query in the category opcode for the zone _SERVER_ should be 1
+ Then the statistics counter iquery in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter status in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter notify in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter update in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter responses for the zone _SERVER_ should be 1
+ Then the statistics counter truncated in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter qrysuccess for the zone _SERVER_ should be 0
+ Then the statistics counter qryauthans for the zone _SERVER_ should be 1
+ Then the statistics counter qrynoauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qryreferral for the zone _SERVER_ should be 0
+ Then the statistics counter qrynxrrset for the zone _SERVER_ should be 1
+ Then the statistics counter authqryrej for the zone _SERVER_ should be 0
+ Then the statistics counter noerror in the category rcode for the zone _SERVER_ should be 1
+ Then the statistics counter formerr in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter servfail in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notimp in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter refused in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notauth in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notzone in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter badvers in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category rcode for the zone _SERVER_ should be 0
+
A query for shell.example.org type SSHFP should have rcode NOERROR
The last query response should have ancount 1
The answer section of the last query response should be
"""
shell.example.org. 3600 IN SSHFP 2 1 123456789abcdef67890123456789abcdef67890
"""
+
+ And wait for new bind10 stderr message STATS_SEND_STATISTICS_REQUEST
+ And wait for new bind10 stderr message AUTH_RECEIVED_COMMAND
+
+ When I query statistics zones of bind10 module Auth
+ last bindctl output should not contain "error"
+ Then the statistics counter v4 in the category request for the zone _SERVER_ should be 2
+ Then the statistics counter v6 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter udp in the category request for the zone _SERVER_ should be 2
+ Then the statistics counter tcp in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badednsver in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter badsig in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter dnssec_ok in the category request for the zone _SERVER_ should be 0
+ Then the statistics counter query in the category opcode for the zone _SERVER_ should be 2
+ Then the statistics counter iquery in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter status in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter notify in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter update in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category opcode for the zone _SERVER_ should be 0
+ Then the statistics counter responses for the zone _SERVER_ should be 2
+ Then the statistics counter truncated in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter edns0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter tsig in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter sig0 in the category response for the zone _SERVER_ should be 0
+ Then the statistics counter qrysuccess for the zone _SERVER_ should be 1
+ Then the statistics counter qryauthans for the zone _SERVER_ should be 2
+ Then the statistics counter qrynoauthans for the zone _SERVER_ should be 0
+ Then the statistics counter qryreferral for the zone _SERVER_ should be 0
+ Then the statistics counter qrynxrrset for the zone _SERVER_ should be 1
+ Then the statistics counter authqryrej for the zone _SERVER_ should be 0
+ Then the statistics counter noerror in the category rcode for the zone _SERVER_ should be 2
+ Then the statistics counter formerr in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter servfail in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notimp in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter refused in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxdomain in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter yxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter nxrrset in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notauth in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter notzone in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter badvers in the category rcode for the zone _SERVER_ should be 0
+ Then the statistics counter other in the category rcode for the zone _SERVER_ should be 0
diff --git a/tests/lettuce/features/terrain/bind10_control.py b/tests/lettuce/features/terrain/bind10_control.py
index 142a78e..394d18a 100644
--- a/tests/lettuce/features/terrain/bind10_control.py
+++ b/tests/lettuce/features/terrain/bind10_control.py
@@ -391,14 +391,16 @@ def find_value(dictionary, key):
for v in dictionary.values():
return find_value(v, key)
- at step('the statistics counter (\S+)(?: for the zone (\S+))? should be' + \
+ at step('the statistics counter (\S+)(?: in the category (\S+))?'+ \
+ '(?: for the zone (\S+))? should be' + \
'(?:( greater than| less than| between))? (\-?\d+)(?: and (\-?\d+))?')
-def check_statistics(step, counter, zone, gtltbt, number, upper):
+def check_statistics(step, counter, category, zone, gtltbt, number, upper):
"""
check the output of bindctl for statistics of specified counter
and zone.
Parameters:
counter ('counter <counter>'): The counter name of statistics.
+ category ('category <category>', optional): The category of counter.
zone ('zone <zone>', optional): The zone name.
gtltbt (' greater than'|' less than'|' between', optional): greater than
<number> or less than <number> or between <number> and <upper>.
@@ -409,14 +411,22 @@ def check_statistics(step, counter, zone, gtltbt, number, upper):
"""
output = parse_bindctl_output_as_data_structure()
found = None
+ category_str = ""
zone_str = ""
+ depth = []
+ if category:
+ depth.insert(0, category)
+ category_str = " for category %s" % category
if zone:
- found = find_value(find_value(output, zone), counter)
+ depth.insert(0, zone)
zone_str = " for zone %s" % zone
+ for level in depth:
+ output = find_value(output, level)
else:
found = find_value(output, counter)
assert found is not None, \
- 'Not found statistics counter %s%s' % (counter, zone_str)
+ 'Not found statistics counter %s%s%s' % \
+ (counter, category_str, zone_str)
msg = "Got %s, expected%s %s as counter %s%s" % \
(found, gtltbt, number, counter, zone_str)
if gtltbt and 'between' in gtltbt and upper:
diff --git a/tests/system/bindctl/tests.sh b/tests/system/bindctl/tests.sh
index 848c09a..090791c 100755
--- a/tests/system/bindctl/tests.sh
+++ b/tests/system/bindctl/tests.sh
@@ -25,12 +25,66 @@ status=0
n=0
# TODO: consider consistency with statistics definition in auth.spec
-cnt_name1="\<tcp\>"
-cnt_name2="\<udp\>"
-cnt_name3="\<query\>"
-cnt_value1=0
-cnt_value2=0
-cnt_value3=0
+
+# flatten JSON
+awk_flatten_json='
+function join(ary, len) {
+ ret = "";
+ for (i = 1; i <= len; ++i) {
+ ret = ret""ary[i];
+ }
+ return ret;
+}
+BEGIN {
+ depth = 0;
+}
+/.+{$/ {
+ label[++depth] = $1;
+ next;
+}
+/},?/ {
+ --depth;
+ next;
+}
+/:/ {
+ print join(label,depth)""$1" "$2;
+}
+'
+# Check the counters have expected values given with 1st argument.
+# This function tests only these counters will be incremented in every checks
+# since the content of datasource and requests are not changed in this test.
+test_counters () {
+ status=0
+ awk "$awk_flatten_json" bindctl.out.$n | \
+ grep '"Auth":"zones":"_SERVER_":"request":"v4": '$1 > \
+ /dev/null || status=1
+ awk "$awk_flatten_json" bindctl.out.$n | \
+ grep '"Auth":"zones":"_SERVER_":"request":"v6": '0 > \
+ /dev/null || status=1
+ awk "$awk_flatten_json" bindctl.out.$n | \
+ grep '"Auth":"zones":"_SERVER_":"request":"udp": '$1 > \
+ /dev/null || status=1
+ awk "$awk_flatten_json" bindctl.out.$n | \
+ grep '"Auth":"zones":"_SERVER_":"request":"tcp": '0 > \
+ /dev/null || status=1
+ awk "$awk_flatten_json" bindctl.out.$n | \
+ grep '"Auth":"zones":"_SERVER_":"opcode":"query": '$1 > \
+ /dev/null || status=1
+ awk "$awk_flatten_json" bindctl.out.$n | \
+ grep '"Auth":"zones":"_SERVER_":"responses": '$1 > \
+ /dev/null || status=1
+ awk "$awk_flatten_json" bindctl.out.$n | \
+ grep '"Auth":"zones":"_SERVER_":"rcode":"noerror": '$1 > \
+ /dev/null || status=1
+ awk "$awk_flatten_json" bindctl.out.$n | \
+ grep '"Auth":"zones":"_SERVER_":"qrysuccess": '$1 > \
+ /dev/null || status=1
+ awk "$awk_flatten_json" bindctl.out.$n | \
+ grep '"Auth":"zones":"_SERVER_":"qryauthans": '$1 > \
+ /dev/null || status=1
+ return $status
+}
+expected_count=0
echo "I:Checking b10-auth is disabled by default ($n)"
$DIG +norec @10.53.0.1 -p 53210 ns.example.com. A > /dev/null && status=1
@@ -56,15 +110,10 @@ sleep 2
echo 'Stats show
' | $RUN_BINDCTL \
--csv-file-dir=$BINDCTL_CSV_DIR > bindctl.out.$n || status=1
-# the server should have received 1 UDP and 0 TCP queries (the server
-# startup script no longer sends any TCP queries)
-cnt_value1=`expr $cnt_value1 + 0`
-cnt_value2=`expr $cnt_value2 + 1`
-cnt_value3=`expr $cnt_value1 + $cnt_value2`
-grep $cnt_name1".*\<"$cnt_value1"\>" bindctl.out.$n > /dev/null || status=1
-grep $cnt_name2".*\<"$cnt_value2"\>" bindctl.out.$n > /dev/null || status=1
-grep $cnt_name3".*\<"$cnt_value3"\>" bindctl.out.$n > /dev/null || status=1
-if [ $status != 0 ]; then echo "I:failed"; fi
+# the server should have received 1 request
+expected_count=`expr $expected_count + 1`
+test_counters $expected_count
+if [ $? != 0 ]; then echo "I:failed"; fi
n=`expr $n + 1`
echo "I:Stopping b10-auth and checking that ($n)"
@@ -101,13 +150,9 @@ echo 'Stats show
# auth sent. Then it cumulates them and new counts which the living
# auth sends. This note assumes that the issue would have been
# resolved : "#1941 stats lossage (multiple auth servers)".
-cnt_value1=`expr $cnt_value1 + 0`
-cnt_value2=`expr $cnt_value2 + 1`
-cnt_value3=`expr $cnt_value1 + $cnt_value2`
-grep $cnt_name1".*\<"$cnt_value1"\>" bindctl.out.$n > /dev/null || status=1
-grep $cnt_name2".*\<"$cnt_value2"\>" bindctl.out.$n > /dev/null || status=1
-grep $cnt_name3".*\<"$cnt_value3"\>" bindctl.out.$n > /dev/null || status=1
-if [ $status != 0 ]; then echo "I:failed"; fi
+expected_count=`expr $expected_count + 1`
+test_counters $expected_count
+if [ $? != 0 ]; then echo "I:failed"; fi
n=`expr $n + 1`
echo "I:Changing the data source from sqlite3 to in-memory ($n)"
@@ -129,13 +174,9 @@ echo 'Stats show
' | $RUN_BINDCTL \
--csv-file-dir=$BINDCTL_CSV_DIR > bindctl.out.$n || status=1
# The statistics counters shouldn't be reset due to hot-swapping datasource.
-cnt_value1=`expr $cnt_value1 + 0`
-cnt_value2=`expr $cnt_value2 + 1`
-cnt_value3=`expr $cnt_value1 + $cnt_value2`
-grep $cnt_name1".*\<"$cnt_value1"\>" bindctl.out.$n > /dev/null || status=1
-grep $cnt_name2".*\<"$cnt_value2"\>" bindctl.out.$n > /dev/null || status=1
-grep $cnt_name3".*\<"$cnt_value3"\>" bindctl.out.$n > /dev/null || status=1
-if [ $status != 0 ]; then echo "I:failed"; fi
+expected_count=`expr $expected_count + 1`
+test_counters $expected_count
+if [ $? != 0 ]; then echo "I:failed"; fi
n=`expr $n + 1`
echo "I:Starting more b10-auths and checking that ($n)"
@@ -155,9 +196,7 @@ n=`expr $n + 1`
echo "I:Rechecking BIND 10 statistics consistency after a pause ($n)"
sleep 2
-cnt_value1=`expr $cnt_value1 + 0`
-cnt_value2=`expr $cnt_value2 + 1`
-cnt_value3=`expr $cnt_value1 + $cnt_value2`
+expected_count=`expr $expected_count + 1`
# Rechecking some times
for i in 1 2 3 4
do
@@ -167,10 +206,8 @@ do
# The statistics counters should keep being consistent even while
# multiple b10-auths are running.
- grep $cnt_name1".*\<"$cnt_value1"\>" bindctl.out.$n > /dev/null || status=1
- grep $cnt_name2".*\<"$cnt_value2"\>" bindctl.out.$n > /dev/null || status=1
- grep $cnt_name3".*\<"$cnt_value3"\>" bindctl.out.$n > /dev/null || status=1
- if [ $status != 0 ]; then echo "I:failed "; break ; fi
+ test_counters $expected_count
+ if [ $? != 0 ]; then echo "I:failed "; break ; fi
done
n=`expr $n + 1`
More information about the bind10-changes
mailing list