1*00b67f09SDavid van Moolenbroek /* $NetBSD: stats.c,v 1.5 2014/12/10 04:37:58 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2004, 2005, 2007-2009, 2012 Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek * Copyright (C) 2000, 2001 Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek *
7*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek *
11*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek */
19*00b67f09SDavid van Moolenbroek
20*00b67f09SDavid van Moolenbroek /* Id: stats.c,v 1.18 2009/01/27 23:47:54 tbox Exp */
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroek /*! \file */
23*00b67f09SDavid van Moolenbroek
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek
26*00b67f09SDavid van Moolenbroek #include <isc/magic.h>
27*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
28*00b67f09SDavid van Moolenbroek #include <isc/stats.h>
29*00b67f09SDavid van Moolenbroek #include <isc/util.h>
30*00b67f09SDavid van Moolenbroek
31*00b67f09SDavid van Moolenbroek #include <dns/opcode.h>
32*00b67f09SDavid van Moolenbroek #include <dns/rdatatype.h>
33*00b67f09SDavid van Moolenbroek #include <dns/stats.h>
34*00b67f09SDavid van Moolenbroek
35*00b67f09SDavid van Moolenbroek #define DNS_STATS_MAGIC ISC_MAGIC('D', 's', 't', 't')
36*00b67f09SDavid van Moolenbroek #define DNS_STATS_VALID(x) ISC_MAGIC_VALID(x, DNS_STATS_MAGIC)
37*00b67f09SDavid van Moolenbroek
38*00b67f09SDavid van Moolenbroek /*%
39*00b67f09SDavid van Moolenbroek * Statistics types.
40*00b67f09SDavid van Moolenbroek */
41*00b67f09SDavid van Moolenbroek typedef enum {
42*00b67f09SDavid van Moolenbroek dns_statstype_general = 0,
43*00b67f09SDavid van Moolenbroek dns_statstype_rdtype = 1,
44*00b67f09SDavid van Moolenbroek dns_statstype_rdataset = 2,
45*00b67f09SDavid van Moolenbroek dns_statstype_opcode = 3
46*00b67f09SDavid van Moolenbroek } dns_statstype_t;
47*00b67f09SDavid van Moolenbroek
48*00b67f09SDavid van Moolenbroek /*%
49*00b67f09SDavid van Moolenbroek * It doesn't make sense to have 2^16 counters for all possible types since
50*00b67f09SDavid van Moolenbroek * most of them won't be used. We have counters for the first 256 types and
51*00b67f09SDavid van Moolenbroek * those explicitly supported in the rdata implementation.
52*00b67f09SDavid van Moolenbroek * XXXJT: this introduces tight coupling with the rdata implementation.
53*00b67f09SDavid van Moolenbroek * Ideally, we should have rdata handle this type of details.
54*00b67f09SDavid van Moolenbroek */
55*00b67f09SDavid van Moolenbroek /*
56*00b67f09SDavid van Moolenbroek * types, !types, nxdomain, stale types, stale !types, stale nxdomain
57*00b67f09SDavid van Moolenbroek */
58*00b67f09SDavid van Moolenbroek enum {
59*00b67f09SDavid van Moolenbroek /* For 0-255, we use the rdtype value as counter indices */
60*00b67f09SDavid van Moolenbroek rdtypecounter_dlv = 256, /* for dns_rdatatype_dlv */
61*00b67f09SDavid van Moolenbroek rdtypecounter_others = 257, /* anything else */
62*00b67f09SDavid van Moolenbroek rdtypecounter_max = 258,
63*00b67f09SDavid van Moolenbroek /* The following are used for rdataset */
64*00b67f09SDavid van Moolenbroek rdtypenxcounter_max = rdtypecounter_max * 2,
65*00b67f09SDavid van Moolenbroek rdtypecounter_nxdomain = rdtypenxcounter_max,
66*00b67f09SDavid van Moolenbroek /* stale counters offset */
67*00b67f09SDavid van Moolenbroek rdtypecounter_stale = rdtypecounter_nxdomain + 1,
68*00b67f09SDavid van Moolenbroek rdatasettypecounter_max = rdtypecounter_stale * 2
69*00b67f09SDavid van Moolenbroek };
70*00b67f09SDavid van Moolenbroek
71*00b67f09SDavid van Moolenbroek struct dns_stats {
72*00b67f09SDavid van Moolenbroek /*% Unlocked */
73*00b67f09SDavid van Moolenbroek unsigned int magic;
74*00b67f09SDavid van Moolenbroek dns_statstype_t type;
75*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
76*00b67f09SDavid van Moolenbroek isc_mutex_t lock;
77*00b67f09SDavid van Moolenbroek isc_stats_t *counters;
78*00b67f09SDavid van Moolenbroek
79*00b67f09SDavid van Moolenbroek /*% Locked by lock */
80*00b67f09SDavid van Moolenbroek unsigned int references;
81*00b67f09SDavid van Moolenbroek };
82*00b67f09SDavid van Moolenbroek
83*00b67f09SDavid van Moolenbroek typedef struct rdatadumparg {
84*00b67f09SDavid van Moolenbroek dns_rdatatypestats_dumper_t fn;
85*00b67f09SDavid van Moolenbroek void *arg;
86*00b67f09SDavid van Moolenbroek } rdatadumparg_t;
87*00b67f09SDavid van Moolenbroek
88*00b67f09SDavid van Moolenbroek typedef struct opcodedumparg {
89*00b67f09SDavid van Moolenbroek dns_opcodestats_dumper_t fn;
90*00b67f09SDavid van Moolenbroek void *arg;
91*00b67f09SDavid van Moolenbroek } opcodedumparg_t;
92*00b67f09SDavid van Moolenbroek
93*00b67f09SDavid van Moolenbroek void
dns_stats_attach(dns_stats_t * stats,dns_stats_t ** statsp)94*00b67f09SDavid van Moolenbroek dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp) {
95*00b67f09SDavid van Moolenbroek REQUIRE(DNS_STATS_VALID(stats));
96*00b67f09SDavid van Moolenbroek REQUIRE(statsp != NULL && *statsp == NULL);
97*00b67f09SDavid van Moolenbroek
98*00b67f09SDavid van Moolenbroek LOCK(&stats->lock);
99*00b67f09SDavid van Moolenbroek stats->references++;
100*00b67f09SDavid van Moolenbroek UNLOCK(&stats->lock);
101*00b67f09SDavid van Moolenbroek
102*00b67f09SDavid van Moolenbroek *statsp = stats;
103*00b67f09SDavid van Moolenbroek }
104*00b67f09SDavid van Moolenbroek
105*00b67f09SDavid van Moolenbroek void
dns_stats_detach(dns_stats_t ** statsp)106*00b67f09SDavid van Moolenbroek dns_stats_detach(dns_stats_t **statsp) {
107*00b67f09SDavid van Moolenbroek dns_stats_t *stats;
108*00b67f09SDavid van Moolenbroek
109*00b67f09SDavid van Moolenbroek REQUIRE(statsp != NULL && DNS_STATS_VALID(*statsp));
110*00b67f09SDavid van Moolenbroek
111*00b67f09SDavid van Moolenbroek stats = *statsp;
112*00b67f09SDavid van Moolenbroek *statsp = NULL;
113*00b67f09SDavid van Moolenbroek
114*00b67f09SDavid van Moolenbroek LOCK(&stats->lock);
115*00b67f09SDavid van Moolenbroek stats->references--;
116*00b67f09SDavid van Moolenbroek UNLOCK(&stats->lock);
117*00b67f09SDavid van Moolenbroek
118*00b67f09SDavid van Moolenbroek if (stats->references == 0) {
119*00b67f09SDavid van Moolenbroek isc_stats_detach(&stats->counters);
120*00b67f09SDavid van Moolenbroek DESTROYLOCK(&stats->lock);
121*00b67f09SDavid van Moolenbroek isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
122*00b67f09SDavid van Moolenbroek }
123*00b67f09SDavid van Moolenbroek }
124*00b67f09SDavid van Moolenbroek
125*00b67f09SDavid van Moolenbroek /*%
126*00b67f09SDavid van Moolenbroek * Create methods
127*00b67f09SDavid van Moolenbroek */
128*00b67f09SDavid van Moolenbroek static isc_result_t
create_stats(isc_mem_t * mctx,dns_statstype_t type,int ncounters,dns_stats_t ** statsp)129*00b67f09SDavid van Moolenbroek create_stats(isc_mem_t *mctx, dns_statstype_t type, int ncounters,
130*00b67f09SDavid van Moolenbroek dns_stats_t **statsp)
131*00b67f09SDavid van Moolenbroek {
132*00b67f09SDavid van Moolenbroek dns_stats_t *stats;
133*00b67f09SDavid van Moolenbroek isc_result_t result;
134*00b67f09SDavid van Moolenbroek
135*00b67f09SDavid van Moolenbroek stats = isc_mem_get(mctx, sizeof(*stats));
136*00b67f09SDavid van Moolenbroek if (stats == NULL)
137*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
138*00b67f09SDavid van Moolenbroek
139*00b67f09SDavid van Moolenbroek stats->counters = NULL;
140*00b67f09SDavid van Moolenbroek stats->references = 1;
141*00b67f09SDavid van Moolenbroek
142*00b67f09SDavid van Moolenbroek result = isc_mutex_init(&stats->lock);
143*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
144*00b67f09SDavid van Moolenbroek goto clean_stats;
145*00b67f09SDavid van Moolenbroek
146*00b67f09SDavid van Moolenbroek result = isc_stats_create(mctx, &stats->counters, ncounters);
147*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
148*00b67f09SDavid van Moolenbroek goto clean_mutex;
149*00b67f09SDavid van Moolenbroek
150*00b67f09SDavid van Moolenbroek stats->magic = DNS_STATS_MAGIC;
151*00b67f09SDavid van Moolenbroek stats->type = type;
152*00b67f09SDavid van Moolenbroek stats->mctx = NULL;
153*00b67f09SDavid van Moolenbroek isc_mem_attach(mctx, &stats->mctx);
154*00b67f09SDavid van Moolenbroek *statsp = stats;
155*00b67f09SDavid van Moolenbroek
156*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
157*00b67f09SDavid van Moolenbroek
158*00b67f09SDavid van Moolenbroek clean_mutex:
159*00b67f09SDavid van Moolenbroek DESTROYLOCK(&stats->lock);
160*00b67f09SDavid van Moolenbroek clean_stats:
161*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, stats, sizeof(*stats));
162*00b67f09SDavid van Moolenbroek
163*00b67f09SDavid van Moolenbroek return (result);
164*00b67f09SDavid van Moolenbroek }
165*00b67f09SDavid van Moolenbroek
166*00b67f09SDavid van Moolenbroek isc_result_t
dns_generalstats_create(isc_mem_t * mctx,dns_stats_t ** statsp,int ncounters)167*00b67f09SDavid van Moolenbroek dns_generalstats_create(isc_mem_t *mctx, dns_stats_t **statsp, int ncounters) {
168*00b67f09SDavid van Moolenbroek REQUIRE(statsp != NULL && *statsp == NULL);
169*00b67f09SDavid van Moolenbroek
170*00b67f09SDavid van Moolenbroek return (create_stats(mctx, dns_statstype_general, ncounters, statsp));
171*00b67f09SDavid van Moolenbroek }
172*00b67f09SDavid van Moolenbroek
173*00b67f09SDavid van Moolenbroek isc_result_t
dns_rdatatypestats_create(isc_mem_t * mctx,dns_stats_t ** statsp)174*00b67f09SDavid van Moolenbroek dns_rdatatypestats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
175*00b67f09SDavid van Moolenbroek REQUIRE(statsp != NULL && *statsp == NULL);
176*00b67f09SDavid van Moolenbroek
177*00b67f09SDavid van Moolenbroek return (create_stats(mctx, dns_statstype_rdtype, rdtypecounter_max,
178*00b67f09SDavid van Moolenbroek statsp));
179*00b67f09SDavid van Moolenbroek }
180*00b67f09SDavid van Moolenbroek
181*00b67f09SDavid van Moolenbroek isc_result_t
dns_rdatasetstats_create(isc_mem_t * mctx,dns_stats_t ** statsp)182*00b67f09SDavid van Moolenbroek dns_rdatasetstats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
183*00b67f09SDavid van Moolenbroek REQUIRE(statsp != NULL && *statsp == NULL);
184*00b67f09SDavid van Moolenbroek
185*00b67f09SDavid van Moolenbroek return (create_stats(mctx, dns_statstype_rdataset,
186*00b67f09SDavid van Moolenbroek rdatasettypecounter_max, statsp));
187*00b67f09SDavid van Moolenbroek }
188*00b67f09SDavid van Moolenbroek
189*00b67f09SDavid van Moolenbroek isc_result_t
dns_opcodestats_create(isc_mem_t * mctx,dns_stats_t ** statsp)190*00b67f09SDavid van Moolenbroek dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
191*00b67f09SDavid van Moolenbroek REQUIRE(statsp != NULL && *statsp == NULL);
192*00b67f09SDavid van Moolenbroek
193*00b67f09SDavid van Moolenbroek return (create_stats(mctx, dns_statstype_opcode, 16, statsp));
194*00b67f09SDavid van Moolenbroek }
195*00b67f09SDavid van Moolenbroek
196*00b67f09SDavid van Moolenbroek /*%
197*00b67f09SDavid van Moolenbroek * Increment/Decrement methods
198*00b67f09SDavid van Moolenbroek */
199*00b67f09SDavid van Moolenbroek void
dns_generalstats_increment(dns_stats_t * stats,isc_statscounter_t counter)200*00b67f09SDavid van Moolenbroek dns_generalstats_increment(dns_stats_t *stats, isc_statscounter_t counter) {
201*00b67f09SDavid van Moolenbroek REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_general);
202*00b67f09SDavid van Moolenbroek
203*00b67f09SDavid van Moolenbroek isc_stats_increment(stats->counters, counter);
204*00b67f09SDavid van Moolenbroek }
205*00b67f09SDavid van Moolenbroek
206*00b67f09SDavid van Moolenbroek void
dns_rdatatypestats_increment(dns_stats_t * stats,dns_rdatatype_t type)207*00b67f09SDavid van Moolenbroek dns_rdatatypestats_increment(dns_stats_t *stats, dns_rdatatype_t type) {
208*00b67f09SDavid van Moolenbroek int counter;
209*00b67f09SDavid van Moolenbroek
210*00b67f09SDavid van Moolenbroek REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdtype);
211*00b67f09SDavid van Moolenbroek
212*00b67f09SDavid van Moolenbroek if (type == dns_rdatatype_dlv)
213*00b67f09SDavid van Moolenbroek counter = rdtypecounter_dlv;
214*00b67f09SDavid van Moolenbroek else if (type > dns_rdatatype_any)
215*00b67f09SDavid van Moolenbroek counter = rdtypecounter_others;
216*00b67f09SDavid van Moolenbroek else
217*00b67f09SDavid van Moolenbroek counter = (int)type;
218*00b67f09SDavid van Moolenbroek
219*00b67f09SDavid van Moolenbroek isc_stats_increment(stats->counters, (isc_statscounter_t)counter);
220*00b67f09SDavid van Moolenbroek }
221*00b67f09SDavid van Moolenbroek
222*00b67f09SDavid van Moolenbroek static inline void
update_rdatasetstats(dns_stats_t * stats,dns_rdatastatstype_t rrsettype,isc_boolean_t increment)223*00b67f09SDavid van Moolenbroek update_rdatasetstats(dns_stats_t *stats, dns_rdatastatstype_t rrsettype,
224*00b67f09SDavid van Moolenbroek isc_boolean_t increment)
225*00b67f09SDavid van Moolenbroek {
226*00b67f09SDavid van Moolenbroek int counter;
227*00b67f09SDavid van Moolenbroek dns_rdatatype_t rdtype;
228*00b67f09SDavid van Moolenbroek
229*00b67f09SDavid van Moolenbroek if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) &
230*00b67f09SDavid van Moolenbroek DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) != 0) {
231*00b67f09SDavid van Moolenbroek counter = rdtypecounter_nxdomain;
232*00b67f09SDavid van Moolenbroek } else {
233*00b67f09SDavid van Moolenbroek rdtype = DNS_RDATASTATSTYPE_BASE(rrsettype);
234*00b67f09SDavid van Moolenbroek if (rdtype == dns_rdatatype_dlv)
235*00b67f09SDavid van Moolenbroek counter = (int)rdtypecounter_dlv;
236*00b67f09SDavid van Moolenbroek else if (rdtype > dns_rdatatype_any)
237*00b67f09SDavid van Moolenbroek counter = (int)rdtypecounter_others;
238*00b67f09SDavid van Moolenbroek else
239*00b67f09SDavid van Moolenbroek counter = (int)rdtype;
240*00b67f09SDavid van Moolenbroek
241*00b67f09SDavid van Moolenbroek if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) &
242*00b67f09SDavid van Moolenbroek DNS_RDATASTATSTYPE_ATTR_NXRRSET) != 0)
243*00b67f09SDavid van Moolenbroek counter += rdtypecounter_max;
244*00b67f09SDavid van Moolenbroek }
245*00b67f09SDavid van Moolenbroek
246*00b67f09SDavid van Moolenbroek if (increment) {
247*00b67f09SDavid van Moolenbroek if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) &
248*00b67f09SDavid van Moolenbroek DNS_RDATASTATSTYPE_ATTR_STALE) != 0) {
249*00b67f09SDavid van Moolenbroek isc_stats_decrement(stats->counters, counter);
250*00b67f09SDavid van Moolenbroek counter += rdtypecounter_stale;
251*00b67f09SDavid van Moolenbroek }
252*00b67f09SDavid van Moolenbroek isc_stats_increment(stats->counters, counter);
253*00b67f09SDavid van Moolenbroek } else {
254*00b67f09SDavid van Moolenbroek if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) &
255*00b67f09SDavid van Moolenbroek DNS_RDATASTATSTYPE_ATTR_STALE) != 0)
256*00b67f09SDavid van Moolenbroek counter += rdtypecounter_stale;
257*00b67f09SDavid van Moolenbroek isc_stats_decrement(stats->counters, counter);
258*00b67f09SDavid van Moolenbroek }
259*00b67f09SDavid van Moolenbroek }
260*00b67f09SDavid van Moolenbroek
261*00b67f09SDavid van Moolenbroek void
dns_rdatasetstats_increment(dns_stats_t * stats,dns_rdatastatstype_t rrsettype)262*00b67f09SDavid van Moolenbroek dns_rdatasetstats_increment(dns_stats_t *stats, dns_rdatastatstype_t rrsettype)
263*00b67f09SDavid van Moolenbroek {
264*00b67f09SDavid van Moolenbroek REQUIRE(DNS_STATS_VALID(stats) &&
265*00b67f09SDavid van Moolenbroek stats->type == dns_statstype_rdataset);
266*00b67f09SDavid van Moolenbroek
267*00b67f09SDavid van Moolenbroek update_rdatasetstats(stats, rrsettype, ISC_TRUE);
268*00b67f09SDavid van Moolenbroek }
269*00b67f09SDavid van Moolenbroek
270*00b67f09SDavid van Moolenbroek void
dns_rdatasetstats_decrement(dns_stats_t * stats,dns_rdatastatstype_t rrsettype)271*00b67f09SDavid van Moolenbroek dns_rdatasetstats_decrement(dns_stats_t *stats, dns_rdatastatstype_t rrsettype)
272*00b67f09SDavid van Moolenbroek {
273*00b67f09SDavid van Moolenbroek REQUIRE(DNS_STATS_VALID(stats) &&
274*00b67f09SDavid van Moolenbroek stats->type == dns_statstype_rdataset);
275*00b67f09SDavid van Moolenbroek
276*00b67f09SDavid van Moolenbroek update_rdatasetstats(stats, rrsettype, ISC_FALSE);
277*00b67f09SDavid van Moolenbroek }
278*00b67f09SDavid van Moolenbroek
279*00b67f09SDavid van Moolenbroek void
dns_opcodestats_increment(dns_stats_t * stats,dns_opcode_t code)280*00b67f09SDavid van Moolenbroek dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code) {
281*00b67f09SDavid van Moolenbroek REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_opcode);
282*00b67f09SDavid van Moolenbroek
283*00b67f09SDavid van Moolenbroek isc_stats_increment(stats->counters, (isc_statscounter_t)code);
284*00b67f09SDavid van Moolenbroek }
285*00b67f09SDavid van Moolenbroek
286*00b67f09SDavid van Moolenbroek /*%
287*00b67f09SDavid van Moolenbroek * Dump methods
288*00b67f09SDavid van Moolenbroek */
289*00b67f09SDavid van Moolenbroek void
dns_generalstats_dump(dns_stats_t * stats,dns_generalstats_dumper_t dump_fn,void * arg,unsigned int options)290*00b67f09SDavid van Moolenbroek dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn,
291*00b67f09SDavid van Moolenbroek void *arg, unsigned int options)
292*00b67f09SDavid van Moolenbroek {
293*00b67f09SDavid van Moolenbroek REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_general);
294*00b67f09SDavid van Moolenbroek
295*00b67f09SDavid van Moolenbroek isc_stats_dump(stats->counters, (isc_stats_dumper_t)dump_fn,
296*00b67f09SDavid van Moolenbroek arg, options);
297*00b67f09SDavid van Moolenbroek }
298*00b67f09SDavid van Moolenbroek
299*00b67f09SDavid van Moolenbroek static void
dump_rdentry(int rdcounter,isc_uint64_t value,dns_rdatastatstype_t attributes,dns_rdatatypestats_dumper_t dump_fn,void * arg)300*00b67f09SDavid van Moolenbroek dump_rdentry(int rdcounter, isc_uint64_t value, dns_rdatastatstype_t attributes,
301*00b67f09SDavid van Moolenbroek dns_rdatatypestats_dumper_t dump_fn, void * arg)
302*00b67f09SDavid van Moolenbroek {
303*00b67f09SDavid van Moolenbroek dns_rdatatype_t rdtype = dns_rdatatype_none; /* sentinel */
304*00b67f09SDavid van Moolenbroek dns_rdatastatstype_t type;
305*00b67f09SDavid van Moolenbroek
306*00b67f09SDavid van Moolenbroek if (rdcounter == rdtypecounter_others)
307*00b67f09SDavid van Moolenbroek attributes |= DNS_RDATASTATSTYPE_ATTR_OTHERTYPE;
308*00b67f09SDavid van Moolenbroek else {
309*00b67f09SDavid van Moolenbroek if (rdcounter == rdtypecounter_dlv)
310*00b67f09SDavid van Moolenbroek rdtype = dns_rdatatype_dlv;
311*00b67f09SDavid van Moolenbroek else
312*00b67f09SDavid van Moolenbroek rdtype = (dns_rdatatype_t)rdcounter;
313*00b67f09SDavid van Moolenbroek }
314*00b67f09SDavid van Moolenbroek type = DNS_RDATASTATSTYPE_VALUE((dns_rdatastatstype_t)rdtype,
315*00b67f09SDavid van Moolenbroek attributes);
316*00b67f09SDavid van Moolenbroek dump_fn(type, value, arg);
317*00b67f09SDavid van Moolenbroek }
318*00b67f09SDavid van Moolenbroek
319*00b67f09SDavid van Moolenbroek static void
rdatatype_dumpcb(isc_statscounter_t counter,isc_uint64_t value,void * arg)320*00b67f09SDavid van Moolenbroek rdatatype_dumpcb(isc_statscounter_t counter, isc_uint64_t value, void *arg) {
321*00b67f09SDavid van Moolenbroek rdatadumparg_t *rdatadumparg = arg;
322*00b67f09SDavid van Moolenbroek
323*00b67f09SDavid van Moolenbroek dump_rdentry(counter, value, 0, rdatadumparg->fn, rdatadumparg->arg);
324*00b67f09SDavid van Moolenbroek }
325*00b67f09SDavid van Moolenbroek
326*00b67f09SDavid van Moolenbroek void
dns_rdatatypestats_dump(dns_stats_t * stats,dns_rdatatypestats_dumper_t dump_fn,void * arg0,unsigned int options)327*00b67f09SDavid van Moolenbroek dns_rdatatypestats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
328*00b67f09SDavid van Moolenbroek void *arg0, unsigned int options)
329*00b67f09SDavid van Moolenbroek {
330*00b67f09SDavid van Moolenbroek rdatadumparg_t arg;
331*00b67f09SDavid van Moolenbroek REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdtype);
332*00b67f09SDavid van Moolenbroek
333*00b67f09SDavid van Moolenbroek arg.fn = dump_fn;
334*00b67f09SDavid van Moolenbroek arg.arg = arg0;
335*00b67f09SDavid van Moolenbroek isc_stats_dump(stats->counters, rdatatype_dumpcb, &arg, options);
336*00b67f09SDavid van Moolenbroek }
337*00b67f09SDavid van Moolenbroek
338*00b67f09SDavid van Moolenbroek static void
rdataset_dumpcb(isc_statscounter_t counter,isc_uint64_t value,void * arg)339*00b67f09SDavid van Moolenbroek rdataset_dumpcb(isc_statscounter_t counter, isc_uint64_t value, void *arg) {
340*00b67f09SDavid van Moolenbroek rdatadumparg_t *rdatadumparg = arg;
341*00b67f09SDavid van Moolenbroek unsigned int attributes;
342*00b67f09SDavid van Moolenbroek
343*00b67f09SDavid van Moolenbroek if (counter < rdtypecounter_max) {
344*00b67f09SDavid van Moolenbroek dump_rdentry(counter, value, 0, rdatadumparg->fn,
345*00b67f09SDavid van Moolenbroek rdatadumparg->arg);
346*00b67f09SDavid van Moolenbroek } else if (counter < rdtypecounter_nxdomain) {
347*00b67f09SDavid van Moolenbroek counter -= rdtypecounter_max;
348*00b67f09SDavid van Moolenbroek attributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET;
349*00b67f09SDavid van Moolenbroek dump_rdentry(counter, value, attributes, rdatadumparg->fn,
350*00b67f09SDavid van Moolenbroek rdatadumparg->arg);
351*00b67f09SDavid van Moolenbroek } else if (counter == rdtypecounter_nxdomain) {
352*00b67f09SDavid van Moolenbroek dump_rdentry(0, value, DNS_RDATASTATSTYPE_ATTR_NXDOMAIN,
353*00b67f09SDavid van Moolenbroek rdatadumparg->fn, rdatadumparg->arg);
354*00b67f09SDavid van Moolenbroek } else if (counter < rdtypecounter_stale + rdtypecounter_max) {
355*00b67f09SDavid van Moolenbroek counter -= rdtypecounter_stale;
356*00b67f09SDavid van Moolenbroek attributes = DNS_RDATASTATSTYPE_ATTR_STALE;
357*00b67f09SDavid van Moolenbroek dump_rdentry(counter, value, attributes, rdatadumparg->fn,
358*00b67f09SDavid van Moolenbroek rdatadumparg->arg);
359*00b67f09SDavid van Moolenbroek } else if (counter < rdtypecounter_stale + rdtypecounter_nxdomain) {
360*00b67f09SDavid van Moolenbroek counter -= rdtypecounter_stale + rdtypecounter_max;
361*00b67f09SDavid van Moolenbroek attributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET |
362*00b67f09SDavid van Moolenbroek DNS_RDATASTATSTYPE_ATTR_STALE;
363*00b67f09SDavid van Moolenbroek dump_rdentry(counter, value, attributes, rdatadumparg->fn,
364*00b67f09SDavid van Moolenbroek rdatadumparg->arg);
365*00b67f09SDavid van Moolenbroek } else {
366*00b67f09SDavid van Moolenbroek attributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN |
367*00b67f09SDavid van Moolenbroek DNS_RDATASTATSTYPE_ATTR_STALE;
368*00b67f09SDavid van Moolenbroek dump_rdentry(0, value, attributes, rdatadumparg->fn,
369*00b67f09SDavid van Moolenbroek rdatadumparg->arg);
370*00b67f09SDavid van Moolenbroek }
371*00b67f09SDavid van Moolenbroek }
372*00b67f09SDavid van Moolenbroek
373*00b67f09SDavid van Moolenbroek void
dns_rdatasetstats_dump(dns_stats_t * stats,dns_rdatatypestats_dumper_t dump_fn,void * arg0,unsigned int options)374*00b67f09SDavid van Moolenbroek dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
375*00b67f09SDavid van Moolenbroek void *arg0, unsigned int options)
376*00b67f09SDavid van Moolenbroek {
377*00b67f09SDavid van Moolenbroek rdatadumparg_t arg;
378*00b67f09SDavid van Moolenbroek
379*00b67f09SDavid van Moolenbroek REQUIRE(DNS_STATS_VALID(stats) &&
380*00b67f09SDavid van Moolenbroek stats->type == dns_statstype_rdataset);
381*00b67f09SDavid van Moolenbroek
382*00b67f09SDavid van Moolenbroek arg.fn = dump_fn;
383*00b67f09SDavid van Moolenbroek arg.arg = arg0;
384*00b67f09SDavid van Moolenbroek isc_stats_dump(stats->counters, rdataset_dumpcb, &arg, options);
385*00b67f09SDavid van Moolenbroek }
386*00b67f09SDavid van Moolenbroek
387*00b67f09SDavid van Moolenbroek static void
opcode_dumpcb(isc_statscounter_t counter,isc_uint64_t value,void * arg)388*00b67f09SDavid van Moolenbroek opcode_dumpcb(isc_statscounter_t counter, isc_uint64_t value, void *arg) {
389*00b67f09SDavid van Moolenbroek opcodedumparg_t *opcodearg = arg;
390*00b67f09SDavid van Moolenbroek
391*00b67f09SDavid van Moolenbroek opcodearg->fn((dns_opcode_t)counter, value, opcodearg->arg);
392*00b67f09SDavid van Moolenbroek }
393*00b67f09SDavid van Moolenbroek
394*00b67f09SDavid van Moolenbroek void
dns_opcodestats_dump(dns_stats_t * stats,dns_opcodestats_dumper_t dump_fn,void * arg0,unsigned int options)395*00b67f09SDavid van Moolenbroek dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn,
396*00b67f09SDavid van Moolenbroek void *arg0, unsigned int options)
397*00b67f09SDavid van Moolenbroek {
398*00b67f09SDavid van Moolenbroek opcodedumparg_t arg;
399*00b67f09SDavid van Moolenbroek
400*00b67f09SDavid van Moolenbroek REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_opcode);
401*00b67f09SDavid van Moolenbroek
402*00b67f09SDavid van Moolenbroek arg.fn = dump_fn;
403*00b67f09SDavid van Moolenbroek arg.arg = arg0;
404*00b67f09SDavid van Moolenbroek isc_stats_dump(stats->counters, opcode_dumpcb, &arg, options);
405*00b67f09SDavid van Moolenbroek }
406*00b67f09SDavid van Moolenbroek
407*00b67f09SDavid van Moolenbroek /***
408*00b67f09SDavid van Moolenbroek *** Obsolete variables and functions follow:
409*00b67f09SDavid van Moolenbroek ***/
410*00b67f09SDavid van Moolenbroek LIBDNS_EXTERNAL_DATA const char *dns_statscounter_names[DNS_STATS_NCOUNTERS] =
411*00b67f09SDavid van Moolenbroek {
412*00b67f09SDavid van Moolenbroek "success",
413*00b67f09SDavid van Moolenbroek "referral",
414*00b67f09SDavid van Moolenbroek "nxrrset",
415*00b67f09SDavid van Moolenbroek "nxdomain",
416*00b67f09SDavid van Moolenbroek "recursion",
417*00b67f09SDavid van Moolenbroek "failure",
418*00b67f09SDavid van Moolenbroek "duplicate",
419*00b67f09SDavid van Moolenbroek "dropped"
420*00b67f09SDavid van Moolenbroek };
421*00b67f09SDavid van Moolenbroek
422*00b67f09SDavid van Moolenbroek isc_result_t
dns_stats_alloccounters(isc_mem_t * mctx,isc_uint64_t ** ctrp)423*00b67f09SDavid van Moolenbroek dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp) {
424*00b67f09SDavid van Moolenbroek int i;
425*00b67f09SDavid van Moolenbroek isc_uint64_t *p =
426*00b67f09SDavid van Moolenbroek isc_mem_get(mctx, DNS_STATS_NCOUNTERS * sizeof(isc_uint64_t));
427*00b67f09SDavid van Moolenbroek if (p == NULL)
428*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
429*00b67f09SDavid van Moolenbroek for (i = 0; i < DNS_STATS_NCOUNTERS; i++)
430*00b67f09SDavid van Moolenbroek p[i] = 0;
431*00b67f09SDavid van Moolenbroek *ctrp = p;
432*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
433*00b67f09SDavid van Moolenbroek }
434*00b67f09SDavid van Moolenbroek
435*00b67f09SDavid van Moolenbroek void
dns_stats_freecounters(isc_mem_t * mctx,isc_uint64_t ** ctrp)436*00b67f09SDavid van Moolenbroek dns_stats_freecounters(isc_mem_t *mctx, isc_uint64_t **ctrp) {
437*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, *ctrp, DNS_STATS_NCOUNTERS * sizeof(isc_uint64_t));
438*00b67f09SDavid van Moolenbroek *ctrp = NULL;
439*00b67f09SDavid van Moolenbroek }
440