Home | History | Annotate | Line # | Download | only in dns
      1 /*	$NetBSD: stats.h,v 1.10 2026/06/19 20:10:01 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #pragma once
     17 
     18 /*! \file dns/stats.h */
     19 
     20 #include <inttypes.h>
     21 
     22 #include <isc/histo.h>
     23 
     24 #include <dns/types.h>
     25 
     26 /*%
     27  * Statistics counters.  Used as isc_statscounter_t values.
     28  */
     29 enum {
     30 	/*%
     31 	 * Resolver statistics counters.
     32 	 */
     33 	dns_resstatscounter_queryv4 = 0,
     34 	dns_resstatscounter_queryv6 = 1,
     35 	dns_resstatscounter_responsev4 = 2,
     36 	dns_resstatscounter_responsev6 = 3,
     37 	dns_resstatscounter_nxdomain = 4,
     38 	dns_resstatscounter_servfail = 5,
     39 	dns_resstatscounter_formerr = 6,
     40 	dns_resstatscounter_othererror = 7,
     41 	dns_resstatscounter_edns0fail = 8,
     42 	dns_resstatscounter_mismatch = 9,
     43 	dns_resstatscounter_truncated = 10,
     44 	dns_resstatscounter_lame = 11,
     45 	dns_resstatscounter_retry = 12,
     46 	dns_resstatscounter_gluefetchv4 = 13,
     47 	dns_resstatscounter_gluefetchv6 = 14,
     48 	dns_resstatscounter_gluefetchv4fail = 15,
     49 	dns_resstatscounter_gluefetchv6fail = 16,
     50 	dns_resstatscounter_val = 17,
     51 	dns_resstatscounter_valsuccess = 18,
     52 	dns_resstatscounter_valnegsuccess = 19,
     53 	dns_resstatscounter_valfail = 20,
     54 	dns_resstatscounter_dispabort = 21,
     55 	dns_resstatscounter_dispsockfail = 22,
     56 	dns_resstatscounter_querytimeout = 23,
     57 	dns_resstatscounter_queryrtt0 = 24,
     58 	dns_resstatscounter_queryrtt1 = 25,
     59 	dns_resstatscounter_queryrtt2 = 26,
     60 	dns_resstatscounter_queryrtt3 = 27,
     61 	dns_resstatscounter_queryrtt4 = 28,
     62 	dns_resstatscounter_queryrtt5 = 29,
     63 	dns_resstatscounter_nfetch = 30,
     64 	dns_resstatscounter_disprequdp = 31,
     65 	dns_resstatscounter_dispreqtcp = 32,
     66 	dns_resstatscounter_buckets = 33,
     67 	dns_resstatscounter_refused = 34,
     68 	dns_resstatscounter_cookienew = 35,
     69 	dns_resstatscounter_cookieout = 36,
     70 	dns_resstatscounter_cookiein = 37,
     71 	dns_resstatscounter_cookieok = 38,
     72 	dns_resstatscounter_badvers = 39,
     73 	dns_resstatscounter_badcookie = 40,
     74 	dns_resstatscounter_zonequota = 41,
     75 	dns_resstatscounter_serverquota = 42,
     76 	dns_resstatscounter_clientquota = 43,
     77 	dns_resstatscounter_nextitem = 44,
     78 	dns_resstatscounter_priming = 45,
     79 	dns_resstatscounter_mismatchtcp = 46,
     80 	dns_resstatscounter_max = 47,
     81 
     82 	/*
     83 	 * DNSSEC stats.
     84 	 */
     85 	dns_dnssecstats_asis = 0,
     86 	dns_dnssecstats_downcase = 1,
     87 	dns_dnssecstats_wildcard = 2,
     88 	dns_dnssecstats_fail = 3,
     89 
     90 	dns_dnssecstats_max = 4,
     91 
     92 	/*%
     93 	 * Zone statistics counters.
     94 	 */
     95 	dns_zonestatscounter_notifyoutv4 = 0,
     96 	dns_zonestatscounter_notifyoutv6 = 1,
     97 	dns_zonestatscounter_notifyinv4 = 2,
     98 	dns_zonestatscounter_notifyinv6 = 3,
     99 	dns_zonestatscounter_notifyrej = 4,
    100 	dns_zonestatscounter_soaoutv4 = 5,
    101 	dns_zonestatscounter_soaoutv6 = 6,
    102 	dns_zonestatscounter_axfrreqv4 = 7,
    103 	dns_zonestatscounter_axfrreqv6 = 8,
    104 	dns_zonestatscounter_ixfrreqv4 = 9,
    105 	dns_zonestatscounter_ixfrreqv6 = 10,
    106 	dns_zonestatscounter_xfrsuccess = 11,
    107 	dns_zonestatscounter_xfrfail = 12,
    108 
    109 	dns_zonestatscounter_max = 13,
    110 
    111 	/*
    112 	 * Adb statistics values.
    113 	 */
    114 	dns_adbstats_nentries = 0,
    115 	dns_adbstats_entriescnt = 1,
    116 	dns_adbstats_nnames = 2,
    117 	dns_adbstats_namescnt = 3,
    118 
    119 	dns_adbstats_max = 4,
    120 
    121 	/*
    122 	 * Cache statistics values.
    123 	 */
    124 	dns_cachestatscounter_hits = 1,
    125 	dns_cachestatscounter_misses = 2,
    126 	dns_cachestatscounter_queryhits = 3,
    127 	dns_cachestatscounter_querymisses = 4,
    128 	dns_cachestatscounter_deletelru = 5,
    129 	dns_cachestatscounter_deletettl = 6,
    130 	dns_cachestatscounter_coveringnsec = 7,
    131 
    132 	dns_cachestatscounter_max = 8,
    133 
    134 	/*%
    135 	 * Query statistics counters (obsolete).
    136 	 */
    137 	dns_statscounter_success = 0,	/*%< Successful lookup */
    138 	dns_statscounter_referral = 1,	/*%< Referral result */
    139 	dns_statscounter_nxrrset = 2,	/*%< NXRRSET result */
    140 	dns_statscounter_nxdomain = 3,	/*%< NXDOMAIN result */
    141 	dns_statscounter_recursion = 4, /*%< Recursion was used */
    142 	dns_statscounter_failure = 5,	/*%< Some other failure */
    143 	dns_statscounter_duplicate = 6, /*%< Duplicate query */
    144 	dns_statscounter_dropped = 7,	/*%< Duplicate query (dropped) */
    145 
    146 	/*%
    147 	 * DNSTAP statistics counters.
    148 	 */
    149 	dns_dnstapcounter_success = 0,
    150 	dns_dnstapcounter_drop = 1,
    151 	dns_dnstapcounter_max = 2,
    152 
    153 	/*
    154 	 * Glue cache statistics counters.
    155 	 */
    156 	dns_gluecachestatscounter_hits_present = 0,
    157 	dns_gluecachestatscounter_hits_absent = 1,
    158 	dns_gluecachestatscounter_inserts_present = 2,
    159 	dns_gluecachestatscounter_inserts_absent = 3,
    160 
    161 	dns_gluecachestatscounter_max = 4,
    162 };
    163 
    164 /*%
    165  * Traffic size statistics, according to RSSAC002 section 2.4
    166  * https://www.icann.org/en/system/files/files/rssac-002-measurements-root-20nov14-en.pdf
    167  *
    168  * The RSSAC002 linear bucketing does not directly match the log-linear
    169  * bucketing of an `isc_histo_t`, so we need to adjust some parameters
    170  * to fit.
    171  *
    172  * To map a message size to an `isc_histo_t`, first divide by
    173  * DNS_SIZEHISTO_QUANTUM so that `isc_histo_inc()` is presented with
    174  * one value per RSSAC002 bucket.
    175  *
    176  * Configure the `isc_histo_t` with large enough `sigbits` that its
    177  * one-value-per-bucket range (its `UNITBUCKETS`) covers the range
    178  * required by RSSAC002.
    179  */
    180 #define DNS_SIZEHISTO_QUANTUM	 16
    181 #define DNS_SIZEHISTO_MAXIN	 (288 / DNS_SIZEHISTO_QUANTUM)
    182 #define DNS_SIZEHISTO_MAXOUT	 (4096 / DNS_SIZEHISTO_QUANTUM)
    183 #define DNS_SIZEHISTO_SIGBITSIN	 4
    184 #define DNS_SIZEHISTO_SIGBITSOUT 7
    185 
    186 #define DNS_SIZEHISTO_BUCKETIN(size) \
    187 	ISC_MIN(size / DNS_SIZEHISTO_QUANTUM, DNS_SIZEHISTO_MAXIN)
    188 
    189 #define DNS_SIZEHISTO_BUCKETOUT(size) \
    190 	ISC_MIN(size / DNS_SIZEHISTO_QUANTUM, DNS_SIZEHISTO_MAXOUT)
    191 
    192 STATIC_ASSERT(DNS_SIZEHISTO_MAXIN <=
    193 		      ISC_HISTO_UNITBUCKETS(DNS_SIZEHISTO_SIGBITSIN),
    194 	      "must be enough histogram buckets for RSSAC002");
    195 
    196 STATIC_ASSERT(DNS_SIZEHISTO_MAXOUT <=
    197 		      ISC_HISTO_UNITBUCKETS(DNS_SIZEHISTO_SIGBITSOUT),
    198 	      "must be enough histogram buckets for RSSAC002");
    199 
    200 /*
    201  * For consistency with other stats counters
    202  */
    203 enum {
    204 	dns_sizecounter_in_max = DNS_SIZEHISTO_MAXIN + 1,
    205 	dns_sizecounter_out_max = DNS_SIZEHISTO_MAXOUT + 1,
    206 };
    207 
    208 /*%
    209  * Attributes for statistics counters of RRset and Rdatatype types.
    210  *
    211  * _OTHERTYPE
    212  *	The rdata type is not explicitly supported and the corresponding counter
    213  *	is counted for other such types, too.  When this attribute is set,
    214  *	the base type is of no use.
    215  *
    216  * _NXRRSET
    217  * 	RRset type counters only.  Indicates the RRset is non existent.
    218  *
    219  * _NXDOMAIN
    220  *	RRset type counters only.  Indicates a non existent name.  When this
    221  *	attribute is set, the base type is of no use.
    222  *
    223  * _STALE
    224  *	RRset type counters only.  This indicates a record that is stale
    225  *	but may still be served.
    226  *
    227  * _ANCIENT
    228  *	RRset type counters only.  This indicates a record that is marked for
    229  *	removal.
    230  */
    231 #define DNS_RDATASTATSTYPE_ATTR_OTHERTYPE 0x0001
    232 #define DNS_RDATASTATSTYPE_ATTR_NXRRSET	  0x0002
    233 #define DNS_RDATASTATSTYPE_ATTR_NXDOMAIN  0x0004
    234 #define DNS_RDATASTATSTYPE_ATTR_STALE	  0x0008
    235 #define DNS_RDATASTATSTYPE_ATTR_ANCIENT	  0x0010
    236 
    237 /*%<
    238  * Conversion macros among dns_rdatatype_t, attributes and isc_statscounter_t.
    239  */
    240 #define DNS_RDATASTATSTYPE_BASE(type)  ((dns_rdatatype_t)((type) & 0xFFFF))
    241 #define DNS_RDATASTATSTYPE_ATTR(type)  ((type) >> 16)
    242 #define DNS_RDATASTATSTYPE_VALUE(b, a) (((a) << 16) | (b))
    243 
    244 /*%
    245  * Types of DNSSEC sign statistics operations.
    246  */
    247 typedef enum {
    248 	dns_dnssecsignstats_sign = 1,
    249 	dns_dnssecsignstats_refresh = 2
    250 } dnssecsignstats_type_t;
    251 
    252 /*%<
    253  * Types of dump callbacks.
    254  */
    255 typedef void (*dns_generalstats_dumper_t)(isc_statscounter_t, uint64_t, void *);
    256 typedef void (*dns_rdatatypestats_dumper_t)(dns_rdatastatstype_t, uint64_t,
    257 					    void *);
    258 typedef void (*dns_dnssecsignstats_dumper_t)(uint32_t, uint64_t, void *);
    259 typedef void (*dns_opcodestats_dumper_t)(dns_opcode_t, uint64_t, void *);
    260 typedef void (*dns_rcodestats_dumper_t)(dns_rcode_t, uint64_t, void *);
    261 
    262 ISC_LANG_BEGINDECLS
    263 
    264 void
    265 dns_generalstats_create(isc_mem_t *mctx, dns_stats_t **statsp, int ncounters);
    266 /*%<
    267  * Create a statistics counter structure of general type.  It counts a general
    268  * set of counters indexed by an ID between 0 and ncounters -1.
    269  * This function is obsolete.  A more general function, isc_stats_create(),
    270  * should be used.
    271  *
    272  * Requires:
    273  *\li	'mctx' must be a valid memory context.
    274  *
    275  *\li	'statsp' != NULL && '*statsp' == NULL.
    276  */
    277 
    278 void
    279 dns_rdatatypestats_create(isc_mem_t *mctx, dns_stats_t **statsp);
    280 /*%<
    281  * Create a statistics counter structure per rdatatype.
    282  *
    283  * Requires:
    284  *\li	'mctx' must be a valid memory context.
    285  *
    286  *\li	'statsp' != NULL && '*statsp' == NULL.
    287  */
    288 
    289 void
    290 dns_rdatasetstats_create(isc_mem_t *mctx, dns_stats_t **statsp);
    291 /*%<
    292  * Create a statistics counter structure per RRset.
    293  *
    294  * Requires:
    295  *\li	'mctx' must be a valid memory context.
    296  *
    297  *\li	'statsp' != NULL && '*statsp' == NULL.
    298  */
    299 
    300 void
    301 dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp);
    302 /*%<
    303  * Create a statistics counter structure per opcode.
    304  *
    305  * Requires:
    306  *\li	'mctx' must be a valid memory context.
    307  *
    308  *\li	'statsp' != NULL && '*statsp' == NULL.
    309  */
    310 
    311 void
    312 dns_rcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp);
    313 /*%<
    314  * Create a statistics counter structure per assigned rcode.
    315  *
    316  * Requires:
    317  *\li	'mctx' must be a valid memory context.
    318  *
    319  *\li	'statsp' != NULL && '*statsp' == NULL.
    320  */
    321 
    322 void
    323 dns_dnssecsignstats_create(isc_mem_t *mctx, dns_stats_t **statsp);
    324 /*%<
    325  * Create a statistics counter structure per assigned DNSKEY id.
    326  *
    327  * Requires:
    328  *\li	'mctx' must be a valid memory context.
    329  *
    330  *\li	'statsp' != NULL && '*statsp' == NULL.
    331  */
    332 
    333 void
    334 dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp);
    335 /*%<
    336  * Attach to a statistics set.
    337  *
    338  * Requires:
    339  *\li	'stats' is a valid dns_stats_t.
    340  *
    341  *\li	'statsp' != NULL && '*statsp' == NULL
    342  */
    343 
    344 void
    345 dns_stats_detach(dns_stats_t **statsp);
    346 /*%<
    347  * Detaches from the statistics set.
    348  *
    349  * Requires:
    350  *\li	'statsp' != NULL and '*statsp' is a valid dns_stats_t.
    351  */
    352 
    353 void
    354 dns_generalstats_increment(dns_stats_t *stats, isc_statscounter_t counter);
    355 /*%<
    356  * Increment the counter-th counter of stats.  This function is obsolete.
    357  * A more general function, isc_stats_increment(), should be used.
    358  *
    359  * Requires:
    360  *\li	'stats' is a valid dns_stats_t created by dns_generalstats_create().
    361  *
    362  *\li	counter is less than the maximum available ID for the stats specified
    363  *	on creation.
    364  */
    365 
    366 void
    367 dns_rdatatypestats_increment(dns_stats_t *stats, dns_rdatatype_t type);
    368 /*%<
    369  * Increment the statistics counter for 'type'.
    370  *
    371  * Requires:
    372  *\li	'stats' is a valid dns_stats_t created by dns_rdatatypestats_create().
    373  */
    374 
    375 void
    376 dns_rdatasetstats_increment(dns_stats_t *stats, dns_rdatastatstype_t rrsettype);
    377 /*%<
    378  * Increment the statistics counter for 'rrsettype'.
    379  *
    380  * Note: if 'rrsettype' has the _STALE attribute set the corresponding
    381  * non-stale counter will be decremented.
    382  *
    383  * Requires:
    384  *\li	'stats' is a valid dns_stats_t created by dns_rdatasetstats_create().
    385  */
    386 
    387 void
    388 dns_rdatasetstats_decrement(dns_stats_t *stats, dns_rdatastatstype_t rrsettype);
    389 /*%<
    390  * Decrement the statistics counter for 'rrsettype'.
    391  *
    392  * Requires:
    393  *\li	'stats' is a valid dns_stats_t created by dns_rdatasetstats_create().
    394  */
    395 
    396 void
    397 dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code);
    398 /*%<
    399  * Increment the statistics counter for 'code'.
    400  *
    401  * Requires:
    402  *\li	'stats' is a valid dns_stats_t created by dns_opcodestats_create().
    403  */
    404 
    405 void
    406 dns_rcodestats_increment(dns_stats_t *stats, dns_opcode_t code);
    407 /*%<
    408  * Increment the statistics counter for 'code'.
    409  *
    410  * Requires:
    411  *\li	'stats' is a valid dns_stats_t created by dns_rcodestats_create().
    412  */
    413 
    414 void
    415 dns_dnssecsignstats_increment(dns_stats_t *stats, dns_keytag_t id, uint8_t alg,
    416 			      dnssecsignstats_type_t operation);
    417 /*%<
    418  * Increment the statistics counter for the DNSKEY 'id' with algorithm 'alg'.
    419  * The 'operation' determines what counter is incremented.
    420  *
    421  * Requires:
    422  *\li	'stats' is a valid dns_stats_t created by dns_dnssecsignstats_create().
    423  */
    424 
    425 void
    426 dns_dnssecsignstats_clear(dns_stats_t *stats, dns_keytag_t id, uint8_t alg);
    427 /*%<
    428  * Clear the statistics counter for the DNSKEY 'id' with algorithm 'alg'.
    429  *
    430  * Requires:
    431  *\li	'stats' is a valid dns_stats_t created by dns_dnssecsignstats_create().
    432  */
    433 
    434 void
    435 dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn,
    436 		      void *arg, unsigned int options);
    437 /*%<
    438  * Dump the current statistics counters in a specified way.  For each counter
    439  * in stats, dump_fn is called with its current value and the given argument
    440  * arg.  By default counters that have a value of 0 is skipped; if options has
    441  * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped.
    442  *
    443  * This function is obsolete.  A more general function, isc_stats_dump(),
    444  * should be used.
    445  *
    446  * Requires:
    447  *\li	'stats' is a valid dns_stats_t created by dns_generalstats_create().
    448  */
    449 
    450 void
    451 dns_rdatatypestats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
    452 			void *arg, unsigned int options);
    453 /*%<
    454  * Dump the current statistics counters in a specified way.  For each counter
    455  * in stats, dump_fn is called with the corresponding type in the form of
    456  * dns_rdatastatstype_t, the current counter value and the given argument
    457  * arg.  By default counters that have a value of 0 is skipped; if options has
    458  * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped.
    459  *
    460  * Requires:
    461  *\li	'stats' is a valid dns_stats_t created by dns_generalstats_create().
    462  */
    463 
    464 void
    465 dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
    466 		       void *arg, unsigned int options);
    467 /*%<
    468  * Dump the current statistics counters in a specified way.  For each counter
    469  * in stats, dump_fn is called with the corresponding type in the form of
    470  * dns_rdatastatstype_t, the current counter value and the given argument
    471  * arg.  By default counters that have a value of 0 is skipped; if options has
    472  * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped.
    473  *
    474  * Requires:
    475  *\li	'stats' is a valid dns_stats_t created by dns_generalstats_create().
    476  */
    477 
    478 void
    479 dns_dnssecsignstats_dump(dns_stats_t *stats, dnssecsignstats_type_t operation,
    480 			 dns_dnssecsignstats_dumper_t dump_fn, void *arg,
    481 			 unsigned int options);
    482 /*%<
    483  * Dump the current statistics counters in a specified way.  For each counter
    484  * in stats, dump_fn is called with the corresponding type in the form of
    485  * dns_rdatastatstype_t, the current counter value and the given argument
    486  * arg.  By default counters that have a value of 0 is skipped; if options has
    487  * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped.
    488  *
    489  * Requires:
    490  *\li	'stats' is a valid dns_stats_t created by dns_generalstats_create().
    491  */
    492 
    493 void
    494 dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn,
    495 		     void *arg, unsigned int options);
    496 /*%<
    497  * Dump the current statistics counters in a specified way.  For each counter
    498  * in stats, dump_fn is called with the corresponding opcode, the current
    499  * counter value and the given argument arg.  By default counters that have a
    500  * value of 0 is skipped; if options has the ISC_STATSDUMP_VERBOSE flag, even
    501  * such counters are dumped.
    502  *
    503  * Requires:
    504  *\li	'stats' is a valid dns_stats_t created by dns_generalstats_create().
    505  */
    506 
    507 void
    508 dns_rcodestats_dump(dns_stats_t *stats, dns_rcodestats_dumper_t dump_fn,
    509 		    void *arg, unsigned int options);
    510 /*%<
    511  * Dump the current statistics counters in a specified way.  For each counter
    512  * in stats, dump_fn is called with the corresponding rcode, the current
    513  * counter value and the given argument arg.  By default counters that have a
    514  * value of 0 is skipped; if options has the ISC_STATSDUMP_VERBOSE flag, even
    515  * such counters are dumped.
    516  *
    517  * Requires:
    518  *\li	'stats' is a valid dns_stats_t created by dns_generalstats_create().
    519  */
    520 
    521 ISC_LANG_ENDDECLS
    522