diff --git a/CHANGES b/CHANGES
index a2e2046d6d..5fac4ad743 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+3501. [func] zone-statistics now takes three options: full,
+ terse, and none. "yes" and "no" are retained as
+ synonyms for full and terse, respectively. [RT #29165]
+
3500. [port] Support NAPTR regular expression validation on
all platforms. [RT #32688]
diff --git a/bin/named/config.c b/bin/named/config.c
index 1a04472d39..dcde6747ee 100644
--- a/bin/named/config.c
+++ b/bin/named/config.c
@@ -202,7 +202,7 @@ options {\n\
sig-signing-signatures 10;\n\
sig-signing-type 65534;\n\
inline-signing no;\n\
- zone-statistics false;\n\
+ zone-statistics terse;\n\
max-journal-size unlimited;\n\
ixfr-from-differences false;\n\
check-wildcard yes;\n\
diff --git a/bin/named/server.c b/bin/named/server.c
index 394986ce6e..7090c3bc31 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -1387,12 +1387,14 @@ check_dbtype(dns_zone_t **zonep, unsigned int dbtypec, const char **dbargv,
}
static isc_result_t
-setquerystats(dns_zone_t *zone, isc_mem_t *mctx, isc_boolean_t on) {
+setquerystats(dns_zone_t *zone, isc_mem_t *mctx, dns_zonestat_level_t level) {
isc_result_t result;
isc_stats_t *zoneqrystats;
+ dns_zone_setstatlevel(zone, level);
+
zoneqrystats = NULL;
- if (on) {
+ if (level == dns_zonestat_full) {
result = isc_stats_create(mctx, &zoneqrystats,
dns_nsstatscounter_max);
if (result != ISC_R_SUCCESS)
@@ -1545,7 +1547,7 @@ dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na,
dns_zone_setdialup(zone, dns_dialuptype_no);
dns_zone_setnotifytype(zone, dns_notifytype_no);
dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, ISC_TRUE);
- CHECK(setquerystats(zone, mctx, ISC_FALSE)); /* XXXMPA */
+ CHECK(setquerystats(zone, mctx, dns_zonestat_none)); /* XXXMPA */
CHECK(dns_view_addzone(view, zone));
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_INFO, "dns64 reverse zone%s%s: %s", sep,
@@ -3283,7 +3285,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
const char *empty_dbtype[4] =
{ "_builtin", "empty", NULL, NULL };
int empty_dbtypec = 4;
- isc_boolean_t zonestats_on;
+ dns_zonestat_level_t statlevel;
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
@@ -3321,7 +3323,22 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
obj = NULL;
result = ns_config_get(maps, "zone-statistics", &obj);
INSIST(result == ISC_R_SUCCESS);
- zonestats_on = cfg_obj_asboolean(obj);
+ if (cfg_obj_isboolean(obj)) {
+ if (cfg_obj_asboolean(obj))
+ statlevel = dns_zonestat_full;
+ else
+ statlevel = dns_zonestat_terse; /* XXX */
+ } else {
+ const char *levelstr = cfg_obj_asstring(obj);
+ if (strcasecmp(levelstr, "full") == 0)
+ statlevel = dns_zonestat_full;
+ else if (strcasecmp(levelstr, "terse") == 0)
+ statlevel = dns_zonestat_terse;
+ else if (strcasecmp(levelstr, "none") == 0)
+ statlevel = dns_zonestat_none;
+ else
+ INSIST(0);
+ }
for (empty = empty_zones[empty_zone];
empty != NULL;
@@ -3380,7 +3397,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
dns_zone_setview(zone, view);
CHECK(dns_view_addzone(view, zone));
CHECK(setquerystats(zone, mctx,
- zonestats_on));
+ statlevel));
dns_zone_detach(&zone);
continue;
}
@@ -3405,7 +3422,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
dns_zone_setnotifytype(zone, dns_notifytype_no);
dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS,
ISC_TRUE);
- CHECK(setquerystats(zone, mctx, zonestats_on));
+ CHECK(setquerystats(zone, mctx, statlevel));
CHECK(dns_view_addzone(view, zone));
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
@@ -4156,7 +4173,7 @@ add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) {
dns_zone_setjournalsize(zone, 0);
dns_zone_setstats(zone, ns_g_server->zonestats);
- CHECK(setquerystats(zone, mctx, ISC_FALSE));
+ CHECK(setquerystats(zone, mctx, dns_zonestat_none));
if (view->managed_keys != NULL)
dns_zone_detach(&view->managed_keys);
diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c
index 325b9d63a7..1cbc76246c 100644
--- a/bin/named/statschannel.c
+++ b/bin/named/statschannel.c
@@ -796,7 +796,7 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
static isc_result_t
zone_xmlrender(dns_zone_t *zone, void *arg) {
-
+ isc_result_t result;
char buf[1024 + 32]; /* sufficiently large for zone name and class */
char *zone_name_only = NULL;
dns_rdataclass_t rdclass;
@@ -804,26 +804,27 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
xmlTextWriterPtr writer = arg;
isc_stats_t *zonestats;
dns_stats_t *rcvquerystats;
-
+ dns_zonestat_level_t statlevel;
isc_uint64_t nsstat_values[dns_nsstatscounter_max];
int xmlrc;
- isc_result_t result;
+
+ statlevel = dns_zone_getstatlevel(zone);
+ if (statlevel == dns_zonestat_none)
+ return (ISC_R_SUCCESS);
stats_dumparg_t dumparg;
dumparg.type = isc_statsformat_xml;
dumparg.arg = writer;
-
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone"));
dns_zone_name(zone, buf, sizeof(buf));
zone_name_only = strtok(buf, "/");
- if(zone_name_only == NULL){
+ if(zone_name_only == NULL)
zone_name_only = buf;
- }
+
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
ISC_XMLCHAR zone_name_only));
-
rdclass = dns_zone_getclass(zone);
dns_rdataclass_format(rdclass, buf, sizeof(buf));
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "rdataclass",
@@ -838,7 +839,7 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
zonestats = dns_zone_getrequeststats(zone);
rcvquerystats = dns_zone_getrcvquerystats(zone);
- if (zonestats != NULL ) {
+ if (statlevel == dns_zonestat_full && zonestats != NULL) {
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
ISC_XMLCHAR "rcode"));
@@ -853,7 +854,7 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
TRY0(xmlTextWriterEndElement(writer));
}
- if(rcvquerystats != NULL){
+ if (statlevel == dns_zonestat_full && rcvquerystats != NULL) {
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
ISC_XMLCHAR "qtype"));
diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c
index 7698c21db4..5eb0ce1113 100644
--- a/bin/named/zoneconf.c
+++ b/bin/named/zoneconf.c
@@ -828,7 +828,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_masterformat_t masterformat;
isc_stats_t *zoneqrystats;
dns_stats_t *rcvquerystats;
- isc_boolean_t zonestats_on;
+ dns_zonestat_level_t statlevel;
int seconds;
dns_zone_t *mayberaw = (raw != NULL) ? raw : zone;
@@ -1034,17 +1034,33 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
obj = NULL;
result = ns_config_get(maps, "zone-statistics", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- zonestats_on = cfg_obj_asboolean(obj);
+ if (cfg_obj_isboolean(obj)) {
+ if (cfg_obj_asboolean(obj))
+ statlevel = dns_zonestat_full;
+ else
+ statlevel = dns_zonestat_terse; /* XXX */
+ } else {
+ const char *levelstr = cfg_obj_asstring(obj);
+ if (strcasecmp(levelstr, "full") == 0)
+ statlevel = dns_zonestat_full;
+ else if (strcasecmp(levelstr, "terse") == 0)
+ statlevel = dns_zonestat_terse;
+ else if (strcasecmp(levelstr, "none") == 0)
+ statlevel = dns_zonestat_none;
+ else
+ INSIST(0);
+ }
+ dns_zone_setstatlevel(zone, statlevel);
zoneqrystats = NULL;
rcvquerystats = NULL;
- if (zonestats_on) {
+ if (statlevel == dns_zonestat_full) {
RETERR(isc_stats_create(mctx, &zoneqrystats,
dns_nsstatscounter_max));
RETERR(dns_rdatatypestats_create(mctx,
&rcvquerystats));
}
- dns_zone_setrequeststats(zone, zoneqrystats );
+ dns_zone_setrequeststats(zone, zoneqrystats);
dns_zone_setrcvquerystats(zone, rcvquerystats);
if (zoneqrystats != NULL)
diff --git a/bin/tests/system/checkconf/good.conf b/bin/tests/system/checkconf/good.conf
index 4ff0c1a731..2b973a8625 100644
--- a/bin/tests/system/checkconf/good.conf
+++ b/bin/tests/system/checkconf/good.conf
@@ -66,6 +66,7 @@ options {
serial-queries 10;
serial-query-rate 100;
server-id none;
+ zone-statistics none;
};
view "first" {
match-clients {
@@ -78,6 +79,7 @@ view "first" {
};
dnssec-lookaside auto;
dnssec-validation auto;
+ zone-statistics terse;
};
view "second" {
match-clients {
@@ -87,6 +89,7 @@ view "second" {
type master;
file "yyy";
update-policy local;
+ zone-statistics yes;
};
zone "example2" {
type static-stub;
@@ -94,7 +97,9 @@ view "second" {
forwarders {
10.53.0.4;
};
+ zone-statistics no;
};
dnssec-lookaside "." trust-anchor "dlv.isc.org.";
dnssec-validation auto;
+ zone-statistics full;
};
diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
index c554991c0c..0b7a0f3f98 100644
--- a/doc/arm/Bv9ARM-book.xml
+++ b/doc/arm/Bv9ARM-book.xml
@@ -5212,7 +5212,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
pid-file path_name;
recursing-file path_name;
statistics-file path_name;
- zone-statistics yes_or_no;
+ zone-statistics full | terse | none;
auth-nxdomain yes_or_no;
deallocate-on-exit yes_or_no;
dialup dialup_option;
@@ -6140,7 +6140,39 @@ options {
-
+
+ zone-statistics
+
+
+ If full, the server will collect
+ statistical data on all zones (unless specifically
+ turned off on a per-zone basis by specifying
+ zone-statistics terse or
+ zone-statistics none
+ in the zone statement).
+ The default is terse, providing
+ minimal statistics on zones (including name and
+ current serial number, but not query type
+ counters).
+
+
+ These statistics may be accessed via the
+ statistics-channel or
+ using rndc stats, which
+ will dump them to the file listed
+ in the statistics-file. See
+ also .
+
+
+ For backward compatibility with earlier versions
+ of BIND 9, the zone-statistics
+ option can also accept yes
+ or no, which have the same
+ effect as full and
+ terse, respectively.
+
+
+
@@ -6638,25 +6670,6 @@ options {
-
- zone-statistics
-
-
- If yes, the server will collect
- statistical data on all zones (unless specifically turned
- off
- on a per-zone basis by specifying zone-statistics no
- in the zone statement).
- The default is no.
- These statistics may be accessed
- using rndc stats, which will
- dump them to the file listed
- in the statistics-file. See
- also .
-
-
-
-
use-ixfr
@@ -10824,7 +10837,7 @@ view "external" {
pubkey number number number string ;
notify-source (ip4_addr | *) port ip_port ;
notify-source-v6 (ip6_addr | *) port ip_port ;
- zone-statistics yes_or_no ;
+ zone-statistics full | terse | none;
sig-validity-interval number number ;
sig-signing-nodes number ;
sig-signing-signatures number ;
@@ -10889,7 +10902,7 @@ zone zone_name class use-alt-transfer-source yes_or_no;
notify-source (ip4_addr | *) port ip_port ;
notify-source-v6 (ip6_addr | *) port ip_port ;
- zone-statistics yes_or_no ;
+ zone-statistics full | terse | none;
sig-validity-interval number number ;
sig-signing-nodes number ;
sig-signing-signatures number ;
diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h
index 4abbc2fd53..e6806e8df5 100644
--- a/lib/dns/include/dns/zone.h
+++ b/lib/dns/include/dns/zone.h
@@ -50,6 +50,12 @@ typedef enum {
dns_zone_redirect
} dns_zonetype_t;
+typedef enum {
+ dns_zonestat_none = 0,
+ dns_zonestat_terse,
+ dns_zonestat_full
+} dns_zonestat_level_t;
+
#define DNS_ZONEOPT_SERVERS 0x00000001U /*%< perform server checks */
#define DNS_ZONEOPT_PARENTS 0x00000002U /*%< perform parent checks */
#define DNS_ZONEOPT_CHILDREN 0x00000004U /*%< perform child checks */
@@ -1704,9 +1710,13 @@ dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats);
void
dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats);
+
+void
+dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats);
/*%<
- * Set an additional statistics set to zone. It is attached in the zone
- * but is not counted in the zone module; only the caller updates the counters.
+ * Set additional statistics sets to zone. These are attached to the zone
+ * but are not counted in the zone module; only the caller updates the
+ * counters.
*
* Requires:
* \li 'zone' to be a valid zone.
@@ -1714,15 +1724,11 @@ dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats);
*\li stats is a valid statistics.
*/
-void
-dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats);
-
isc_stats_t *
dns_zone_getrequeststats(dns_zone_t *zone);
dns_stats_t *
dns_zone_getrcvquerystats(dns_zone_t *zone);
-
/*%<
* Get the additional statistics for zone, if one is installed.
*
@@ -2109,6 +2115,16 @@ dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs,
dns_rpz_num_t
dns_zone_get_rpz_num(dns_zone_t *zone);
+void
+dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level);
+
+dns_zonestat_level_t
+dns_zone_getstatlevel(dns_zone_t *zone);
+/*%
+ * Set and get the statistics reporting level for the zone;
+ * full, terse, or none.
+ */
+
ISC_LANG_ENDDECLS
diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def
index 117c319b08..a663f912ee 100644
--- a/lib/dns/win32/libdns.def
+++ b/lib/dns/win32/libdns.def
@@ -858,6 +858,7 @@ dns_zone_getserialupdatemethod
dns_zone_getsigresigninginterval
dns_zone_getsigvalidityinterval
dns_zone_getssutable
+dns_zone_getstatlevel
dns_zone_getstatscounters
dns_zone_gettask
dns_zone_gettype
@@ -945,6 +946,7 @@ dns_zone_setsigresigninginterval
dns_zone_setsigvalidityinterval
dns_zone_setssutable
dns_zone_setstatistics
+dns_zone_setstatlevel
dns_zone_setstats
dns_zone_settask
dns_zone_settype
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 3a23d69488..2f3d4cdeff 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -310,6 +310,7 @@ struct dns_zone {
* Optional per-zone statistics counters. Counted outside of this
* module.
*/
+ dns_zonestat_level_t statlevel;
isc_boolean_t requeststats_on;
isc_stats_t *requeststats;
dns_stats_t *rcvquerystats;
@@ -919,6 +920,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->statelist = NULL;
zone->stats = NULL;
zone->requeststats_on = ISC_FALSE;
+ zone->statlevel = dns_zonestat_none;
zone->requeststats = NULL;
zone->rcvquerystats = NULL;
zone->notifydelay = 5;
@@ -16842,3 +16844,17 @@ dns_zone_getincludes(dns_zone_t *zone, char ***includesp) {
UNLOCK_ZONE(zone);
return (n);
}
+
+void
+dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ zone->statlevel = level;
+}
+
+dns_zonestat_level_t
+dns_zone_getstatlevel(dns_zone_t *zone) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ return (zone->statlevel);
+}
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
index 5611809039..68cdd9c3b4 100644
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -54,6 +54,9 @@ static isc_result_t
parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype,
const cfg_type_t *othertype, cfg_obj_t **ret);
+static void
+doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *type);
+
static isc_result_t
parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
@@ -560,6 +563,23 @@ static cfg_type_t cfg_type_updatemethod = {
&cfg_rep_string, &updatemethods_enums
};
+/*
+ * zone-statistics: full, terse, or none.
+ *
+ * for backward compatibility, we also support boolean values.
+ * yes represents "full", no represents "terse". in the future we
+ * may change no to mean "none".
+ */
+static const char *zonestat_enums[] = { "full", "terse", "none", NULL };
+static isc_result_t
+parse_zonestat(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+ return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
+}
+static cfg_type_t cfg_type_zonestat = {
+ "zonestat", parse_zonestat, cfg_print_ustring, doc_enum_or_other,
+ &cfg_rep_string, zonestat_enums
+};
+
static cfg_type_t cfg_type_rrsetorder = {
"rrsetorder", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list,
&cfg_rep_list, &cfg_type_rrsetorderingelement
@@ -1571,7 +1591,7 @@ zone_clauses[] = {
{ "update-check-ksk", &cfg_type_boolean, 0 },
{ "use-alt-transfer-source", &cfg_type_boolean, 0 },
{ "zero-no-soa-ttl", &cfg_type_boolean, 0 },
- { "zone-statistics", &cfg_type_boolean, 0 },
+ { "zone-statistics", &cfg_type_zonestat, 0 },
{ NULL, NULL, 0 }
};