xref: /minix3/external/bsd/bind/dist/lib/dns/stats.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
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