diff --git a/CHANGES b/CHANGES
index 52981c221f..f78947e808 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,14 @@
+5373. [bug] Collecting DNSSEC signing operations introduced by
+ GL #513 (change 5254) allocated counters for every
+ possible key id per zone which results in a lot of
+ wasted memory. Fix by tracking up to four keys
+ per zone, rotate counters when keys are replaced.
+ This fixes the immediate problem of the high
+ memory usage, but should be improved in a future
+ release by growing and shrinking the number of
+ keys to track triggered by key rollover events.
+ [GL #1179]
+
5372. [bug] Fix migration from existing DNSSEC key files using
auto-dnssec maintain to dnssec-policy. [GL #1706]
diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c
index c3568b1216..25bec658bf 100644
--- a/bin/named/statschannel.c
+++ b/bin/named/statschannel.c
@@ -1814,7 +1814,6 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
isc_stats_t *gluecachestats;
dns_stats_t *rcvquerystats;
dns_stats_t *dnssecsignstats;
- dns_stats_t *dnssecrefreshstats;
uint64_t nsstat_values[ns_statscounter_max];
uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
@@ -1880,6 +1879,7 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
dnssecsignstats = dns_zone_getdnssecsignstats(zone);
if (dnssecsignstats != NULL) {
+ /* counters type="dnssec-sign"*/
TRY0(xmlTextWriterStartElement(writer,
ISC_XMLCHAR "counters"));
TRY0(xmlTextWriterWriteAttribute(
@@ -1887,19 +1887,17 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
ISC_XMLCHAR "dnssec-sign"));
dumparg.result = ISC_R_SUCCESS;
- dns_dnssecsignstats_dump(dnssecsignstats,
- dnssecsignstat_dump, &dumparg,
- 0);
+ dns_dnssecsignstats_dump(
+ dnssecsignstats, dns_dnssecsignstats_sign,
+ dnssecsignstat_dump, &dumparg, 0);
if (dumparg.result != ISC_R_SUCCESS) {
goto error;
}
/* counters type="dnssec-sign"*/
TRY0(xmlTextWriterEndElement(writer));
- }
- dnssecrefreshstats = dns_zone_getdnssecrefreshstats(zone);
- if (dnssecrefreshstats != NULL) {
+ /* counters type="dnssec-refresh"*/
TRY0(xmlTextWriterStartElement(writer,
ISC_XMLCHAR "counters"));
TRY0(xmlTextWriterWriteAttribute(
@@ -1907,9 +1905,9 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
ISC_XMLCHAR "dnssec-refresh"));
dumparg.result = ISC_R_SUCCESS;
- dns_dnssecsignstats_dump(dnssecrefreshstats,
- dnssecsignstat_dump, &dumparg,
- 0);
+ dns_dnssecsignstats_dump(
+ dnssecsignstats, dns_dnssecsignstats_refresh,
+ dnssecsignstat_dump, &dumparg, 0);
if (dumparg.result != ISC_R_SUCCESS) {
goto error;
}
@@ -2626,7 +2624,6 @@ zone_jsonrender(dns_zone_t *zone, void *arg) {
isc_stats_t *gluecachestats;
dns_stats_t *rcvquerystats;
dns_stats_t *dnssecsignstats;
- dns_stats_t *dnssecrefreshstats;
uint64_t nsstat_values[ns_statscounter_max];
uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
@@ -2708,50 +2705,49 @@ zone_jsonrender(dns_zone_t *zone, void *arg) {
dnssecsignstats = dns_zone_getdnssecsignstats(zone);
if (dnssecsignstats != NULL) {
stats_dumparg_t dumparg;
- json_object *counters = json_object_new_object();
- CHECKMEM(counters);
+ json_object *sign_counters = json_object_new_object();
+ CHECKMEM(sign_counters);
dumparg.type = isc_statsformat_json;
- dumparg.arg = counters;
+ dumparg.arg = sign_counters;
dumparg.result = ISC_R_SUCCESS;
- dns_dnssecsignstats_dump(dnssecsignstats,
- dnssecsignstat_dump, &dumparg,
- 0);
+ dns_dnssecsignstats_dump(
+ dnssecsignstats, dns_dnssecsignstats_sign,
+ dnssecsignstat_dump, &dumparg, 0);
if (dumparg.result != ISC_R_SUCCESS) {
- json_object_put(counters);
+ json_object_put(sign_counters);
goto error;
}
- if (json_object_get_object(counters)->count != 0) {
+ if (json_object_get_object(sign_counters)->count != 0) {
json_object_object_add(zoneobj, "dnssec-sign",
- counters);
+ sign_counters);
} else {
- json_object_put(counters);
+ json_object_put(sign_counters);
}
- }
- dnssecrefreshstats = dns_zone_getdnssecrefreshstats(zone);
- if (dnssecrefreshstats != NULL) {
- stats_dumparg_t dumparg;
- json_object *counters = json_object_new_object();
- CHECKMEM(counters);
+ json_object *refresh_counters =
+ json_object_new_object();
+ CHECKMEM(refresh_counters);
dumparg.type = isc_statsformat_json;
- dumparg.arg = counters;
+ dumparg.arg = refresh_counters;
dumparg.result = ISC_R_SUCCESS;
- dns_dnssecsignstats_dump(dnssecrefreshstats,
- dnssecsignstat_dump, &dumparg,
- 0);
+ dns_dnssecsignstats_dump(
+ dnssecsignstats, dns_dnssecsignstats_refresh,
+ dnssecsignstat_dump, &dumparg, 0);
if (dumparg.result != ISC_R_SUCCESS) {
- json_object_put(counters);
+ json_object_put(refresh_counters);
goto error;
}
- if (json_object_get_object(counters)->count != 0) {
- json_object_object_add(
- zoneobj, "dnssec-refresh", counters);
+ if (json_object_get_object(refresh_counters)->count !=
+ 0) {
+ json_object_object_add(zoneobj,
+ "dnssec-refresh",
+ refresh_counters);
} else {
- json_object_put(counters);
+ json_object_put(refresh_counters);
}
}
}
diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c
index 6ceb710346..7cad6c6b7a 100644
--- a/bin/named/zoneconf.c
+++ b/bin/named/zoneconf.c
@@ -890,7 +890,6 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
isc_stats_t *zoneqrystats;
dns_stats_t *rcvquerystats;
dns_stats_t *dnssecsignstats;
- dns_stats_t *dnssecrefreshstats;
dns_zonestat_level_t statlevel = dns_zonestat_none;
int seconds;
dns_zone_t *mayberaw = (raw != NULL) ? raw : zone;
@@ -1187,18 +1186,15 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
zoneqrystats = NULL;
rcvquerystats = NULL;
dnssecsignstats = NULL;
- dnssecrefreshstats = NULL;
if (statlevel == dns_zonestat_full) {
RETERR(isc_stats_create(mctx, &zoneqrystats,
ns_statscounter_max));
RETERR(dns_rdatatypestats_create(mctx, &rcvquerystats));
RETERR(dns_dnssecsignstats_create(mctx, &dnssecsignstats));
- RETERR(dns_dnssecsignstats_create(mctx, &dnssecrefreshstats));
}
dns_zone_setrequeststats(zone, zoneqrystats);
dns_zone_setrcvquerystats(zone, rcvquerystats);
dns_zone_setdnssecsignstats(zone, dnssecsignstats);
- dns_zone_setdnssecrefreshstats(zone, dnssecrefreshstats);
if (zoneqrystats != NULL) {
isc_stats_detach(&zoneqrystats);
@@ -1212,10 +1208,6 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_stats_detach(&dnssecsignstats);
}
- if (dnssecrefreshstats != NULL) {
- dns_stats_detach(&dnssecrefreshstats);
- }
-
/*
* Configure master functionality. This applies
* to primary masters (type "master") and slaves
diff --git a/bin/tests/system/statschannel/clean.sh b/bin/tests/system/statschannel/clean.sh
index f38d6ac0b1..c9edbde9ee 100644
--- a/bin/tests/system/statschannel/clean.sh
+++ b/bin/tests/system/statschannel/clean.sh
@@ -22,5 +22,6 @@ rm -f xml.*mem json.*mem
rm -f compressed.headers regular.headers compressed.out regular.out
rm -f ns*/managed-keys.bind*
rm -f ns2/Kdnssec* ns2/dnssec.*.id
-rm -f ns2/dnssec.db.signed* ns2/dsset-dnssec.
+rm -f ns2/Kmanykeys* ns2/manykeys.*.id
+rm -f ns2/*.db.signed* ns2/dsset-*. ns2/*.jbk
rm -f ns2/core
diff --git a/bin/tests/system/statschannel/ns2/named.conf.in b/bin/tests/system/statschannel/ns2/named.conf.in
index fc2952fa2a..70aadf8b28 100644
--- a/bin/tests/system/statschannel/ns2/named.conf.in
+++ b/bin/tests/system/statschannel/ns2/named.conf.in
@@ -34,6 +34,17 @@ controls {
inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
+dnssec-policy "manykeys" {
+ keys {
+ ksk lifetime unlimited algorithm 5;
+ zsk lifetime unlimited algorithm 5;
+ ksk lifetime unlimited algorithm 13;
+ zsk lifetime unlimited algorithm 13;
+ ksk lifetime unlimited algorithm 14;
+ zsk lifetime unlimited algorithm 14;
+ };
+};
+
zone "example" {
type master;
file "example.db";
@@ -49,3 +60,10 @@ zone "dnssec" {
dnssec-dnskey-kskonly yes;
update-check-ksk yes;
};
+
+zone "manykeys" {
+ type master;
+ file "manykeys.db.signed";
+ zone-statistics full;
+ dnssec-policy "manykeys";
+};
diff --git a/bin/tests/system/statschannel/ns2/sign.sh b/bin/tests/system/statschannel/ns2/sign.sh
index 3a90654d75..669adec3ec 100644
--- a/bin/tests/system/statschannel/ns2/sign.sh
+++ b/bin/tests/system/statschannel/ns2/sign.sh
@@ -17,12 +17,27 @@ set -e
zone=dnssec.
infile=dnssec.db.in
zonefile=dnssec.db.signed
-
ksk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK "$zone")
zsk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
# Sign deliberately with a very short expiration date.
"$SIGNER" -S -x -O full -e "now"+1s -o "$zone" -f "$zonefile" "$infile" > /dev/null 2>&1
-
keyfile_to_key_id "$ksk" > dnssec.ksk.id
keyfile_to_key_id "$zsk" > dnssec.zsk.id
+zone=manykeys.
+infile=manykeys.db.in
+zonefile=manykeys.db.signed
+ksk8=$("$KEYGEN" -q -a RSASHA256 -b 2048 -f KSK "$zone")
+zsk8=$("$KEYGEN" -q -a RSASHA256 -b 2048 "$zone")
+ksk13=$("$KEYGEN" -q -a ECDSAP256SHA256 -b 256 -f KSK "$zone")
+zsk13=$("$KEYGEN" -q -a ECDSAP256SHA256 -b 256 "$zone")
+ksk14=$("$KEYGEN" -q -a ECDSAP384SHA384 -b 384 -f KSK "$zone")
+zsk14=$("$KEYGEN" -q -a ECDSAP384SHA384 -b 384 "$zone")
+# Sign deliberately with a very short expiration date.
+"$SIGNER" -S -x -O full -e "now"+1s -o "$zone" -f "$zonefile" "$infile" > /dev/null 2>&1
+keyfile_to_key_id "$ksk8" > manykeys.ksk8.id
+keyfile_to_key_id "$zsk8" > manykeys.zsk8.id
+keyfile_to_key_id "$ksk13" > manykeys.ksk13.id
+keyfile_to_key_id "$zsk13" > manykeys.zsk13.id
+keyfile_to_key_id "$ksk14" > manykeys.ksk14.id
+keyfile_to_key_id "$zsk14" > manykeys.zsk14.id
diff --git a/bin/tests/system/statschannel/tests.sh b/bin/tests/system/statschannel/tests.sh
index 333018a03a..32a9da451c 100644
--- a/bin/tests/system/statschannel/tests.sh
+++ b/bin/tests/system/statschannel/tests.sh
@@ -70,8 +70,8 @@ getzones() {
*) return 1 ;;
esac
file=`$PERL fetch.pl -p ${EXTRAPORT1} $path`
- cp $file $file.$1.$2
- $PERL zones-${1}.pl $file 2>/dev/null | sort > zones.out.$2
+ cp $file $file.$1.$3
+ $PERL zones-${1}.pl $file $2 2>/dev/null | sort > zones.out.$3
result=$?
return $result
}
@@ -292,11 +292,11 @@ rm -f zones.expect
# Fetch and check the dnssec sign statistics.
echo_i "fetching zone stats data after zone maintenance at startup ($n)"
if [ $PERL_XML ]; then
- getzones xml x$n || ret=1
+ getzones xml $zone x$n || ret=1
cmp zones.out.x$n zones.expect.$n || ret=1
fi
if [ $PERL_JSON ]; then
- getzones json j$n || ret=1
+ getzones json $zone j$n || ret=1
cmp zones.out.j$n zones.expect.$n || ret=1
fi
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -322,11 +322,11 @@ rm -f zones.expect
# Fetch and check the dnssec sign statistics.
echo_i "fetching zone stats data after dynamic update ($n)"
if [ $PERL_XML ]; then
- getzones xml x$n || ret=1
+ getzones xml $zone x$n || ret=1
cmp zones.out.x$n zones.expect.$n || ret=1
fi
if [ $PERL_JSON ]; then
- getzones json j$n || ret=1
+ getzones json $zone j$n || ret=1
cmp zones.out.j$n zones.expect.$n || ret=1
fi
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -349,16 +349,39 @@ cat zones.expect | sort > zones.expect.$n
rm -f zones.expect
# Fetch and check the dnssec sign statistics.
if [ $PERL_XML ]; then
- getzones xml x$n || ret=1
+ getzones xml $zone x$n || ret=1
cmp zones.out.x$n zones.expect.$n || ret=1
fi
if [ $PERL_JSON ]; then
- getzones json j$n || ret=1
+ getzones json $zone j$n || ret=1
cmp zones.out.j$n zones.expect.$n || ret=1
fi
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`
+
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
diff --git a/bin/tests/system/statschannel/zones-json.pl b/bin/tests/system/statschannel/zones-json.pl
index deef35b0f1..51f26ac0f3 100644
--- a/bin/tests/system/statschannel/zones-json.pl
+++ b/bin/tests/system/statschannel/zones-json.pl
@@ -16,6 +16,7 @@
use JSON;
my $file = $ARGV[0];
+my $zone = $ARGV[1];
open(INPUT, "<$file");
my $text = do{local$/;};
close(INPUT);
@@ -23,12 +24,12 @@ close(INPUT);
my $ref = decode_json($text);
-my $dnssecsign = $ref->{views}->{_default}->{zones}[0]->{"dnssec-sign"};
+my $dnssecsign = $ref->{views}->{_default}->{zones}[$zone]->{"dnssec-sign"};
my $type = "dnssec-sign operations ";
foreach $key (keys %{$dnssecsign}) {
print $type . $key . ": ". $dnssecsign->{$key} ."\n";
}
-my $dnssecrefresh = $ref->{views}->{_default}->{zones}[0]->{"dnssec-refresh"};
+my $dnssecrefresh = $ref->{views}->{_default}->{zones}[$zone]->{"dnssec-refresh"};
my $type = "dnssec-refresh operations ";
foreach $key (keys %{$dnssecrefresh}) {
print $type . $key . ": ". $dnssecrefresh->{$key} ."\n";
diff --git a/bin/tests/system/statschannel/zones-xml.pl b/bin/tests/system/statschannel/zones-xml.pl
index f078b054bb..45a3fe6cbf 100644
--- a/bin/tests/system/statschannel/zones-xml.pl
+++ b/bin/tests/system/statschannel/zones-xml.pl
@@ -16,10 +16,11 @@
use XML::Simple;
my $file = $ARGV[0];
+my $zone = $ARGV[1];
my $ref = XMLin($file);
-my $counters = $ref->{views}->{view}->{_default}->{zones}->{zone}->{dnssec}->{counters};
+my $counters = $ref->{views}->{view}->{_default}->{zones}->{zone}->{$zone}->{counters};
foreach $group (@$counters) {
diff --git a/doc/arm/notes-9.17.1.xml b/doc/arm/notes-9.17.1.xml
index aaad722969..b807089039 100644
--- a/doc/arm/notes-9.17.1.xml
+++ b/doc/arm/notes-9.17.1.xml
@@ -45,7 +45,9 @@
- None.
+ The DNSSEC sign statistics used lots of memory. The number of keys
+ to track is reduced to four per zone, which should be enough for
+ 99% of all signed zones. [GL #1179]
diff --git a/lib/dns/include/dns/stats.h b/lib/dns/include/dns/stats.h
index 4526e68e2d..8c1d04aed9 100644
--- a/lib/dns/include/dns/stats.h
+++ b/lib/dns/include/dns/stats.h
@@ -491,6 +491,14 @@ LIBDNS_EXTERNAL_DATA extern const char *dns_statscounter_names[];
#define DNS_RDATASTATSTYPE_ATTR(type) ((type) >> 16)
#define DNS_RDATASTATSTYPE_VALUE(b, a) (((a) << 16) | (b))
+/*%
+ * Types of DNSSEC sign statistics operations.
+ */
+typedef enum {
+ dns_dnssecsignstats_sign = 1,
+ dns_dnssecsignstats_refresh = 2
+} dnssecsignstats_type_t;
+
/*%<
* Types of dump callbacks.
*/
@@ -684,9 +692,11 @@ dns_rcodestats_increment(dns_stats_t *stats, dns_opcode_t code);
*/
void
-dns_dnssecsignstats_increment(dns_stats_t *stats, dns_keytag_t id);
+dns_dnssecsignstats_increment(dns_stats_t *stats, dns_keytag_t id, uint8_t alg,
+ dnssecsignstats_type_t operation);
/*%<
- * Increment the statistics counter for the DNSKEY 'id'.
+ * Increment the statistics counter for the DNSKEY 'id'. The 'operation'
+ * determines what counter is incremented.
*
* Requires:
*\li 'stats' is a valid dns_stats_t created by dns_dnssecsignstats_create().
@@ -737,7 +747,7 @@ dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
*/
void
-dns_dnssecsignstats_dump(dns_stats_t * stats,
+dns_dnssecsignstats_dump(dns_stats_t *stats, dnssecsignstats_type_t operation,
dns_dnssecsignstats_dumper_t dump_fn, void *arg,
unsigned int options);
/*%<
diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h
index c5c363ab0e..093e467598 100644
--- a/lib/dns/include/dns/zone.h
+++ b/lib/dns/include/dns/zone.h
@@ -1957,9 +1957,6 @@ dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats);
void
dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats);
-
-void
-dns_zone_setdnssecrefreshstats(dns_zone_t *zone, dns_stats_t *stats);
/*%<
* 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
@@ -1979,9 +1976,6 @@ dns_zone_getrcvquerystats(dns_zone_t *zone);
dns_stats_t *
dns_zone_getdnssecsignstats(dns_zone_t *zone);
-
-dns_stats_t *
-dns_zone_getdnssecrefreshstats(dns_zone_t *zone);
/*%<
* Get the additional statistics for zone, if one is installed.
*
@@ -1993,17 +1987,6 @@ dns_zone_getdnssecrefreshstats(dns_zone_t *zone);
* otherwise NULL.
*/
-/*%<
- * 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.
- *
- *\li stats is a valid statistics.
- */
-
void
dns_zone_dialup(dns_zone_t *zone);
/*%<
diff --git a/lib/dns/stats.c b/lib/dns/stats.c
index 50f9308f23..c06c0fc2dd 100644
--- a/lib/dns/stats.c
+++ b/lib/dns/stats.c
@@ -20,6 +20,7 @@
#include
#include
+#include
#include
#include
#include
@@ -93,8 +94,19 @@ typedef enum {
*/
#define RDTYPECOUNTER_MAXVAL 0x0602
-/* dnssec maximum key id */
-static int dnssec_keyid_max = 65535;
+/*
+ * DNSSEC sign statistics.
+ *
+ * Per key we maintain 3 counters. The first is actually no counter but
+ * a key id reference. The second is the number of signatures the key created.
+ * The third is the number of signatures refreshed by the key.
+ */
+
+/* Maximum number of keys to keep track of for DNSSEC signing statistics. */
+static int dnssecsign_max_keys = 4;
+static int dnssecsign_block_size = 3;
+/* Key id mask */
+#define DNSSECSIGNSTATS_KEY_ID_MASK 0x0000FFFF
struct dns_stats {
unsigned int magic;
@@ -228,8 +240,12 @@ isc_result_t
dns_dnssecsignstats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
REQUIRE(statsp != NULL && *statsp == NULL);
- return (create_stats(mctx, dns_statstype_dnssec, dnssec_keyid_max,
- statsp));
+ /*
+ * Create two counters per key, one is the key id, the other two are
+ * the actual counters for creating and refreshing signatures.
+ */
+ return (create_stats(mctx, dns_statstype_dnssec,
+ dnssecsign_max_keys * 3, statsp));
}
/*%
@@ -342,10 +358,64 @@ dns_rcodestats_increment(dns_stats_t *stats, dns_rcode_t code) {
}
void
-dns_dnssecsignstats_increment(dns_stats_t *stats, dns_keytag_t id) {
+dns_dnssecsignstats_increment(dns_stats_t *stats, dns_keytag_t id, uint8_t alg,
+ dnssecsignstats_type_t operation) {
+ uint32_t kval;
+
REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_dnssec);
- isc_stats_increment(stats->counters, (isc_statscounter_t)id);
+ /* Shift algorithm in front of key tag, which is 16 bits */
+ kval = (uint32_t)(alg << 16 | id);
+
+ /* Look up correct counter. */
+ for (int i = 0; i < dnssecsign_max_keys; i++) {
+ int idx = i * dnssecsign_block_size;
+ uint32_t counter = isc_stats_get_counter(stats->counters, idx);
+ if (counter == kval) {
+ /* Match */
+ isc_stats_increment(stats->counters, (idx + operation));
+ return;
+ }
+ }
+
+ /* No match found. Store key in unused slot. */
+ for (int i = 0; i < dnssecsign_max_keys; i++) {
+ int idx = i * dnssecsign_block_size;
+ uint32_t counter = isc_stats_get_counter(stats->counters, idx);
+ if (counter == 0) {
+ isc_stats_set(stats->counters, kval, idx);
+ isc_stats_increment(stats->counters, (idx + operation));
+ return;
+ }
+ }
+
+ /* No room, rotate keys. */
+ for (int i = 1; i < dnssecsign_max_keys; i++) {
+ int gidx = i * dnssecsign_block_size; /* Get key (get index,
+ gidx) */
+ uint32_t keyv = isc_stats_get_counter(stats->counters, gidx);
+ uint32_t sign = isc_stats_get_counter(
+ stats->counters, (gidx + dns_dnssecsignstats_sign));
+ uint32_t refr = isc_stats_get_counter(
+ stats->counters, (gidx + dns_dnssecsignstats_refresh));
+
+ int sidx = (i - 1) * dnssecsign_block_size; /* Set key, (set
+ index, sidx) */
+ isc_stats_set(stats->counters, keyv, sidx);
+ isc_stats_set(stats->counters, sign,
+ (sidx + dns_dnssecsignstats_sign));
+ isc_stats_set(stats->counters, refr,
+ (sidx + dns_dnssecsignstats_refresh));
+ }
+
+ /* Reset counters for new key (new index, nidx). */
+ int nidx = (dnssecsign_max_keys - 1) * dnssecsign_block_size;
+ isc_stats_set(stats->counters, kval, nidx);
+ isc_stats_set(stats->counters, 0, (nidx + dns_dnssecsignstats_sign));
+ isc_stats_set(stats->counters, 0, (nidx + dns_dnssecsignstats_refresh));
+
+ /* And increment the counter for the given operation. */
+ isc_stats_increment(stats->counters, (nidx + operation));
}
/*%
@@ -452,8 +522,34 @@ dnssec_dumpcb(isc_statscounter_t counter, uint64_t value, void *arg) {
dnssecarg->fn((dns_keytag_t)counter, value, dnssecarg->arg);
}
+static void
+dnssec_statsdump(isc_stats_t *stats, dnssecsignstats_type_t operation,
+ isc_stats_dumper_t dump_fn, void *arg, unsigned int options) {
+ int i;
+
+ for (i = 0; i < dnssecsign_max_keys; i++) {
+ int idx = dnssecsign_block_size * i;
+ uint32_t kval, val;
+ dns_keytag_t id;
+
+ kval = isc_stats_get_counter(stats, idx);
+ if (kval == 0) {
+ continue;
+ }
+
+ val = isc_stats_get_counter(stats, (idx + operation));
+ if ((options & ISC_STATSDUMP_VERBOSE) == 0 && val == 0) {
+ continue;
+ }
+
+ id = (dns_keytag_t)kval & DNSSECSIGNSTATS_KEY_ID_MASK;
+
+ dump_fn((isc_statscounter_t)id, val, arg);
+ }
+}
+
void
-dns_dnssecsignstats_dump(dns_stats_t *stats,
+dns_dnssecsignstats_dump(dns_stats_t *stats, dnssecsignstats_type_t operation,
dns_dnssecsignstats_dumper_t dump_fn, void *arg0,
unsigned int options) {
dnssecsigndumparg_t arg;
@@ -462,7 +558,9 @@ dns_dnssecsignstats_dump(dns_stats_t *stats,
arg.fn = dump_fn;
arg.arg = arg0;
- isc_stats_dump(stats->counters, dnssec_dumpcb, &arg, options);
+
+ dnssec_statsdump(stats->counters, operation, dnssec_dumpcb, &arg,
+ options);
}
static void
diff --git a/lib/dns/update.c b/lib/dns/update.c
index e2a062e0c3..76d4cee4ef 100644
--- a/lib/dns/update.c
+++ b/lib/dns/update.c
@@ -1117,6 +1117,7 @@ add_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
+#define ID(x) dst_key_id(x)
#define ALG(x) dst_key_alg(x)
/*
@@ -1260,7 +1261,9 @@ add_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
/* Update DNSSEC sign statistics. */
if (dnssecsignstats != NULL) {
dns_dnssecsignstats_increment(dnssecsignstats,
- dst_key_id(keys[i]));
+ ID(keys[i]),
+ (uint8_t)ALG(keys[i]),
+ dns_dnssecsignstats_sign);
}
}
if (!added_sig) {
diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in
index 71c85d9ef7..50e42bae36 100644
--- a/lib/dns/win32/libdns.def.in
+++ b/lib/dns/win32/libdns.def.in
@@ -1194,7 +1194,6 @@ dns_zone_getchecknames
dns_zone_getclass
dns_zone_getdb
dns_zone_getdbtype
-dns_zone_getdnssecrefreshstats
dns_zone_getdnssecsignstats
dns_zone_getexpiretime
dns_zone_getfile
@@ -1298,7 +1297,6 @@ dns_zone_setclass
dns_zone_setdb
dns_zone_setdbtype
dns_zone_setdialup
-dns_zone_setdnssecrefreshstats
dns_zone_setdnssecsignstats
dns_zone_setfile
dns_zone_setflag
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index aefb71b866..4ba75ef52d 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -120,6 +120,7 @@
*/
#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
+#define ID(x) dst_key_id(x)
#define ALG(x) dst_key_alg(x)
/*
@@ -338,7 +339,6 @@ struct dns_zone {
isc_stats_t *requeststats;
dns_stats_t *rcvquerystats;
dns_stats_t *dnssecsignstats;
- dns_stats_t *dnssecrefreshstats;
uint32_t notifydelay;
dns_isselffunc_t isself;
void *isselfarg;
@@ -1091,7 +1091,6 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->requeststats = NULL;
zone->rcvquerystats = NULL;
zone->dnssecsignstats = NULL;
- zone->dnssecrefreshstats = NULL;
zone->notifydelay = 5;
zone->isself = NULL;
zone->isselfarg = NULL;
@@ -1270,9 +1269,6 @@ zone_free(dns_zone_t *zone) {
if (zone->dnssecsignstats != NULL) {
dns_stats_detach(&zone->dnssecsignstats);
}
- if (zone->dnssecrefreshstats != NULL) {
- dns_stats_detach(&zone->dnssecrefreshstats);
- }
if (zone->db != NULL) {
zone_detachdb(zone);
}
@@ -6752,7 +6748,6 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_zone_t *zone,
dns_dbnode_t *node = NULL;
dns_kasp_t *kasp = dns_zone_getkasp(zone);
dns_stats_t *dnssecsignstats;
- dns_stats_t *dnssecrefreshstats;
dns_rdataset_t rdataset;
dns_rdata_t sig_rdata = DNS_RDATA_INIT;
unsigned char data[1024]; /* XXX */
@@ -6926,16 +6921,17 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_zone_t *zone,
/* Update DNSSEC sign statistics. */
dnssecsignstats = dns_zone_getdnssecsignstats(zone);
- dnssecrefreshstats = dns_zone_getdnssecrefreshstats(zone);
if (dnssecsignstats != NULL) {
+ /* Generated a new signature. */
+ dns_dnssecsignstats_increment(dnssecsignstats,
+ ID(keys[i]),
+ (uint8_t)ALG(keys[i]),
+ dns_dnssecsignstats_sign);
+ /* This is a refresh. */
dns_dnssecsignstats_increment(
- dns_zone_getdnssecsignstats(zone),
- dst_key_id(keys[i]));
- }
- if (dnssecrefreshstats != NULL) {
- dns_dnssecsignstats_increment(
- dns_zone_getdnssecrefreshstats(zone),
- dst_key_id(keys[i]));
+ dnssecsignstats, ID(keys[i]),
+ (uint8_t)ALG(keys[i]),
+ dns_dnssecsignstats_refresh);
}
}
@@ -7396,7 +7392,6 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
dns_rdataset_t rdataset;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_stats_t *dnssecsignstats;
- dns_stats_t *dnssecrefreshstats;
isc_buffer_t buffer;
unsigned char data[1024];
@@ -7515,16 +7510,15 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
/* Update DNSSEC sign statistics. */
dnssecsignstats = dns_zone_getdnssecsignstats(zone);
- dnssecrefreshstats = dns_zone_getdnssecrefreshstats(zone);
if (dnssecsignstats != NULL) {
+ /* Generated a new signature. */
+ dns_dnssecsignstats_increment(dnssecsignstats, ID(key),
+ ALG(key),
+ dns_dnssecsignstats_sign);
+ /* This is a refresh. */
dns_dnssecsignstats_increment(
- dns_zone_getdnssecsignstats(zone),
- dst_key_id(key));
- }
- if (dnssecrefreshstats != NULL) {
- dns_dnssecsignstats_increment(
- dns_zone_getdnssecrefreshstats(zone),
- dst_key_id(key));
+ dnssecsignstats, ID(key), ALG(key),
+ dns_dnssecsignstats_refresh);
}
(*signatures)--;
@@ -18458,17 +18452,6 @@ dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) {
UNLOCK_ZONE(zone);
}
-void
-dns_zone_setdnssecrefreshstats(dns_zone_t *zone, dns_stats_t *stats) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- LOCK_ZONE(zone);
- if (stats != NULL && zone->dnssecrefreshstats == NULL) {
- dns_stats_attach(stats, &zone->dnssecrefreshstats);
- }
- UNLOCK_ZONE(zone);
-}
-
dns_stats_t *
dns_zone_getdnssecsignstats(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
@@ -18476,13 +18459,6 @@ dns_zone_getdnssecsignstats(dns_zone_t *zone) {
return (zone->dnssecsignstats);
}
-dns_stats_t *
-dns_zone_getdnssecrefreshstats(dns_zone_t *zone) {
- REQUIRE(DNS_ZONE_VALID(zone));
-
- return (zone->dnssecrefreshstats);
-}
-
isc_stats_t *
dns_zone_getrequeststats(dns_zone_t *zone) {
/*