4 * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2000, 2001 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: stats.c,v 1.18 2009/01/27 23:47:54 tbox Exp */
26 #include <isc/magic.h>
28 #include <isc/stats.h>
31 #include <dns/opcode.h>
32 #include <dns/rdatatype.h>
33 #include <dns/stats.h>
35 #define DNS_STATS_MAGIC ISC_MAGIC('D', 's', 't', 't')
36 #define DNS_STATS_VALID(x) ISC_MAGIC_VALID(x, DNS_STATS_MAGIC)
42 dns_statstype_general
= 0,
43 dns_statstype_rdtype
= 1,
44 dns_statstype_rdataset
= 2,
45 dns_statstype_opcode
= 3
49 * It doesn't make sense to have 2^16 counters for all possible types since
50 * most of them won't be used. We have counters for the first 256 types and
51 * those explicitly supported in the rdata implementation.
52 * XXXJT: this introduces tight coupling with the rdata implementation.
53 * Ideally, we should have rdata handle this type of details.
56 /* For 0-255, we use the rdtype value as counter indices */
57 rdtypecounter_dlv
= 256, /* for dns_rdatatype_dlv */
58 rdtypecounter_others
= 257, /* anything else */
59 rdtypecounter_max
= 258,
60 /* The following are used for rdataset */
61 rdtypenxcounter_max
= rdtypecounter_max
* 2,
62 rdtypecounter_nxdomain
= rdtypenxcounter_max
,
63 rdatasettypecounter_max
= rdtypecounter_nxdomain
+ 1
72 isc_stats_t
*counters
;
75 unsigned int references
;
78 typedef struct rdatadumparg
{
79 dns_rdatatypestats_dumper_t fn
;
83 typedef struct opcodedumparg
{
84 dns_opcodestats_dumper_t fn
;
89 dns_stats_attach(dns_stats_t
*stats
, dns_stats_t
**statsp
) {
90 REQUIRE(DNS_STATS_VALID(stats
));
91 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
101 dns_stats_detach(dns_stats_t
**statsp
) {
104 REQUIRE(statsp
!= NULL
&& DNS_STATS_VALID(*statsp
));
111 UNLOCK(&stats
->lock
);
113 if (stats
->references
== 0) {
114 isc_stats_detach(&stats
->counters
);
115 DESTROYLOCK(&stats
->lock
);
116 isc_mem_putanddetach(&stats
->mctx
, stats
, sizeof(*stats
));
124 create_stats(isc_mem_t
*mctx
, dns_statstype_t type
, int ncounters
,
125 dns_stats_t
**statsp
)
130 stats
= isc_mem_get(mctx
, sizeof(*stats
));
132 return (ISC_R_NOMEMORY
);
134 stats
->counters
= NULL
;
135 stats
->references
= 1;
137 result
= isc_mutex_init(&stats
->lock
);
138 if (result
!= ISC_R_SUCCESS
)
141 result
= isc_stats_create(mctx
, &stats
->counters
, ncounters
);
142 if (result
!= ISC_R_SUCCESS
)
145 stats
->magic
= DNS_STATS_MAGIC
;
148 isc_mem_attach(mctx
, &stats
->mctx
);
151 return (ISC_R_SUCCESS
);
154 DESTROYLOCK(&stats
->lock
);
156 isc_mem_put(mctx
, stats
, sizeof(*stats
));
162 dns_generalstats_create(isc_mem_t
*mctx
, dns_stats_t
**statsp
, int ncounters
) {
163 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
165 return (create_stats(mctx
, dns_statstype_general
, ncounters
, statsp
));
169 dns_rdatatypestats_create(isc_mem_t
*mctx
, dns_stats_t
**statsp
) {
170 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
172 return (create_stats(mctx
, dns_statstype_rdtype
, rdtypecounter_max
,
177 dns_rdatasetstats_create(isc_mem_t
*mctx
, dns_stats_t
**statsp
) {
178 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
180 return (create_stats(mctx
, dns_statstype_rdataset
,
181 (rdtypecounter_max
* 2) + 1, statsp
));
185 dns_opcodestats_create(isc_mem_t
*mctx
, dns_stats_t
**statsp
) {
186 REQUIRE(statsp
!= NULL
&& *statsp
== NULL
);
188 return (create_stats(mctx
, dns_statstype_opcode
, 16, statsp
));
192 * Increment/Decrement methods
195 dns_generalstats_increment(dns_stats_t
*stats
, isc_statscounter_t counter
) {
196 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_general
);
198 isc_stats_increment(stats
->counters
, counter
);
202 dns_rdatatypestats_increment(dns_stats_t
*stats
, dns_rdatatype_t type
) {
205 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_rdtype
);
207 if (type
== dns_rdatatype_dlv
)
208 counter
= rdtypecounter_dlv
;
209 else if (type
> dns_rdatatype_any
)
210 counter
= rdtypecounter_others
;
214 isc_stats_increment(stats
->counters
, (isc_statscounter_t
)counter
);
218 update_rdatasetstats(dns_stats_t
*stats
, dns_rdatastatstype_t rrsettype
,
219 isc_boolean_t increment
)
222 dns_rdatatype_t rdtype
;
224 if ((DNS_RDATASTATSTYPE_ATTR(rrsettype
) &
225 DNS_RDATASTATSTYPE_ATTR_NXDOMAIN
) != 0) {
226 counter
= rdtypecounter_nxdomain
;
228 rdtype
= DNS_RDATASTATSTYPE_BASE(rrsettype
);
229 if (rdtype
== dns_rdatatype_dlv
)
230 counter
= (int)rdtypecounter_dlv
;
231 else if (rdtype
> dns_rdatatype_any
)
232 counter
= (int)rdtypecounter_others
;
234 counter
= (int)rdtype
;
236 if ((DNS_RDATASTATSTYPE_ATTR(rrsettype
) &
237 DNS_RDATASTATSTYPE_ATTR_NXRRSET
) != 0)
238 counter
+= rdtypecounter_max
;
242 isc_stats_increment(stats
->counters
, counter
);
244 isc_stats_decrement(stats
->counters
, counter
);
248 dns_rdatasetstats_increment(dns_stats_t
*stats
, dns_rdatastatstype_t rrsettype
)
250 REQUIRE(DNS_STATS_VALID(stats
) &&
251 stats
->type
== dns_statstype_rdataset
);
253 update_rdatasetstats(stats
, rrsettype
, ISC_TRUE
);
257 dns_rdatasetstats_decrement(dns_stats_t
*stats
, dns_rdatastatstype_t rrsettype
)
259 REQUIRE(DNS_STATS_VALID(stats
) &&
260 stats
->type
== dns_statstype_rdataset
);
262 update_rdatasetstats(stats
, rrsettype
, ISC_FALSE
);
265 dns_opcodestats_increment(dns_stats_t
*stats
, dns_opcode_t code
) {
266 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_opcode
);
268 isc_stats_increment(stats
->counters
, (isc_statscounter_t
)code
);
275 dns_generalstats_dump(dns_stats_t
*stats
, dns_generalstats_dumper_t dump_fn
,
276 void *arg
, unsigned int options
)
278 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_general
);
280 isc_stats_dump(stats
->counters
, (isc_stats_dumper_t
)dump_fn
,
285 dump_rdentry(int rdcounter
, isc_uint64_t value
, dns_rdatastatstype_t attributes
,
286 dns_rdatatypestats_dumper_t dump_fn
, void * arg
)
288 dns_rdatatype_t rdtype
= dns_rdatatype_none
; /* sentinel */
289 dns_rdatastatstype_t type
;
291 if (rdcounter
== rdtypecounter_others
)
292 attributes
|= DNS_RDATASTATSTYPE_ATTR_OTHERTYPE
;
294 if (rdcounter
== rdtypecounter_dlv
)
295 rdtype
= dns_rdatatype_dlv
;
297 rdtype
= (dns_rdatatype_t
)rdcounter
;
299 type
= DNS_RDATASTATSTYPE_VALUE((dns_rdatastatstype_t
)rdtype
,
301 dump_fn(type
, value
, arg
);
305 rdatatype_dumpcb(isc_statscounter_t counter
, isc_uint64_t value
, void *arg
) {
306 rdatadumparg_t
*rdatadumparg
= arg
;
308 dump_rdentry(counter
, value
, 0, rdatadumparg
->fn
, rdatadumparg
->arg
);
312 dns_rdatatypestats_dump(dns_stats_t
*stats
, dns_rdatatypestats_dumper_t dump_fn
,
313 void *arg0
, unsigned int options
)
316 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_rdtype
);
320 isc_stats_dump(stats
->counters
, rdatatype_dumpcb
, &arg
, options
);
324 rdataset_dumpcb(isc_statscounter_t counter
, isc_uint64_t value
, void *arg
) {
325 rdatadumparg_t
*rdatadumparg
= arg
;
327 if (counter
< rdtypecounter_max
) {
328 dump_rdentry(counter
, value
, 0, rdatadumparg
->fn
,
330 } else if (counter
< rdtypenxcounter_max
) {
331 dump_rdentry(counter
- rdtypecounter_max
, value
,
332 DNS_RDATASTATSTYPE_ATTR_NXRRSET
,
333 rdatadumparg
->fn
, rdatadumparg
->arg
);
335 dump_rdentry(0, value
, DNS_RDATASTATSTYPE_ATTR_NXDOMAIN
,
336 rdatadumparg
->fn
, rdatadumparg
->arg
);
341 dns_rdatasetstats_dump(dns_stats_t
*stats
, dns_rdatatypestats_dumper_t dump_fn
,
342 void *arg0
, unsigned int options
)
346 REQUIRE(DNS_STATS_VALID(stats
) &&
347 stats
->type
== dns_statstype_rdataset
);
351 isc_stats_dump(stats
->counters
, rdataset_dumpcb
, &arg
, options
);
355 opcode_dumpcb(isc_statscounter_t counter
, isc_uint64_t value
, void *arg
) {
356 opcodedumparg_t
*opcodearg
= arg
;
358 opcodearg
->fn((dns_opcode_t
)counter
, value
, opcodearg
->arg
);
362 dns_opcodestats_dump(dns_stats_t
*stats
, dns_opcodestats_dumper_t dump_fn
,
363 void *arg0
, unsigned int options
)
367 REQUIRE(DNS_STATS_VALID(stats
) && stats
->type
== dns_statstype_opcode
);
371 isc_stats_dump(stats
->counters
, opcode_dumpcb
, &arg
, options
);
375 *** Obsolete variables and functions follow:
377 LIBDNS_EXTERNAL_DATA
const char *dns_statscounter_names
[DNS_STATS_NCOUNTERS
] =
390 dns_stats_alloccounters(isc_mem_t
*mctx
, isc_uint64_t
**ctrp
) {
393 isc_mem_get(mctx
, DNS_STATS_NCOUNTERS
* sizeof(isc_uint64_t
));
395 return (ISC_R_NOMEMORY
);
396 for (i
= 0; i
< DNS_STATS_NCOUNTERS
; i
++)
399 return (ISC_R_SUCCESS
);
403 dns_stats_freecounters(isc_mem_t
*mctx
, isc_uint64_t
**ctrp
) {
404 isc_mem_put(mctx
, *ctrp
, DNS_STATS_NCOUNTERS
* sizeof(isc_uint64_t
));