2 * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: stats.c,v 1.12.128.6 2009/01/29 23:47:13 tbox Exp $ */
24 #include <isc/magic.h>
26 #include <isc/stats.h>
29 #include <dns/opcode.h>
30 #include <dns/rdatatype.h>
31 #include <dns/stats.h>
33 #define DNS_STATS_MAGIC ISC_MAGIC('D', 's', 't', 't')
34 #define DNS_STATS_VALID(x) ISC_MAGIC_VALID(x, DNS_STATS_MAGIC)
40 dns_statstype_general
= 0,
41 dns_statstype_rdtype
= 1,
42 dns_statstype_rdataset
= 2,
43 dns_statstype_opcode
= 3
47 * It doesn't make sense to have 2^16 counters for all possible types since
48 * most of them won't be used. We have counters for the first 256 types and
49 * those explicitly supported in the rdata implementation.
50 * XXXJT: this introduces tight coupling with the rdata implementation.
51 * Ideally, we should have rdata handle this type of details.
54 /* For 0-255, we use the rdtype value as counter indices */
55 rdtypecounter_dlv
= 256, /* for dns_rdatatype_dlv */
56 rdtypecounter_others
= 257, /* anything else */
57 rdtypecounter_max
= 258,
58 /* The following are used for rdataset */
59 rdtypenxcounter_max
= rdtypecounter_max
* 2,
60 rdtypecounter_nxdomain
= rdtypenxcounter_max
,
61 rdatasettypecounter_max
= rdtypecounter_nxdomain
+ 1
70 isc_stats_t
*counters
;
73 unsigned int references
;
76 typedef struct rdatadumparg
{
77 dns_rdatatypestats_dumper_t fn
;
81 typedef struct opcodedumparg
{
82 dns_opcodestats_dumper_t fn
;
87 dns_stats_attach(dns_stats_t
*stats
, dns_stats_t
**statsp
) {
88 REQUIRE(DNS_STATS_VALID(stats
));
89 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
99 dns_stats_detach(dns_stats_t
**statsp
) {
102 REQUIRE(statsp
!= NULL
&& DNS_STATS_VALID(*statsp
));
109 UNLOCK(&stats
->lock
);
111 if (stats
->references
== 0) {
112 isc_stats_detach(&stats
->counters
);
113 DESTROYLOCK(&stats
->lock
);
114 isc_mem_putanddetach(&stats
->mctx
, stats
, sizeof(*stats
));
122 create_stats(isc_mem_t
*mctx
, dns_statstype_t type
, int ncounters
,
123 dns_stats_t
**statsp
)
128 stats
= isc_mem_get(mctx
, sizeof(*stats
));
130 return (ISC_R_NOMEMORY
);
132 stats
->counters
= NULL
;
133 stats
->references
= 1;
135 result
= isc_mutex_init(&stats
->lock
);
136 if (result
!= ISC_R_SUCCESS
)
139 result
= isc_stats_create(mctx
, &stats
->counters
, ncounters
);
140 if (result
!= ISC_R_SUCCESS
)
143 stats
->magic
= DNS_STATS_MAGIC
;
146 isc_mem_attach(mctx
, &stats
->mctx
);
149 return (ISC_R_SUCCESS
);
152 DESTROYLOCK(&stats
->lock
);
154 isc_mem_put(mctx
, stats
, sizeof(*stats
));
160 dns_generalstats_create(isc_mem_t
*mctx
, dns_stats_t
**statsp
, int ncounters
) {
161 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
163 return (create_stats(mctx
, dns_statstype_general
, ncounters
, statsp
));
167 dns_rdatatypestats_create(isc_mem_t
*mctx
, dns_stats_t
**statsp
) {
168 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
170 return (create_stats(mctx
, dns_statstype_rdtype
, rdtypecounter_max
,
175 dns_rdatasetstats_create(isc_mem_t
*mctx
, dns_stats_t
**statsp
) {
176 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
178 return (create_stats(mctx
, dns_statstype_rdataset
,
179 (rdtypecounter_max
* 2) + 1, statsp
));
183 dns_opcodestats_create(isc_mem_t
*mctx
, dns_stats_t
**statsp
) {
184 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
186 return (create_stats(mctx
, dns_statstype_opcode
, 16, statsp
));
190 * Increment/Decrement methods
193 dns_generalstats_increment(dns_stats_t
*stats
, isc_statscounter_t counter
) {
194 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_general
);
196 isc_stats_increment(stats
->counters
, counter
);
200 dns_rdatatypestats_increment(dns_stats_t
*stats
, dns_rdatatype_t type
) {
203 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_rdtype
);
205 if (type
== dns_rdatatype_dlv
)
206 counter
= rdtypecounter_dlv
;
207 else if (type
> dns_rdatatype_any
)
208 counter
= rdtypecounter_others
;
212 isc_stats_increment(stats
->counters
, (isc_statscounter_t
)counter
);
216 update_rdatasetstats(dns_stats_t
*stats
, dns_rdatastatstype_t rrsettype
,
217 isc_boolean_t increment
)
220 dns_rdatatype_t rdtype
;
222 if ((DNS_RDATASTATSTYPE_ATTR(rrsettype
) &
223 DNS_RDATASTATSTYPE_ATTR_NXDOMAIN
) != 0) {
224 counter
= rdtypecounter_nxdomain
;
226 rdtype
= DNS_RDATASTATSTYPE_BASE(rrsettype
);
227 if (rdtype
== dns_rdatatype_dlv
)
228 counter
= (int)rdtypecounter_dlv
;
229 else if (rdtype
> dns_rdatatype_any
)
230 counter
= (int)rdtypecounter_others
;
232 counter
= (int)rdtype
;
234 if ((DNS_RDATASTATSTYPE_ATTR(rrsettype
) &
235 DNS_RDATASTATSTYPE_ATTR_NXRRSET
) != 0)
236 counter
+= rdtypecounter_max
;
240 isc_stats_increment(stats
->counters
, counter
);
242 isc_stats_decrement(stats
->counters
, counter
);
246 dns_rdatasetstats_increment(dns_stats_t
*stats
, dns_rdatastatstype_t rrsettype
)
248 REQUIRE(DNS_STATS_VALID(stats
) &&
249 stats
->type
== dns_statstype_rdataset
);
251 update_rdatasetstats(stats
, rrsettype
, ISC_TRUE
);
255 dns_rdatasetstats_decrement(dns_stats_t
*stats
, dns_rdatastatstype_t rrsettype
)
257 REQUIRE(DNS_STATS_VALID(stats
) &&
258 stats
->type
== dns_statstype_rdataset
);
260 update_rdatasetstats(stats
, rrsettype
, ISC_FALSE
);
263 dns_opcodestats_increment(dns_stats_t
*stats
, dns_opcode_t code
) {
264 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_opcode
);
266 isc_stats_increment(stats
->counters
, (isc_statscounter_t
)code
);
273 dns_generalstats_dump(dns_stats_t
*stats
, dns_generalstats_dumper_t dump_fn
,
274 void *arg
, unsigned int options
)
276 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_general
);
278 isc_stats_dump(stats
->counters
, (isc_stats_dumper_t
)dump_fn
,
283 dump_rdentry(int rdcounter
, isc_uint64_t value
, dns_rdatastatstype_t attributes
,
284 dns_rdatatypestats_dumper_t dump_fn
, void * arg
)
286 dns_rdatatype_t rdtype
= dns_rdatatype_none
; /* sentinel */
287 dns_rdatastatstype_t type
;
289 if (rdcounter
== rdtypecounter_others
)
290 attributes
|= DNS_RDATASTATSTYPE_ATTR_OTHERTYPE
;
292 if (rdcounter
== rdtypecounter_dlv
)
293 rdtype
= dns_rdatatype_dlv
;
295 rdtype
= (dns_rdatatype_t
)rdcounter
;
297 type
= DNS_RDATASTATSTYPE_VALUE((dns_rdatastatstype_t
)rdtype
,
299 dump_fn(type
, value
, arg
);
303 rdatatype_dumpcb(isc_statscounter_t counter
, isc_uint64_t value
, void *arg
) {
304 rdatadumparg_t
*rdatadumparg
= arg
;
306 dump_rdentry(counter
, value
, 0, rdatadumparg
->fn
, rdatadumparg
->arg
);
310 dns_rdatatypestats_dump(dns_stats_t
*stats
, dns_rdatatypestats_dumper_t dump_fn
,
311 void *arg0
, unsigned int options
)
314 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_rdtype
);
318 isc_stats_dump(stats
->counters
, rdatatype_dumpcb
, &arg
, options
);
322 rdataset_dumpcb(isc_statscounter_t counter
, isc_uint64_t value
, void *arg
) {
323 rdatadumparg_t
*rdatadumparg
= arg
;
325 if (counter
< rdtypecounter_max
) {
326 dump_rdentry(counter
, value
, 0, rdatadumparg
->fn
,
328 } else if (counter
< rdtypenxcounter_max
) {
329 dump_rdentry(counter
- rdtypecounter_max
, value
,
330 DNS_RDATASTATSTYPE_ATTR_NXRRSET
,
331 rdatadumparg
->fn
, rdatadumparg
->arg
);
333 dump_rdentry(0, value
, DNS_RDATASTATSTYPE_ATTR_NXDOMAIN
,
334 rdatadumparg
->fn
, rdatadumparg
->arg
);
339 dns_rdatasetstats_dump(dns_stats_t
*stats
, dns_rdatatypestats_dumper_t dump_fn
,
340 void *arg0
, unsigned int options
)
344 REQUIRE(DNS_STATS_VALID(stats
) &&
345 stats
->type
== dns_statstype_rdataset
);
349 isc_stats_dump(stats
->counters
, rdataset_dumpcb
, &arg
, options
);
353 opcode_dumpcb(isc_statscounter_t counter
, isc_uint64_t value
, void *arg
) {
354 opcodedumparg_t
*opcodearg
= arg
;
356 opcodearg
->fn((dns_opcode_t
)counter
, value
, opcodearg
->arg
);
360 dns_opcodestats_dump(dns_stats_t
*stats
, dns_opcodestats_dumper_t dump_fn
,
361 void *arg0
, unsigned int options
)
365 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_opcode
);
369 isc_stats_dump(stats
->counters
, opcode_dumpcb
, &arg
, options
);
373 *** Obsolete variables and functions follow:
375 LIBDNS_EXTERNAL_DATA
const char *dns_statscounter_names
[DNS_STATS_NCOUNTERS
] =
388 dns_stats_alloccounters(isc_mem_t
*mctx
, isc_uint64_t
**ctrp
) {
391 isc_mem_get(mctx
, DNS_STATS_NCOUNTERS
* sizeof(isc_uint64_t
));
393 return (ISC_R_NOMEMORY
);
394 for (i
= 0; i
< DNS_STATS_NCOUNTERS
; i
++)
397 return (ISC_R_SUCCESS
);
401 dns_stats_freecounters(isc_mem_t
*mctx
, isc_uint64_t
**ctrp
) {
402 isc_mem_put(mctx
, *ctrp
, DNS_STATS_NCOUNTERS
* sizeof(isc_uint64_t
));