mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-05 10:22:04 -04:00
Merge branch '1232-stats-channel-zone-timers' into 'master'
Resolve "[ISC-support #15166] expose zone timers (reload, refresh, expire) via stats channel" Closes #1232 See merge request isc-projects/bind9!3308
This commit is contained in:
commit
4303fa3880
23 changed files with 870 additions and 190 deletions
4
CHANGES
4
CHANGES
|
|
@ -1,3 +1,7 @@
|
|||
5407. [func] The zone timers are now exported to the statistics
|
||||
channel. Thanks to Paul Frieden, Verizon Media.
|
||||
[GL #1232]
|
||||
|
||||
5406. [func] Added a new logging category "rpz-passthru". It allows
|
||||
RPZ passthru actions to be logged into a separate
|
||||
channel. [GL #54]
|
||||
|
|
|
|||
|
|
@ -775,7 +775,7 @@
|
|||
<xsl:for-each select="views/view">
|
||||
<h3>Zones for View <xsl:value-of select="@name"/></h3>
|
||||
<table class="zones">
|
||||
<thead><tr><th>Name</th><th>Class</th><th>Type</th><th>Serial</th></tr></thead>
|
||||
<thead><tr><th>Name</th><th>Class</th><th>Type</th><th>Serial</th><th>Loaded</th><th>Expires</th><th>Refresh</th></tr></thead>
|
||||
<tbody>
|
||||
<xsl:for-each select="zones/zone">
|
||||
<xsl:variable name="css-class15">
|
||||
|
|
@ -788,7 +788,10 @@
|
|||
<td><xsl:value-of select="@name"/></td>
|
||||
<td><xsl:value-of select="@rdataclass"/></td>
|
||||
<td><xsl:value-of select="type"/></td>
|
||||
<td><xsl:value-of select="serial"/></td></tr>
|
||||
<td><xsl:value-of select="serial"/></td>
|
||||
<td><xsl:value-of select="loaded"/></td>
|
||||
<td><xsl:value-of select="expires"/></td>
|
||||
<td><xsl:value-of select="refresh"/></td></tr>
|
||||
</xsl:for-each>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -1809,6 +1809,43 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
|
|||
}
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* serial */
|
||||
|
||||
/*
|
||||
* Export zone timers to the statistics channel in XML format. For
|
||||
* master zones, only include the loaded time. For slave zones, also
|
||||
* include the expires and refresh times.
|
||||
*/
|
||||
isc_time_t timestamp;
|
||||
|
||||
result = dns_zone_getloadtime(zone, ×tamp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
isc_time_formatISO8601(×tamp, buf, 64);
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "loaded"));
|
||||
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
|
||||
TRY0(xmlTextWriterEndElement(writer));
|
||||
|
||||
if (dns_zone_gettype(zone) == dns_zone_slave) {
|
||||
result = dns_zone_getexpiretime(zone, ×tamp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
isc_time_formatISO8601(×tamp, buf, 64);
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "expires"));
|
||||
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
|
||||
TRY0(xmlTextWriterEndElement(writer));
|
||||
|
||||
result = dns_zone_getrefreshtime(zone, ×tamp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
isc_time_formatISO8601(×tamp, buf, 64);
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "refresh"));
|
||||
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
|
||||
TRY0(xmlTextWriterEndElement(writer));
|
||||
}
|
||||
|
||||
if (statlevel == dns_zonestat_full) {
|
||||
isc_stats_t *zonestats;
|
||||
isc_stats_t *gluecachestats;
|
||||
|
|
@ -2619,6 +2656,40 @@ zone_jsonrender(dns_zone_t *zone, void *arg) {
|
|||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Export zone timers to the statistics channel in JSON format. For
|
||||
* master zones, only include the loaded time. For slave zones, also
|
||||
* include the expires and refresh times.
|
||||
*/
|
||||
|
||||
isc_time_t timestamp;
|
||||
|
||||
result = dns_zone_getloadtime(zone, ×tamp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
isc_time_formatISO8601(×tamp, buf, 64);
|
||||
json_object_object_add(zoneobj, "loaded", json_object_new_string(buf));
|
||||
|
||||
if (dns_zone_gettype(zone) == dns_zone_slave) {
|
||||
result = dns_zone_getexpiretime(zone, ×tamp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
isc_time_formatISO8601(×tamp, buf, 64);
|
||||
json_object_object_add(zoneobj, "expires",
|
||||
json_object_new_string(buf));
|
||||
|
||||
result = dns_zone_getrefreshtime(zone, ×tamp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
isc_time_formatISO8601(×tamp, buf, 64);
|
||||
json_object_object_add(zoneobj, "refresh",
|
||||
json_object_new_string(buf));
|
||||
}
|
||||
|
||||
if (statlevel == dns_zonestat_full) {
|
||||
isc_stats_t *zonestats;
|
||||
isc_stats_t *gluecachestats;
|
||||
|
|
|
|||
|
|
@ -185,10 +185,8 @@ fi
|
|||
# Clean up files left from any potential previous runs
|
||||
if test -f "$systest/clean.sh"
|
||||
then
|
||||
( cd "${systest}" && $SHELL clean.sh "$@" )
|
||||
ret=$?
|
||||
if [ $ret -ne 0 ]; then
|
||||
echowarn "I:$systest:clean.sh script failed with $ret"
|
||||
if ! ( cd "${systest}" && $SHELL clean.sh "$@" ); then
|
||||
echowarn "I:$systest:clean.sh script failed"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
|
@ -196,10 +194,8 @@ fi
|
|||
# Set up any dynamically generated test data
|
||||
if test -f "$systest/setup.sh"
|
||||
then
|
||||
( cd "${systest}" && $SHELL setup.sh "$@" )
|
||||
ret=$?
|
||||
if [ $ret -ne 0 ]; then
|
||||
echowarn "I:$systest:clean.sh script failed with $ret"
|
||||
if ! ( cd "${systest}" && $SHELL setup.sh "$@" ); then
|
||||
echowarn "I:$systest:clean.sh script failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
|
|||
2
bin/tests/system/statschannel/.gitignore
vendored
Normal file
2
bin/tests/system/statschannel/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/.cache/
|
||||
/__pycache__/
|
||||
|
|
@ -12,9 +12,9 @@
|
|||
rm -f traffic traffic.out.* traffic.json.* traffic.xml.*
|
||||
rm -f zones zones.out.* zones.json.* zones.xml.* zones.expect.*
|
||||
rm -f dig.out*
|
||||
rm -f */named.memstats
|
||||
rm -f */named.conf
|
||||
rm -f */named.run*
|
||||
rm -f ns*/named.memstats
|
||||
rm -f ns*/named.conf
|
||||
rm -f ns*/named.run*
|
||||
rm -f ns*/named.lock
|
||||
rm -f ns*/named.stats
|
||||
rm -f xml.*stats json.*stats
|
||||
|
|
@ -24,4 +24,6 @@ rm -f ns*/managed-keys.bind*
|
|||
rm -f ns2/Kdnssec* ns2/dnssec.*.id
|
||||
rm -f ns2/Kmanykeys* ns2/manykeys.*.id
|
||||
rm -f ns2/*.db.signed* ns2/dsset-*. ns2/*.jbk
|
||||
rm -f ns2/core
|
||||
rm -f ns2/dnssec.db.signed* ns2/dsset-dnssec.
|
||||
rm -f ns3/*.db
|
||||
rm -rf ./.cache ./__pycache__
|
||||
|
|
|
|||
107
bin/tests/system/statschannel/conftest.py
Normal file
107
bin/tests/system/statschannel/conftest.py
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
############################################################################
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
############################################################################
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
|
||||
def pytest_configure(config):
|
||||
config.addinivalue_line(
|
||||
"markers", "requests: mark tests that need requests to function"
|
||||
)
|
||||
config.addinivalue_line(
|
||||
"markers", "json: mark tests that need json to function"
|
||||
)
|
||||
config.addinivalue_line(
|
||||
"markers", "xml: mark tests that need xml.etree to function"
|
||||
)
|
||||
config.addinivalue_line(
|
||||
"markers", "dnspython: mark tests that need dnspython to function"
|
||||
)
|
||||
|
||||
|
||||
def pytest_collection_modifyitems(config, items):
|
||||
# pylint: disable=unused-argument,unused-import,too-many-branches
|
||||
# pylint: disable=import-outside-toplevel
|
||||
# Test for requests module
|
||||
skip_requests = pytest.mark.skip(
|
||||
reason="need requests module to run")
|
||||
try:
|
||||
import requests # noqa: F401
|
||||
except ModuleNotFoundError:
|
||||
for item in items:
|
||||
if "requests" in item.keywords:
|
||||
item.add_marker(skip_requests)
|
||||
# Test for json module
|
||||
skip_json = pytest.mark.skip(
|
||||
reason="need json module to run")
|
||||
try:
|
||||
import json # noqa: F401
|
||||
except ModuleNotFoundError:
|
||||
for item in items:
|
||||
if "json" in item.keywords:
|
||||
item.add_marker(skip_json)
|
||||
# Test for xml module
|
||||
skip_xml = pytest.mark.skip(
|
||||
reason="need xml module to run")
|
||||
try:
|
||||
import xml.etree.ElementTree # noqa: F401
|
||||
except ModuleNotFoundError:
|
||||
for item in items:
|
||||
if "xml" in item.keywords:
|
||||
item.add_marker(skip_xml)
|
||||
# Test if JSON statistics channel was enabled
|
||||
no_jsonstats = pytest.mark.skip(
|
||||
reason="need JSON statistics to be enabled")
|
||||
if os.getenv("HAVEJSONSTATS") is None:
|
||||
for item in items:
|
||||
if "json" in item.keywords:
|
||||
item.add_marker(no_jsonstats)
|
||||
# Test if XML statistics channel was enabled
|
||||
no_xmlstats = pytest.mark.skip(
|
||||
reason="need XML statistics to be enabled")
|
||||
if os.getenv("HAVEXMLSTATS") is None:
|
||||
for item in items:
|
||||
if "xml" in item.keywords:
|
||||
item.add_marker(no_xmlstats)
|
||||
# Test for dnspython module
|
||||
skip_dnspython = pytest.mark.skip(
|
||||
reason="need dnspython module to run")
|
||||
try:
|
||||
import dns.query # noqa: F401
|
||||
except ModuleNotFoundError:
|
||||
for item in items:
|
||||
if "dnspython" in item.keywords:
|
||||
item.add_marker(skip_dnspython)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def statsport(request):
|
||||
# pylint: disable=unused-argument
|
||||
env_port = os.getenv("EXTRAPORT1")
|
||||
if port is None:
|
||||
env_port = 5301
|
||||
else:
|
||||
env_port = int(env_port)
|
||||
|
||||
return env_port
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def port(request):
|
||||
# pylint: disable=unused-argument
|
||||
env_port = os.getenv("PORT")
|
||||
if port is None:
|
||||
env_port = 5300
|
||||
else:
|
||||
env_port = int(env_port)
|
||||
|
||||
return env_port
|
||||
95
bin/tests/system/statschannel/generic.py
Normal file
95
bin/tests/system/statschannel/generic.py
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
############################################################################
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
############################################################################
|
||||
|
||||
import helper
|
||||
|
||||
|
||||
def test_zone_timers_primary(fetch_zones, load_timers, **kwargs):
|
||||
|
||||
statsip = kwargs['statsip']
|
||||
statsport = kwargs['statsport']
|
||||
zonedir = kwargs['zonedir']
|
||||
|
||||
zones = fetch_zones(statsip, statsport)
|
||||
|
||||
for zone in zones:
|
||||
(name, loaded, expires, refresh) = load_timers(zone, True)
|
||||
mtime = helper.zone_mtime(zonedir, name)
|
||||
helper.check_zone_timers(loaded, expires, refresh, mtime)
|
||||
|
||||
|
||||
def test_zone_timers_secondary(fetch_zones, load_timers, **kwargs):
|
||||
|
||||
statsip = kwargs['statsip']
|
||||
statsport = kwargs['statsport']
|
||||
zonedir = kwargs['zonedir']
|
||||
|
||||
zones = fetch_zones(statsip, statsport)
|
||||
|
||||
for zone in zones:
|
||||
(name, loaded, expires, refresh) = load_timers(zone, False)
|
||||
mtime = helper.zone_mtime(zonedir, name)
|
||||
helper.check_zone_timers(loaded, expires, refresh, mtime)
|
||||
|
||||
|
||||
def test_zone_with_many_keys(fetch_zones, load_zone, **kwargs):
|
||||
|
||||
statsip = kwargs['statsip']
|
||||
statsport = kwargs['statsport']
|
||||
|
||||
zones = fetch_zones(statsip, statsport)
|
||||
|
||||
for zone in zones:
|
||||
name = load_zone(zone)
|
||||
if name == 'manykeys':
|
||||
helper.check_manykeys(name)
|
||||
|
||||
|
||||
def test_traffic(fetch_traffic, **kwargs):
|
||||
|
||||
statsip = kwargs['statsip']
|
||||
statsport = kwargs['statsport']
|
||||
port = kwargs['port']
|
||||
|
||||
data = fetch_traffic(statsip, statsport)
|
||||
exp = helper.create_expected(data)
|
||||
|
||||
msg = helper.create_msg("short.example.", "TXT")
|
||||
helper.update_expected(exp, "dns-udp-requests-sizes-received-ipv4", msg)
|
||||
ans = helper.udp_query(statsip, port, msg)
|
||||
helper.update_expected(exp, "dns-udp-responses-sizes-sent-ipv4", ans)
|
||||
data = fetch_traffic(statsip, statsport)
|
||||
|
||||
helper.check_traffic(data, exp)
|
||||
|
||||
msg = helper.create_msg("long.example.", "TXT")
|
||||
helper.update_expected(exp, "dns-udp-requests-sizes-received-ipv4", msg)
|
||||
ans = helper.udp_query(statsip, port, msg)
|
||||
helper.update_expected(exp, "dns-udp-responses-sizes-sent-ipv4", ans)
|
||||
data = fetch_traffic(statsip, statsport)
|
||||
|
||||
helper.check_traffic(data, exp)
|
||||
|
||||
msg = helper.create_msg("short.example.", "TXT")
|
||||
helper.update_expected(exp, "dns-tcp-requests-sizes-received-ipv4", msg)
|
||||
ans = helper.tcp_query(statsip, port, msg)
|
||||
helper.update_expected(exp, "dns-tcp-responses-sizes-sent-ipv4", ans)
|
||||
data = fetch_traffic(statsip, statsport)
|
||||
|
||||
helper.check_traffic(data, exp)
|
||||
|
||||
msg = helper.create_msg("long.example.", "TXT")
|
||||
helper.update_expected(exp, "dns-tcp-requests-sizes-received-ipv4", msg)
|
||||
ans = helper.tcp_query(statsip, port, msg)
|
||||
helper.update_expected(exp, "dns-tcp-responses-sizes-sent-ipv4", ans)
|
||||
data = fetch_traffic(statsip, statsport)
|
||||
|
||||
helper.check_traffic(data, exp)
|
||||
153
bin/tests/system/statschannel/helper.py
Normal file
153
bin/tests/system/statschannel/helper.py
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
############################################################################
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
############################################################################
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
||||
from collections import defaultdict
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import dns.message
|
||||
import dns.query
|
||||
import dns.rcode
|
||||
|
||||
# ISO datetime format without msec
|
||||
fmt = '%Y-%m-%dT%H:%M:%SZ'
|
||||
|
||||
# The constants were taken from BIND 9 source code (lib/dns/zone.c)
|
||||
max_refresh = timedelta(seconds=2419200) # 4 weeks
|
||||
max_expires = timedelta(seconds=14515200) # 24 weeks
|
||||
now = datetime.utcnow().replace(microsecond=0)
|
||||
dayzero = datetime.utcfromtimestamp(0).replace(microsecond=0)
|
||||
|
||||
|
||||
TIMEOUT = 10
|
||||
|
||||
|
||||
# Generic helper functions
|
||||
def check_expires(expires, min_time, max_time):
|
||||
assert expires >= min_time
|
||||
assert expires <= max_time
|
||||
|
||||
|
||||
def check_refresh(refresh, min_time, max_time):
|
||||
assert refresh >= min_time
|
||||
assert refresh <= max_time
|
||||
|
||||
|
||||
def check_loaded(loaded, expected):
|
||||
# Sanity check the zone timers values
|
||||
assert loaded == expected
|
||||
assert loaded < now
|
||||
|
||||
|
||||
def check_zone_timers(loaded, expires, refresh, loaded_exp):
|
||||
# Sanity checks the zone timers values
|
||||
if expires is not None:
|
||||
check_expires(expires, now, now + max_expires)
|
||||
if refresh is not None:
|
||||
check_refresh(refresh, now, now + max_refresh)
|
||||
check_loaded(loaded, loaded_exp)
|
||||
|
||||
|
||||
#
|
||||
# The output is gibberish, but at least make sure it does not crash.
|
||||
#
|
||||
def check_manykeys(name, zone=None):
|
||||
# pylint: disable=unused-argument
|
||||
assert name == "manykeys"
|
||||
|
||||
|
||||
def zone_mtime(zonedir, name):
|
||||
|
||||
try:
|
||||
si = os.stat(os.path.join(zonedir, "{}.db".format(name)))
|
||||
except FileNotFoundError:
|
||||
return dayzero
|
||||
|
||||
mtime = datetime.utcfromtimestamp(si.st_mtime).replace(microsecond=0)
|
||||
|
||||
return mtime
|
||||
|
||||
|
||||
def zone_keyid(nameserver, zone, key):
|
||||
with open(f'{nameserver}/{zone}.{key}.id') as f:
|
||||
keyid = f.read().strip()
|
||||
print(f'{zone}-{key} ID: {keyid}')
|
||||
return keyid
|
||||
|
||||
|
||||
def create_msg(qname, qtype):
|
||||
msg = dns.message.make_query(qname, qtype, want_dnssec=True,
|
||||
use_edns=0, payload=4096)
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
def udp_query(ip, port, msg):
|
||||
|
||||
ans = dns.query.udp(msg, ip, TIMEOUT, port=port)
|
||||
assert ans.rcode() == dns.rcode.NOERROR
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
def tcp_query(ip, port, msg):
|
||||
|
||||
ans = dns.query.tcp(msg, ip, TIMEOUT, port=port)
|
||||
assert ans.rcode() == dns.rcode.NOERROR
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
def create_expected(data):
|
||||
expected = {"dns-tcp-requests-sizes-received-ipv4": defaultdict(int),
|
||||
"dns-tcp-responses-sizes-sent-ipv4": defaultdict(int),
|
||||
"dns-tcp-requests-sizes-received-ipv6": defaultdict(int),
|
||||
"dns-tcp-responses-sizes-sent-ipv6": defaultdict(int),
|
||||
"dns-udp-requests-sizes-received-ipv4": defaultdict(int),
|
||||
"dns-udp-requests-sizes-received-ipv6": defaultdict(int),
|
||||
"dns-udp-responses-sizes-sent-ipv4": defaultdict(int),
|
||||
"dns-udp-responses-sizes-sent-ipv6": defaultdict(int),
|
||||
}
|
||||
|
||||
for k, v in data.items():
|
||||
for kk, vv in v.items():
|
||||
expected[k][kk] += vv
|
||||
|
||||
return expected
|
||||
|
||||
|
||||
def update_expected(expected, key, msg):
|
||||
msg_len = len(msg.to_wire())
|
||||
bucket_num = (msg_len // 16) * 16
|
||||
bucket = "{}-{}".format(bucket_num, bucket_num + 15)
|
||||
|
||||
expected[key][bucket] += 1
|
||||
|
||||
|
||||
def check_traffic(data, expected):
|
||||
def ordered(obj):
|
||||
if isinstance(obj, dict):
|
||||
return sorted((k, ordered(v)) for k, v in obj.items())
|
||||
if isinstance(obj, list):
|
||||
return sorted(ordered(x) for x in obj)
|
||||
return obj
|
||||
|
||||
ordered_data = ordered(data)
|
||||
ordered_expected = ordered(expected)
|
||||
|
||||
assert len(ordered_data) == 8
|
||||
assert len(ordered_expected) == 8
|
||||
assert len(data) == len(ordered_data)
|
||||
assert len(expected) == len(ordered_expected)
|
||||
|
||||
assert ordered_data == ordered_expected
|
||||
47
bin/tests/system/statschannel/ns1/example.db
Normal file
47
bin/tests/system/statschannel/ns1/example.db
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$ORIGIN .
|
||||
$TTL 300 ; 5 minutes
|
||||
example IN SOA mname1. . (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
example. NS ns2.example.
|
||||
ns2.example. A 10.53.0.2
|
||||
|
||||
$ORIGIN example.
|
||||
a A 10.0.0.1
|
||||
MX 10 mail.example.
|
||||
short TXT "short text"
|
||||
long TXT (
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
"longlonglonglonglonglonglonglonglonglong"
|
||||
)
|
||||
|
||||
mail A 10.0.0.2
|
||||
41
bin/tests/system/statschannel/ns1/named.conf.in
Normal file
41
bin/tests/system/statschannel/ns1/named.conf.in
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.1;
|
||||
notify-source 10.53.0.1;
|
||||
transfer-source 10.53.0.1;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.1; };
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
notify explicit;
|
||||
minimal-responses no;
|
||||
version none; // make statistics independent of the version number
|
||||
};
|
||||
|
||||
statistics-channels { inet 10.53.0.1 port @EXTRAPORT1@ allow { localhost; }; };
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
zone "example" {
|
||||
type master;
|
||||
file "example.db";
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
|
@ -18,7 +18,7 @@ options {
|
|||
listen-on { 10.53.0.2; };
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
notify yes;
|
||||
notify no;
|
||||
minimal-responses no;
|
||||
version none; // make statistics independent of the version number
|
||||
};
|
||||
|
|
|
|||
41
bin/tests/system/statschannel/ns3/named.conf.in
Normal file
41
bin/tests/system/statschannel/ns3/named.conf.in
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.3;
|
||||
notify-source 10.53.0.3;
|
||||
transfer-source 10.53.0.3;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.3; };
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
notify no;
|
||||
minimal-responses no;
|
||||
version none; // make statistics independent of the version number
|
||||
};
|
||||
|
||||
statistics-channels { inet 10.53.0.3 port @EXTRAPORT1@ allow { localhost; }; };
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
zone "example" {
|
||||
type secondary;
|
||||
file "example.db";
|
||||
masters { 10.53.0.1; };
|
||||
};
|
||||
|
|
@ -12,9 +12,8 @@
|
|||
# shellcheck source=conf.sh
|
||||
. "$SYSTEMTESTTOP/conf.sh"
|
||||
|
||||
copy_setports ns2/named.conf.in ns2/named.conf
|
||||
for conf in ns*/named.conf.in; do
|
||||
copy_setports "$conf" "$(dirname "$conf")/$(basename "$conf" .in)"
|
||||
done
|
||||
|
||||
(
|
||||
cd ns2
|
||||
$SHELL sign.sh
|
||||
)
|
||||
(cd ns2 && $SHELL sign.sh)
|
||||
|
|
|
|||
100
bin/tests/system/statschannel/tests-json.py
Executable file
100
bin/tests/system/statschannel/tests-json.py
Executable file
|
|
@ -0,0 +1,100 @@
|
|||
#!/usr/bin/python3
|
||||
############################################################################
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
############################################################################
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
import generic
|
||||
from helper import fmt
|
||||
|
||||
|
||||
# JSON helper functions
|
||||
def fetch_zones_json(statsip, statsport):
|
||||
|
||||
r = requests.get("http://{}:{}/json/v1/zones".format(statsip, statsport))
|
||||
assert r.status_code == 200
|
||||
|
||||
data = r.json()
|
||||
return data["views"]["_default"]["zones"]
|
||||
|
||||
|
||||
def fetch_traffic_json(statsip, statsport):
|
||||
|
||||
r = requests.get("http://{}:{}/json/v1/traffic".format(statsip, statsport))
|
||||
assert r.status_code == 200
|
||||
|
||||
data = r.json()
|
||||
|
||||
return data["traffic"]
|
||||
|
||||
|
||||
def load_timers_json(zone, primary=True):
|
||||
|
||||
name = zone['name']
|
||||
|
||||
# Check if the primary zone timer exists
|
||||
assert 'loaded' in zone
|
||||
loaded = datetime.strptime(zone['loaded'], fmt)
|
||||
|
||||
if primary:
|
||||
# Check if the secondary zone timers does not exist
|
||||
assert 'expires' not in zone
|
||||
assert 'refresh' not in zone
|
||||
expires = None
|
||||
refresh = None
|
||||
else:
|
||||
assert 'expires' in zone
|
||||
assert 'refresh' in zone
|
||||
expires = datetime.strptime(zone['expires'], fmt)
|
||||
refresh = datetime.strptime(zone['refresh'], fmt)
|
||||
|
||||
return (name, loaded, expires, refresh)
|
||||
|
||||
|
||||
def load_zone_json(zone):
|
||||
name = zone['name']
|
||||
|
||||
return name
|
||||
|
||||
|
||||
@pytest.mark.json
|
||||
@pytest.mark.requests
|
||||
def test_zone_timers_primary_json(statsport):
|
||||
generic.test_zone_timers_primary(fetch_zones_json, load_timers_json,
|
||||
statsip="10.53.0.1", statsport=statsport,
|
||||
zonedir="ns1")
|
||||
|
||||
|
||||
@pytest.mark.json
|
||||
@pytest.mark.requests
|
||||
def test_zone_timers_secondary_json(statsport):
|
||||
generic.test_zone_timers_secondary(fetch_zones_json, load_timers_json,
|
||||
statsip="10.53.0.3", statsport=statsport,
|
||||
zonedir="ns3")
|
||||
|
||||
|
||||
@pytest.mark.json
|
||||
@pytest.mark.requests
|
||||
def test_zone_with_many_keys_json(statsport):
|
||||
generic.test_zone_with_many_keys(fetch_zones_json, load_zone_json,
|
||||
statsip="10.53.0.2", statsport=statsport)
|
||||
|
||||
|
||||
@pytest.mark.json
|
||||
@pytest.mark.requests
|
||||
@pytest.mark.dnspython
|
||||
def test_traffic_json(port, statsport):
|
||||
generic.test_traffic(fetch_traffic_json,
|
||||
statsip="10.53.0.2", statsport=statsport,
|
||||
port=port)
|
||||
130
bin/tests/system/statschannel/tests-xml.py
Executable file
130
bin/tests/system/statschannel/tests-xml.py
Executable file
|
|
@ -0,0 +1,130 @@
|
|||
#!/usr/bin/python3
|
||||
############################################################################
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
############################################################################
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
import generic
|
||||
from helper import fmt
|
||||
|
||||
|
||||
# XML helper functions
|
||||
def fetch_zones_xml(statsip, statsport):
|
||||
|
||||
r = requests.get("http://{}:{}/xml/v3/zones".format(statsip, statsport))
|
||||
assert r.status_code == 200
|
||||
|
||||
root = ET.fromstring(r.text)
|
||||
|
||||
default_view = None
|
||||
for view in root.find('views').iter('view'):
|
||||
if view.attrib['name'] == "_default":
|
||||
default_view = view
|
||||
break
|
||||
assert default_view is not None
|
||||
|
||||
return default_view.find('zones').findall('zone')
|
||||
|
||||
|
||||
def fetch_traffic_xml(statsip, statsport):
|
||||
|
||||
def load_counters(data):
|
||||
out = {}
|
||||
for counter in data.findall("counter"):
|
||||
out[counter.attrib['name']] = int(counter.text)
|
||||
|
||||
return out
|
||||
|
||||
r = requests.get("http://{}:{}/xml/v3/traffic".format(statsip, statsport))
|
||||
assert r.status_code == 200
|
||||
|
||||
root = ET.fromstring(r.text)
|
||||
|
||||
traffic = {}
|
||||
for ip in ["ipv4", "ipv6"]:
|
||||
for proto in ["udp", "tcp"]:
|
||||
proto_root = root.find("traffic").find(ip).find(proto)
|
||||
for counters in proto_root.findall("counters"):
|
||||
if counters.attrib['type'] == "request-size":
|
||||
key = "dns-{}-requests-sizes-received-{}".format(proto, ip)
|
||||
else:
|
||||
key = "dns-{}-responses-sizes-sent-{}".format(proto, ip)
|
||||
|
||||
values = load_counters(counters)
|
||||
traffic[key] = values
|
||||
|
||||
return traffic
|
||||
|
||||
|
||||
def load_timers_xml(zone, primary=True):
|
||||
|
||||
name = zone.attrib['name']
|
||||
|
||||
loaded_el = zone.find('loaded')
|
||||
assert loaded_el is not None
|
||||
loaded = datetime.strptime(loaded_el.text, fmt)
|
||||
|
||||
expires_el = zone.find('expires')
|
||||
refresh_el = zone.find('refresh')
|
||||
if primary:
|
||||
assert expires_el is None
|
||||
assert refresh_el is None
|
||||
expires = None
|
||||
refresh = None
|
||||
else:
|
||||
assert expires_el is not None
|
||||
assert refresh_el is not None
|
||||
expires = datetime.strptime(expires_el.text, fmt)
|
||||
refresh = datetime.strptime(refresh_el.text, fmt)
|
||||
|
||||
return (name, loaded, expires, refresh)
|
||||
|
||||
|
||||
def load_zone_xml(zone):
|
||||
name = zone.attrib['name']
|
||||
|
||||
return name
|
||||
|
||||
|
||||
@pytest.mark.xml
|
||||
@pytest.mark.requests
|
||||
def test_zone_timers_primary_xml(statsport):
|
||||
generic.test_zone_timers_primary(fetch_zones_xml, load_timers_xml,
|
||||
statsip="10.53.0.1", statsport=statsport,
|
||||
zonedir="ns1")
|
||||
|
||||
|
||||
@pytest.mark.xml
|
||||
@pytest.mark.requests
|
||||
def test_zone_timers_secondary_xml(statsport):
|
||||
generic.test_zone_timers_secondary(fetch_zones_xml, load_timers_xml,
|
||||
statsip="10.53.0.3", statsport=statsport,
|
||||
zonedir="ns3")
|
||||
|
||||
|
||||
@pytest.mark.xml
|
||||
@pytest.mark.requests
|
||||
def test_zone_with_many_keys_xml(statsport):
|
||||
generic.test_zone_with_many_keys(fetch_zones_xml, load_zone_xml,
|
||||
statsip="10.53.0.2", statsport=statsport)
|
||||
|
||||
|
||||
@pytest.mark.xml
|
||||
@pytest.mark.requests
|
||||
@pytest.mark.dnspython
|
||||
def test_traffic_xml(port, statsport):
|
||||
generic.test_traffic(fetch_traffic_xml,
|
||||
statsip="10.53.0.2", statsport=statsport,
|
||||
port=port)
|
||||
|
|
@ -45,21 +45,6 @@ if [ ! "$PERL_JSON" -a ! "$PERL_XML" ]; then
|
|||
fi
|
||||
|
||||
|
||||
gettraffic() {
|
||||
sleep 1
|
||||
echo_i "... using $1"
|
||||
case $1 in
|
||||
xml) path='xml/v3/traffic' ;;
|
||||
json) path='json/v1/traffic' ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
file=`$PERL fetch.pl -p ${EXTRAPORT1} $path`
|
||||
cp $file $file.$1.$2
|
||||
$PERL traffic-${1}.pl $file 2>/dev/null | sort > traffic.out.$2
|
||||
result=$?
|
||||
return $result
|
||||
}
|
||||
|
||||
getzones() {
|
||||
sleep 1
|
||||
echo_i "... using $1"
|
||||
|
|
@ -86,81 +71,6 @@ loadkeys_on() {
|
|||
|
||||
status=0
|
||||
n=1
|
||||
ret=0
|
||||
echo_i "fetching traffic size data ($n)"
|
||||
if [ $PERL_XML ]; then
|
||||
gettraffic xml x$n || ret=1
|
||||
cmp traffic.out.x$n traffic.expect.$n || ret=1
|
||||
fi
|
||||
if [ $PERL_JSON ]; then
|
||||
gettraffic json j$n || ret=1
|
||||
cmp traffic.out.j$n traffic.expect.$n || ret=1
|
||||
fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
n=`expr $n + 1`
|
||||
|
||||
ret=0
|
||||
echo_i "fetching traffic size data after small UDP query ($n)"
|
||||
$DIGCMD short.example txt > dig.out.$n || ret=1
|
||||
if [ $PERL_XML ]; then
|
||||
gettraffic xml x$n || ret=1
|
||||
cmp traffic.out.x$n traffic.expect.$n || ret=1
|
||||
fi
|
||||
if [ $PERL_JSON ]; then
|
||||
gettraffic json j$n || ret=1
|
||||
cmp traffic.out.j$n traffic.expect.$n || ret=1
|
||||
fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
n=`expr $n + 1`
|
||||
|
||||
ret=0
|
||||
n=`expr $n + 1`
|
||||
echo_i "fetching traffic size data after large UDP query ($n)"
|
||||
$DIGCMD long.example txt > dig.out.$n || ret=1
|
||||
if [ $PERL_XML ]; then
|
||||
gettraffic xml x$n || ret=1
|
||||
cmp traffic.out.x$n traffic.expect.$n || ret=1
|
||||
fi
|
||||
if [ $PERL_JSON ]; then
|
||||
gettraffic json j$n || ret=1
|
||||
cmp traffic.out.j$n traffic.expect.$n || ret=1
|
||||
fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
n=`expr $n + 1`
|
||||
|
||||
ret=0
|
||||
echo_i "fetching traffic size data after small TCP query ($n)"
|
||||
$DIGCMD +tcp short.example txt > dig.out.$n || ret=1
|
||||
if [ $PERL_XML ]; then
|
||||
gettraffic xml x$n || ret=1
|
||||
cmp traffic.out.x$n traffic.expect.$n || ret=1
|
||||
fi
|
||||
if [ $PERL_JSON ]; then
|
||||
gettraffic json j$n || ret=1
|
||||
cmp traffic.out.j$n traffic.expect.$n || ret=1
|
||||
fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
n=`expr $n + 1`
|
||||
|
||||
ret=0
|
||||
echo_i "fetching traffic size data after large TCP query ($n)"
|
||||
$DIGCMD +tcp long.example txt > dig.out.$n || ret=1
|
||||
if [ $PERL_XML ]; then
|
||||
gettraffic xml x$n || ret=1
|
||||
cmp traffic.out.x$n traffic.expect.$n || ret=1
|
||||
fi
|
||||
if [ $PERL_JSON ]; then
|
||||
gettraffic json j$n || ret=1
|
||||
cmp traffic.out.j$n traffic.expect.$n || ret=1
|
||||
fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
n=`expr $n + 1`
|
||||
|
||||
ret=0
|
||||
echo_i "checking consistency between named.stats and xml/json ($n)"
|
||||
rm -f ns2/named.stats
|
||||
|
|
@ -359,25 +269,6 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
|
|||
status=`expr $status + $ret`
|
||||
n=`expr $n + 1`
|
||||
|
||||
# 4. Test a zone with more than four keys.
|
||||
zone="manykeys"
|
||||
ksk8_id=`cat ns2/$zone.ksk8.id`
|
||||
zsk8_id=`cat ns2/$zone.zsk8.id`
|
||||
ksk13_id=`cat ns2/$zone.ksk13.id`
|
||||
zsk13_id=`cat ns2/$zone.zsk13.id`
|
||||
ksk14_id=`cat ns2/$zone.ksk14.id`
|
||||
zsk14_id=`cat ns2/$zone.zsk14.id`
|
||||
|
||||
ret=0
|
||||
echo_i "fetch zone stats data for a zone with many keys ($n)"
|
||||
# Fetch and check the dnssec sign statistics.
|
||||
if [ $PERL_XML ]; then
|
||||
getzones xml $zone x$n || ret=1
|
||||
fi
|
||||
if [ $PERL_JSON ]; then
|
||||
getzones json $zone j$n || ret=1
|
||||
fi
|
||||
# The output is gibberish, but at least make sure it does not crash.
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
n=`expr $n + 1`
|
||||
|
|
|
|||
|
|
@ -88,6 +88,14 @@
|
|||
actions to be logged into a separate channel. [GL #54]
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The zone timers are now exported to the statistics channel. For the
|
||||
primary zones, only the loaded time is exported. For the secondary
|
||||
zones, the exported timers also include expire and refresh times.
|
||||
Contributed by Paul Frieden, Verizon Media. [GL #1232]
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
|
|
|
|||
|
|
@ -288,15 +288,12 @@ options {
|
|||
dnssec\-secure\-to\-insecure boolean;
|
||||
dnssec\-update\-mode ( maintain | no\-resign );
|
||||
dnssec\-validation ( yes | no | auto );
|
||||
dnstap { ( all | auth | client | forwarder |
|
||||
resolver | update ) [ ( query | response ) ];
|
||||
... };
|
||||
dnstap\-identity ( quoted_string | none |
|
||||
hostname );
|
||||
dnstap\-output ( file | unix ) quoted_string [
|
||||
size ( unlimited | size ) ] [ versions (
|
||||
unlimited | integer ) ] [ suffix ( increment
|
||||
| timestamp ) ];
|
||||
dnstap { ( all | auth | client | forwarder | resolver | update ) [
|
||||
( query | response ) ]; ... };
|
||||
dnstap\-identity ( quoted_string | none | hostname );
|
||||
dnstap\-output ( file | unix ) quoted_string [ size ( unlimited |
|
||||
size ) ] [ versions ( unlimited | integer ) ] [ suffix (
|
||||
increment | timestamp ) ];
|
||||
dnstap\-version ( quoted_string | none );
|
||||
dscp integer;
|
||||
dual\-stack\-servers [ port integer ] { ( quoted_string [ port
|
||||
|
|
@ -686,9 +683,8 @@ view string [ class ] {
|
|||
dnssec\-secure\-to\-insecure boolean;
|
||||
dnssec\-update\-mode ( maintain | no\-resign );
|
||||
dnssec\-validation ( yes | no | auto );
|
||||
dnstap { ( all | auth | client | forwarder |
|
||||
resolver | update ) [ ( query | response ) ];
|
||||
... };
|
||||
dnstap { ( all | auth | client | forwarder | resolver | update ) [
|
||||
( query | response ) ]; ... };
|
||||
dual\-stack\-servers [ port integer ] { ( quoted_string [ port
|
||||
integer ] [ dscp integer ] | ipv4_address [ port
|
||||
integer ] [ dscp integer ] | ipv6_address [ port
|
||||
|
|
|
|||
|
|
@ -166,16 +166,13 @@ options {
|
|||
dnssec-secure-to-insecure <boolean>;
|
||||
dnssec-update-mode ( maintain | no-resign );
|
||||
dnssec-validation ( yes | no | auto );
|
||||
dnstap { ( all | auth | client | forwarder |
|
||||
resolver | update ) [ ( query | response ) ];
|
||||
... }; // not configured
|
||||
dnstap-identity ( <quoted_string> | none |
|
||||
hostname ); // not configured
|
||||
dnstap-output ( file | unix ) <quoted_string> [
|
||||
size ( unlimited | <size> ) ] [ versions (
|
||||
unlimited | <integer> ) ] [ suffix ( increment
|
||||
| timestamp ) ]; // not configured
|
||||
dnstap-version ( <quoted_string> | none ); // not configured
|
||||
dnstap { ( all | auth | client | forwarder | resolver | update ) [
|
||||
( query | response ) ]; ... };
|
||||
dnstap-identity ( <quoted_string> | none | hostname );
|
||||
dnstap-output ( file | unix ) <quoted_string> [ size ( unlimited |
|
||||
<size> ) ] [ versions ( unlimited | <integer> ) ] [ suffix (
|
||||
increment | timestamp ) ];
|
||||
dnstap-version ( <quoted_string> | none );
|
||||
dscp <integer>;
|
||||
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
|
||||
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
|
||||
|
|
@ -199,13 +196,13 @@ options {
|
|||
forward ( first | only );
|
||||
forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address>
|
||||
| <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
|
||||
fstrm-set-buffer-hint <integer>; // not configured
|
||||
fstrm-set-flush-timeout <integer>; // not configured
|
||||
fstrm-set-input-queue-size <integer>; // not configured
|
||||
fstrm-set-output-notify-threshold <integer>; // not configured
|
||||
fstrm-set-output-queue-model ( mpsc | spsc ); // not configured
|
||||
fstrm-set-output-queue-size <integer>; // not configured
|
||||
fstrm-set-reopen-interval <duration>; // not configured
|
||||
fstrm-set-buffer-hint <integer>;
|
||||
fstrm-set-flush-timeout <integer>;
|
||||
fstrm-set-input-queue-size <integer>;
|
||||
fstrm-set-output-notify-threshold <integer>;
|
||||
fstrm-set-output-queue-model ( mpsc | spsc );
|
||||
fstrm-set-output-queue-size <integer>;
|
||||
fstrm-set-reopen-interval <duration>;
|
||||
geoip-directory ( <quoted_string> | none );
|
||||
geoip-use-ecs <boolean>; // obsolete
|
||||
glue-cache <boolean>;
|
||||
|
|
@ -550,9 +547,8 @@ view <string> [ <class> ] {
|
|||
dnssec-secure-to-insecure <boolean>;
|
||||
dnssec-update-mode ( maintain | no-resign );
|
||||
dnssec-validation ( yes | no | auto );
|
||||
dnstap { ( all | auth | client | forwarder |
|
||||
resolver | update ) [ ( query | response ) ];
|
||||
... }; // not configured
|
||||
dnstap { ( all | auth | client | forwarder | resolver | update ) [
|
||||
( query | response ) ]; ... };
|
||||
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
|
||||
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
|
||||
<integer> ] [ dscp <integer> ] | <ipv6_address> [ port
|
||||
|
|
|
|||
|
|
@ -153,16 +153,13 @@ options {
|
|||
dnssec-secure-to-insecure <boolean>;
|
||||
dnssec-update-mode ( maintain | no-resign );
|
||||
dnssec-validation ( yes | no | auto );
|
||||
dnstap { ( all | auth | client | forwarder |
|
||||
resolver | update ) [ ( query | response ) ];
|
||||
... }; // not configured
|
||||
dnstap-identity ( <quoted_string> | none |
|
||||
hostname ); // not configured
|
||||
dnstap-output ( file | unix ) <quoted_string> [
|
||||
size ( unlimited | <size> ) ] [ versions (
|
||||
unlimited | <integer> ) ] [ suffix ( increment
|
||||
| timestamp ) ]; // not configured
|
||||
dnstap-version ( <quoted_string> | none ); // not configured
|
||||
dnstap { ( all | auth | client | forwarder | resolver | update ) [
|
||||
( query | response ) ]; ... };
|
||||
dnstap-identity ( <quoted_string> | none | hostname );
|
||||
dnstap-output ( file | unix ) <quoted_string> [ size ( unlimited |
|
||||
<size> ) ] [ versions ( unlimited | <integer> ) ] [ suffix (
|
||||
increment | timestamp ) ];
|
||||
dnstap-version ( <quoted_string> | none );
|
||||
dscp <integer>;
|
||||
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
|
||||
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
|
||||
|
|
@ -181,13 +178,13 @@ options {
|
|||
forward ( first | only );
|
||||
forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address>
|
||||
| <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
|
||||
fstrm-set-buffer-hint <integer>; // not configured
|
||||
fstrm-set-flush-timeout <integer>; // not configured
|
||||
fstrm-set-input-queue-size <integer>; // not configured
|
||||
fstrm-set-output-notify-threshold <integer>; // not configured
|
||||
fstrm-set-output-queue-model ( mpsc | spsc ); // not configured
|
||||
fstrm-set-output-queue-size <integer>; // not configured
|
||||
fstrm-set-reopen-interval <duration>; // not configured
|
||||
fstrm-set-buffer-hint <integer>;
|
||||
fstrm-set-flush-timeout <integer>;
|
||||
fstrm-set-input-queue-size <integer>;
|
||||
fstrm-set-output-notify-threshold <integer>;
|
||||
fstrm-set-output-queue-model ( mpsc | spsc );
|
||||
fstrm-set-output-queue-size <integer>;
|
||||
fstrm-set-reopen-interval <duration>;
|
||||
geoip-directory ( <quoted_string> | none );
|
||||
glue-cache <boolean>;
|
||||
heartbeat-interval <integer>;
|
||||
|
|
@ -495,9 +492,8 @@ view <string> [ <class> ] {
|
|||
dnssec-secure-to-insecure <boolean>;
|
||||
dnssec-update-mode ( maintain | no-resign );
|
||||
dnssec-validation ( yes | no | auto );
|
||||
dnstap { ( all | auth | client | forwarder |
|
||||
resolver | update ) [ ( query | response ) ];
|
||||
... }; // not configured
|
||||
dnstap { ( all | auth | client | forwarder | resolver | update ) [
|
||||
( query | response ) ]; ... };
|
||||
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
|
||||
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
|
||||
<integer> ] [ dscp <integer> ] | <ipv6_address> [ port
|
||||
|
|
|
|||
|
|
@ -82,15 +82,12 @@
|
|||
dnssec-secure-to-insecure <boolean>;
|
||||
dnssec-update-mode ( maintain | no-resign );
|
||||
dnssec-validation ( yes | no | auto );
|
||||
dnstap { ( all | auth | client | forwarder |
|
||||
resolver | update ) [ ( query | response ) ];
|
||||
... };
|
||||
dnstap-identity ( <quoted_string> | none |
|
||||
hostname );
|
||||
dnstap-output ( file | unix ) <quoted_string> [
|
||||
size ( unlimited | <size> ) ] [ versions (
|
||||
unlimited | <integer> ) ] [ suffix ( increment
|
||||
| timestamp ) ];
|
||||
dnstap { ( all | auth | client | forwarder | resolver | update ) [
|
||||
( query | response ) ]; ... };
|
||||
dnstap-identity ( <quoted_string> | none | hostname );
|
||||
dnstap-output ( file | unix ) <quoted_string> [ size ( unlimited |
|
||||
<size> ) ] [ versions ( unlimited | <integer> ) ] [ suffix (
|
||||
increment | timestamp ) ];
|
||||
dnstap-version ( <quoted_string> | none );
|
||||
dscp <integer>;
|
||||
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
|
||||
|
|
|
|||
|
|
@ -808,12 +808,17 @@
|
|||
./bin/tests/system/statistics/setup.sh SH 2018,2019,2020
|
||||
./bin/tests/system/statistics/tests.sh SH 2012,2015,2016,2017,2018,2019,2020
|
||||
./bin/tests/system/statschannel/clean.sh SH 2015,2016,2017,2018,2019,2020
|
||||
./bin/tests/system/statschannel/conftest.py PYTHON 2020
|
||||
./bin/tests/system/statschannel/fetch.pl PERL 2015,2016,2018,2019,2020
|
||||
./bin/tests/system/statschannel/generic.py PYTHON 2020
|
||||
./bin/tests/system/statschannel/helper.py PYTHON 2020
|
||||
./bin/tests/system/statschannel/mem-xml.pl PERL 2017,2018,2019,2020
|
||||
./bin/tests/system/statschannel/ns2/sign.sh SH 2019,2020
|
||||
./bin/tests/system/statschannel/server-json.pl PERL 2015,2016,2017,2018,2019,2020
|
||||
./bin/tests/system/statschannel/server-xml.pl PERL 2015,2016,2017,2018,2019,2020
|
||||
./bin/tests/system/statschannel/setup.sh SH 2018,2019,2020
|
||||
./bin/tests/system/statschannel/tests-json.py PYTHON-BIN 2020
|
||||
./bin/tests/system/statschannel/tests-xml.py PYTHON-BIN 2020
|
||||
./bin/tests/system/statschannel/tests.sh SH 2015,2016,2017,2018,2019,2020
|
||||
./bin/tests/system/statschannel/traffic-json.pl PERL 2015,2016,2017,2018,2019,2020
|
||||
./bin/tests/system/statschannel/traffic-xml.pl PERL 2015,2016,2017,2018,2019,2020
|
||||
|
|
|
|||
Loading…
Reference in a new issue