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 } };