]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Grow dnssec-sign statistics instead of rotating
authorMatthijs Mekking <matthijs@isc.org>
Fri, 20 Aug 2021 09:14:49 +0000 (11:14 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Tue, 24 Aug 2021 07:07:15 +0000 (09:07 +0200)
We have introduced dnssec-sign statistics to the zone statistics. This
introduced an operational issue because when using zone-statistics
full, the memory usage was going through the roof. We fixed this by
by allocating just four key slots per zone. If a zone exceeds the
number of keys for example through a key rollover, the keys will be
rotated out on a FIFO basis.

This works for most cases, and fixes the immediate problem of high
memory usage, but if you sign your zone with many, many keys, or are
sign with a ZSK/KSK double algorithm strategy you may experience weird
statistics. A better strategy is to grow the number of key slots per
zone on key rollover events.

That is what this commit is doing: instead of rotating the four slots
to track sign statistics, named now grows the number of key slots
during a key rollover (or via some other method that introduces new
keys).

lib/dns/stats.c

index 702b690b838628fb72ac0e26e58808a2142f3cf6..40127fd3c177d926e046162212c3bade0dfa51ad 100644 (file)
@@ -103,7 +103,7 @@ typedef enum {
  */
 
 /* Maximum number of keys to keep track of for DNSSEC signing statistics. */
-static int dnssecsign_max_keys = 4;
+static int dnssecsign_num_keys = 4;
 static int dnssecsign_block_size = 3;
 /* Key id mask */
 #define DNSSECSIGNSTATS_KEY_ID_MASK 0x0000FFFF
@@ -245,7 +245,8 @@ dns_dnssecsignstats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
         * the actual counters for creating and refreshing signatures.
         */
        return (create_stats(mctx, dns_statstype_dnssec,
-                            dnssecsign_max_keys * 3, statsp));
+                            dnssecsign_num_keys * dnssecsign_block_size,
+                            statsp));
 }
 
 /*%
@@ -361,6 +362,8 @@ void
 dns_dnssecsignstats_increment(dns_stats_t *stats, dns_keytag_t id, uint8_t alg,
                              dnssecsignstats_type_t operation) {
        uint32_t kval;
+       int num_keys = isc_stats_ncounters(stats->counters) /
+                      dnssecsign_block_size;
 
        REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_dnssec);
 
@@ -368,7 +371,7 @@ dns_dnssecsignstats_increment(dns_stats_t *stats, dns_keytag_t id, uint8_t alg,
        kval = (uint32_t)(alg << 16 | id);
 
        /* Look up correct counter. */
-       for (int i = 0; i < dnssecsign_max_keys; i++) {
+       for (int i = 0; i < num_keys; i++) {
                int idx = i * dnssecsign_block_size;
                uint32_t counter = isc_stats_get_counter(stats->counters, idx);
                if (counter == kval) {
@@ -379,7 +382,7 @@ dns_dnssecsignstats_increment(dns_stats_t *stats, dns_keytag_t id, uint8_t alg,
        }
 
        /* No match found. Store key in unused slot. */
-       for (int i = 0; i < dnssecsign_max_keys; i++) {
+       for (int i = 0; i < num_keys; i++) {
                int idx = i * dnssecsign_block_size;
                uint32_t counter = isc_stats_get_counter(stats->counters, idx);
                if (counter == 0) {
@@ -389,27 +392,12 @@ dns_dnssecsignstats_increment(dns_stats_t *stats, dns_keytag_t id, uint8_t alg,
                }
        }
 
-       /* 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));
-       }
+       /* No room, grow stats storage. */
+       isc_stats_resize(&stats->counters,
+                        (num_keys * dnssecsign_block_size * 2));
 
        /* Reset counters for new key (new index, nidx). */
-       int nidx = (dnssecsign_max_keys - 1) * dnssecsign_block_size;
+       int nidx = num_keys * 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));
@@ -525,9 +513,10 @@ dnssec_dumpcb(isc_statscounter_t counter, uint64_t value, void *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;
+       int i, num_keys;
 
-       for (i = 0; i < dnssecsign_max_keys; i++) {
+       num_keys = isc_stats_ncounters(stats) / dnssecsign_block_size;
+       for (i = 0; i < num_keys; i++) {
                int idx = dnssecsign_block_size * i;
                uint32_t kval, val;
                dns_keytag_t id;