1 /*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 *
8 * See the COPYRIGHT file distributed with this work for additional
9 * information regarding copyright ownership.
10 */
11
12 /*! \file */
13
14 #include <inttypes.h>
15 #include <stdbool.h>
16
17 #include <isc/buffer.h>
18 #include <isc/httpd.h>
19 #include <isc/mem.h>
20 #include <isc/once.h>
21 #include <isc/print.h>
22 #include <isc/socket.h>
23 #include <isc/stats.h>
24 #include <isc/string.h>
25 #include <isc/task.h>
26 #include <isc/util.h>
27
28 #include <dns/cache.h>
29 #include <dns/db.h>
30 #include <dns/opcode.h>
31 #include <dns/rcode.h>
32 #include <dns/rdataclass.h>
33 #include <dns/rdatatype.h>
34 #include <dns/resolver.h>
35 #include <dns/stats.h>
36 #include <dns/view.h>
37 #include <dns/zt.h>
38
39 #include <ns/stats.h>
40
41 #include <named/log.h>
42 #include <named/server.h>
43 #include <named/statschannel.h>
44
45 #if HAVE_JSON_C
46 #include <json_object.h>
47 #include <linkhash.h>
48 #endif /* HAVE_JSON_C */
49
50 #if HAVE_LIBXML2
51 #include <libxml/xmlwriter.h>
52 #define ISC_XMLCHAR (const xmlChar *)
53 #endif /* HAVE_LIBXML2 */
54
55 #include "bind9.xsl.h"
56
57 struct named_statschannel {
58 /* Unlocked */
59 isc_httpdmgr_t *httpdmgr;
60 isc_sockaddr_t address;
61 isc_mem_t *mctx;
62
63 /*
64 * Locked by channel lock: can be referenced and modified by both
65 * the server task and the channel task.
66 */
67 isc_mutex_t lock;
68 dns_acl_t *acl;
69
70 /* Locked by server task */
71 ISC_LINK(struct named_statschannel) link;
72 };
73
74 typedef struct stats_dumparg {
75 isc_statsformat_t type;
76 void *arg; /* type dependent argument */
77 int ncounters; /* for general statistics */
78 int *counterindices; /* for general statistics */
79 uint64_t *countervalues; /* for general statistics */
80 isc_result_t result;
81 } stats_dumparg_t;
82
83 static isc_once_t once = ISC_ONCE_INIT;
84
85 #if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C)
86 #define EXTENDED_STATS
87 #else /* if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C) */
88 #undef EXTENDED_STATS
89 #endif /* if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C) */
90
91 #ifdef EXTENDED_STATS
92 static const char *
user_zonetype(dns_zone_t * zone)93 user_zonetype(dns_zone_t *zone) {
94 dns_zonetype_t ztype;
95 dns_view_t *view;
96 static const struct zt {
97 const dns_zonetype_t type;
98 const char *const string;
99 } typemap[] = { { dns_zone_none, "none" },
100 { dns_zone_master, "master" },
101 { dns_zone_slave, "slave" },
102 { dns_zone_mirror, "mirror" },
103 { dns_zone_stub, "stub" },
104 { dns_zone_staticstub, "static-stub" },
105 { dns_zone_key, "key" },
106 { dns_zone_dlz, "dlz" },
107 { dns_zone_redirect, "redirect" },
108 { 0, NULL } };
109 const struct zt *tp;
110
111 if ((dns_zone_getoptions(zone) & DNS_ZONEOPT_AUTOEMPTY) != 0) {
112 return ("builtin");
113 }
114
115 view = dns_zone_getview(zone);
116 if (view != NULL && strcmp(view->name, "_bind") == 0) {
117 return ("builtin");
118 }
119
120 ztype = dns_zone_gettype(zone);
121 for (tp = typemap; tp->string != NULL && tp->type != ztype; tp++) {
122 /* empty */
123 }
124 return (tp->string);
125 }
126 #endif /* ifdef EXTENDED_STATS */
127
128 /*%
129 * Statistics descriptions. These could be statistically initialized at
130 * compile time, but we configure them run time in the init_desc() function
131 * below so that they'll be less susceptible to counter name changes.
132 */
133 static const char *nsstats_desc[ns_statscounter_max];
134 static const char *resstats_desc[dns_resstatscounter_max];
135 static const char *adbstats_desc[dns_adbstats_max];
136 static const char *zonestats_desc[dns_zonestatscounter_max];
137 static const char *sockstats_desc[isc_sockstatscounter_max];
138 static const char *dnssecstats_desc[dns_dnssecstats_max];
139 static const char *udpinsizestats_desc[dns_sizecounter_in_max];
140 static const char *udpoutsizestats_desc[dns_sizecounter_out_max];
141 static const char *tcpinsizestats_desc[dns_sizecounter_in_max];
142 static const char *tcpoutsizestats_desc[dns_sizecounter_out_max];
143 static const char *dnstapstats_desc[dns_dnstapcounter_max];
144 static const char *gluecachestats_desc[dns_gluecachestatscounter_max];
145 #if defined(EXTENDED_STATS)
146 static const char *nsstats_xmldesc[ns_statscounter_max];
147 static const char *resstats_xmldesc[dns_resstatscounter_max];
148 static const char *adbstats_xmldesc[dns_adbstats_max];
149 static const char *zonestats_xmldesc[dns_zonestatscounter_max];
150 static const char *sockstats_xmldesc[isc_sockstatscounter_max];
151 static const char *dnssecstats_xmldesc[dns_dnssecstats_max];
152 static const char *udpinsizestats_xmldesc[dns_sizecounter_in_max];
153 static const char *udpoutsizestats_xmldesc[dns_sizecounter_out_max];
154 static const char *tcpinsizestats_xmldesc[dns_sizecounter_in_max];
155 static const char *tcpoutsizestats_xmldesc[dns_sizecounter_out_max];
156 static const char *dnstapstats_xmldesc[dns_dnstapcounter_max];
157 static const char *gluecachestats_xmldesc[dns_gluecachestatscounter_max];
158 #else /* if defined(EXTENDED_STATS) */
159 #define nsstats_xmldesc NULL
160 #define resstats_xmldesc NULL
161 #define adbstats_xmldesc NULL
162 #define zonestats_xmldesc NULL
163 #define sockstats_xmldesc NULL
164 #define dnssecstats_xmldesc NULL
165 #define udpinsizestats_xmldesc NULL
166 #define udpoutsizestats_xmldesc NULL
167 #define tcpinsizestats_xmldesc NULL
168 #define tcpoutsizestats_xmldesc NULL
169 #define dnstapstats_xmldesc NULL
170 #define gluecachestats_xmldesc NULL
171 #endif /* EXTENDED_STATS */
172
173 #define TRY0(a) \
174 do { \
175 xmlrc = (a); \
176 if (xmlrc < 0) \
177 goto error; \
178 } while (0)
179
180 /*%
181 * Mapping arrays to represent statistics counters in the order of our
182 * preference, regardless of the order of counter indices. For example,
183 * nsstats_desc[nsstats_index[0]] will be the description that is shown first.
184 */
185 static int nsstats_index[ns_statscounter_max];
186 static int resstats_index[dns_resstatscounter_max];
187 static int adbstats_index[dns_adbstats_max];
188 static int zonestats_index[dns_zonestatscounter_max];
189 static int sockstats_index[isc_sockstatscounter_max];
190 static int dnssecstats_index[dns_dnssecstats_max];
191 static int udpinsizestats_index[dns_sizecounter_in_max];
192 static int udpoutsizestats_index[dns_sizecounter_out_max];
193 static int tcpinsizestats_index[dns_sizecounter_in_max];
194 static int tcpoutsizestats_index[dns_sizecounter_out_max];
195 static int dnstapstats_index[dns_dnstapcounter_max];
196 static int gluecachestats_index[dns_gluecachestatscounter_max];
197
198 static inline void
set_desc(int counter,int maxcounter,const char * fdesc,const char ** fdescs,const char * xdesc,const char ** xdescs)199 set_desc(int counter, int maxcounter, const char *fdesc, const char **fdescs,
200 const char *xdesc, const char **xdescs) {
201 REQUIRE(counter < maxcounter);
202 REQUIRE(fdescs != NULL && fdescs[counter] == NULL);
203 #if defined(EXTENDED_STATS)
204 REQUIRE(xdescs != NULL && xdescs[counter] == NULL);
205 #endif /* if defined(EXTENDED_STATS) */
206
207 fdescs[counter] = fdesc;
208 #if defined(EXTENDED_STATS)
209 xdescs[counter] = xdesc;
210 #else /* if defined(EXTENDED_STATS) */
211 UNUSED(xdesc);
212 UNUSED(xdescs);
213 #endif /* if defined(EXTENDED_STATS) */
214 }
215
216 static void
init_desc(void)217 init_desc(void) {
218 int i;
219
220 /* Initialize name server statistics */
221 for (i = 0; i < ns_statscounter_max; i++) {
222 nsstats_desc[i] = NULL;
223 }
224 #if defined(EXTENDED_STATS)
225 for (i = 0; i < ns_statscounter_max; i++) {
226 nsstats_xmldesc[i] = NULL;
227 }
228 #endif /* if defined(EXTENDED_STATS) */
229
230 #define SET_NSSTATDESC(counterid, desc, xmldesc) \
231 do { \
232 set_desc(ns_statscounter_##counterid, ns_statscounter_max, \
233 desc, nsstats_desc, xmldesc, nsstats_xmldesc); \
234 nsstats_index[i++] = ns_statscounter_##counterid; \
235 } while (0)
236
237 i = 0;
238 SET_NSSTATDESC(requestv4, "IPv4 requests received", "Requestv4");
239 SET_NSSTATDESC(requestv6, "IPv6 requests received", "Requestv6");
240 SET_NSSTATDESC(edns0in, "requests with EDNS(0) received", "ReqEdns0");
241 SET_NSSTATDESC(badednsver,
242 "requests with unsupported EDNS version received",
243 "ReqBadEDNSVer");
244 SET_NSSTATDESC(tsigin, "requests with TSIG received", "ReqTSIG");
245 SET_NSSTATDESC(sig0in, "requests with SIG(0) received", "ReqSIG0");
246 SET_NSSTATDESC(invalidsig, "requests with invalid signature",
247 "ReqBadSIG");
248 SET_NSSTATDESC(requesttcp, "TCP requests received", "ReqTCP");
249 SET_NSSTATDESC(tcphighwater, "TCP connection high-water",
250 "TCPConnHighWater");
251 SET_NSSTATDESC(authrej, "auth queries rejected", "AuthQryRej");
252 SET_NSSTATDESC(recurserej, "recursive queries rejected", "RecQryRej");
253 SET_NSSTATDESC(xfrrej, "transfer requests rejected", "XfrRej");
254 SET_NSSTATDESC(updaterej, "update requests rejected", "UpdateRej");
255 SET_NSSTATDESC(response, "responses sent", "Response");
256 SET_NSSTATDESC(truncatedresp, "truncated responses sent",
257 "TruncatedResp");
258 SET_NSSTATDESC(edns0out, "responses with EDNS(0) sent", "RespEDNS0");
259 SET_NSSTATDESC(tsigout, "responses with TSIG sent", "RespTSIG");
260 SET_NSSTATDESC(sig0out, "responses with SIG(0) sent", "RespSIG0");
261 SET_NSSTATDESC(success, "queries resulted in successful answer",
262 "QrySuccess");
263 SET_NSSTATDESC(authans, "queries resulted in authoritative answer",
264 "QryAuthAns");
265 SET_NSSTATDESC(nonauthans,
266 "queries resulted in non authoritative answer",
267 "QryNoauthAns");
268 SET_NSSTATDESC(referral, "queries resulted in referral answer",
269 "QryReferral");
270 SET_NSSTATDESC(nxrrset, "queries resulted in nxrrset", "QryNxrrset");
271 SET_NSSTATDESC(servfail, "queries resulted in SERVFAIL", "QrySERVFAIL");
272 SET_NSSTATDESC(formerr, "queries resulted in FORMERR", "QryFORMERR");
273 SET_NSSTATDESC(nxdomain, "queries resulted in NXDOMAIN", "QryNXDOMAIN");
274 SET_NSSTATDESC(recursion, "queries caused recursion", "QryRecursion");
275 SET_NSSTATDESC(duplicate, "duplicate queries received", "QryDuplicate");
276 SET_NSSTATDESC(dropped, "queries dropped", "QryDropped");
277 SET_NSSTATDESC(failure, "other query failures", "QryFailure");
278 SET_NSSTATDESC(xfrdone, "requested transfers completed", "XfrReqDone");
279 SET_NSSTATDESC(updatereqfwd, "update requests forwarded",
280 "UpdateReqFwd");
281 SET_NSSTATDESC(updaterespfwd, "update responses forwarded",
282 "UpdateRespFwd");
283 SET_NSSTATDESC(updatefwdfail, "update forward failed", "UpdateFwdFail");
284 SET_NSSTATDESC(updatedone, "updates completed", "UpdateDone");
285 SET_NSSTATDESC(updatefail, "updates failed", "UpdateFail");
286 SET_NSSTATDESC(updatebadprereq,
287 "updates rejected due to prerequisite failure",
288 "UpdateBadPrereq");
289 SET_NSSTATDESC(recursclients, "recursing clients", "RecursClients");
290 SET_NSSTATDESC(dns64, "queries answered by DNS64", "DNS64");
291 SET_NSSTATDESC(ratedropped, "responses dropped for rate limits",
292 "RateDropped");
293 SET_NSSTATDESC(rateslipped, "responses truncated for rate limits",
294 "RateSlipped");
295 SET_NSSTATDESC(rpz_rewrites, "response policy zone rewrites",
296 "RPZRewrites");
297 SET_NSSTATDESC(udp, "UDP queries received", "QryUDP");
298 SET_NSSTATDESC(tcp, "TCP queries received", "QryTCP");
299 SET_NSSTATDESC(nsidopt, "NSID option received", "NSIDOpt");
300 SET_NSSTATDESC(expireopt, "Expire option received", "ExpireOpt");
301 SET_NSSTATDESC(keepaliveopt, "EDNS TCP keepalive option received",
302 "KeepAliveOpt");
303 SET_NSSTATDESC(padopt, "EDNS padding option received", "PadOpt");
304 SET_NSSTATDESC(otheropt, "Other EDNS option received", "OtherOpt");
305 SET_NSSTATDESC(cookiein, "COOKIE option received", "CookieIn");
306 SET_NSSTATDESC(cookienew, "COOKIE - client only", "CookieNew");
307 SET_NSSTATDESC(cookiebadsize, "COOKIE - bad size", "CookieBadSize");
308 SET_NSSTATDESC(cookiebadtime, "COOKIE - bad time", "CookieBadTime");
309 SET_NSSTATDESC(cookienomatch, "COOKIE - no match", "CookieNoMatch");
310 SET_NSSTATDESC(cookiematch, "COOKIE - match", "CookieMatch");
311 SET_NSSTATDESC(ecsopt, "EDNS client subnet option received", "ECSOpt");
312 SET_NSSTATDESC(nxdomainredirect,
313 "queries resulted in NXDOMAIN that were redirected",
314 "QryNXRedir");
315 SET_NSSTATDESC(nxdomainredirect_rlookup,
316 "queries resulted in NXDOMAIN that were redirected and "
317 "resulted in a successful remote lookup",
318 "QryNXRedirRLookup");
319 SET_NSSTATDESC(badcookie, "sent badcookie response", "QryBADCOOKIE");
320 SET_NSSTATDESC(nxdomainsynth, "synthesized a NXDOMAIN response",
321 "SynthNXDOMAIN");
322 SET_NSSTATDESC(nodatasynth, "syththesized a no-data response",
323 "SynthNODATA");
324 SET_NSSTATDESC(wildcardsynth, "synthesized a wildcard response",
325 "SynthWILDCARD");
326 SET_NSSTATDESC(trystale,
327 "attempts to use stale cache data after lookup failure",
328 "QryTryStale");
329 SET_NSSTATDESC(usedstale,
330 "successful uses of stale cache data after lookup "
331 "failure",
332 "QryUsedStale");
333 SET_NSSTATDESC(prefetch, "queries triggered prefetch", "Prefetch");
334 SET_NSSTATDESC(keytagopt, "Keytag option received", "KeyTagOpt");
335 SET_NSSTATDESC(reclimitdropped,
336 "queries dropped due to recursive client limit",
337 "RecLimitDropped");
338
339 INSIST(i == ns_statscounter_max);
340
341 /* Initialize resolver statistics */
342 for (i = 0; i < dns_resstatscounter_max; i++) {
343 resstats_desc[i] = NULL;
344 }
345 #if defined(EXTENDED_STATS)
346 for (i = 0; i < dns_resstatscounter_max; i++) {
347 resstats_xmldesc[i] = NULL;
348 }
349 #endif /* if defined(EXTENDED_STATS) */
350
351 #define SET_RESSTATDESC(counterid, desc, xmldesc) \
352 do { \
353 set_desc(dns_resstatscounter_##counterid, \
354 dns_resstatscounter_max, desc, resstats_desc, \
355 xmldesc, resstats_xmldesc); \
356 resstats_index[i++] = dns_resstatscounter_##counterid; \
357 } while (0)
358
359 i = 0;
360 SET_RESSTATDESC(queryv4, "IPv4 queries sent", "Queryv4");
361 SET_RESSTATDESC(queryv6, "IPv6 queries sent", "Queryv6");
362 SET_RESSTATDESC(responsev4, "IPv4 responses received", "Responsev4");
363 SET_RESSTATDESC(responsev6, "IPv6 responses received", "Responsev6");
364 SET_RESSTATDESC(nxdomain, "NXDOMAIN received", "NXDOMAIN");
365 SET_RESSTATDESC(servfail, "SERVFAIL received", "SERVFAIL");
366 SET_RESSTATDESC(formerr, "FORMERR received", "FORMERR");
367 SET_RESSTATDESC(othererror, "other errors received", "OtherError");
368 SET_RESSTATDESC(edns0fail, "EDNS(0) query failures", "EDNS0Fail");
369 SET_RESSTATDESC(mismatch, "mismatch responses received", "Mismatch");
370 SET_RESSTATDESC(truncated, "truncated responses received", "Truncated");
371 SET_RESSTATDESC(lame, "lame delegations received", "Lame");
372 SET_RESSTATDESC(retry, "query retries", "Retry");
373 SET_RESSTATDESC(dispabort, "queries aborted due to quota",
374 "QueryAbort");
375 SET_RESSTATDESC(dispsockfail, "failures in opening query sockets",
376 "QuerySockFail");
377 SET_RESSTATDESC(disprequdp, "UDP queries in progress", "QueryCurUDP");
378 SET_RESSTATDESC(dispreqtcp, "TCP queries in progress", "QueryCurTCP");
379 SET_RESSTATDESC(querytimeout, "query timeouts", "QueryTimeout");
380 SET_RESSTATDESC(gluefetchv4, "IPv4 NS address fetches", "GlueFetchv4");
381 SET_RESSTATDESC(gluefetchv6, "IPv6 NS address fetches", "GlueFetchv6");
382 SET_RESSTATDESC(gluefetchv4fail, "IPv4 NS address fetch failed",
383 "GlueFetchv4Fail");
384 SET_RESSTATDESC(gluefetchv6fail, "IPv6 NS address fetch failed",
385 "GlueFetchv6Fail");
386 SET_RESSTATDESC(val, "DNSSEC validation attempted", "ValAttempt");
387 SET_RESSTATDESC(valsuccess, "DNSSEC validation succeeded", "ValOk");
388 SET_RESSTATDESC(valnegsuccess, "DNSSEC NX validation succeeded",
389 "ValNegOk");
390 SET_RESSTATDESC(valfail, "DNSSEC validation failed", "ValFail");
391 SET_RESSTATDESC(queryrtt0,
392 "queries with RTT < " DNS_RESOLVER_QRYRTTCLASS0STR "ms",
393 "QryRTT" DNS_RESOLVER_QRYRTTCLASS0STR);
394 SET_RESSTATDESC(queryrtt1,
395 "queries with RTT " DNS_RESOLVER_QRYRTTCLASS0STR
396 "-" DNS_RESOLVER_QRYRTTCLASS1STR "ms",
397 "QryRTT" DNS_RESOLVER_QRYRTTCLASS1STR);
398 SET_RESSTATDESC(queryrtt2,
399 "queries with RTT " DNS_RESOLVER_QRYRTTCLASS1STR
400 "-" DNS_RESOLVER_QRYRTTCLASS2STR "ms",
401 "QryRTT" DNS_RESOLVER_QRYRTTCLASS2STR);
402 SET_RESSTATDESC(queryrtt3,
403 "queries with RTT " DNS_RESOLVER_QRYRTTCLASS2STR
404 "-" DNS_RESOLVER_QRYRTTCLASS3STR "ms",
405 "QryRTT" DNS_RESOLVER_QRYRTTCLASS3STR);
406 SET_RESSTATDESC(queryrtt4,
407 "queries with RTT " DNS_RESOLVER_QRYRTTCLASS3STR
408 "-" DNS_RESOLVER_QRYRTTCLASS4STR "ms",
409 "QryRTT" DNS_RESOLVER_QRYRTTCLASS4STR);
410 SET_RESSTATDESC(queryrtt5,
411 "queries with RTT > " DNS_RESOLVER_QRYRTTCLASS4STR "ms",
412 "QryRTT" DNS_RESOLVER_QRYRTTCLASS4STR "+");
413 SET_RESSTATDESC(nfetch, "active fetches", "NumFetch");
414 SET_RESSTATDESC(buckets, "bucket size", "BucketSize");
415 SET_RESSTATDESC(refused, "REFUSED received", "REFUSED");
416 SET_RESSTATDESC(cookienew, "COOKIE send with client cookie only",
417 "ClientCookieOut");
418 SET_RESSTATDESC(cookieout, "COOKIE sent with client and server cookie",
419 "ServerCookieOut");
420 SET_RESSTATDESC(cookiein, "COOKIE replies received", "CookieIn");
421 SET_RESSTATDESC(cookieok, "COOKIE client ok", "CookieClientOk");
422 SET_RESSTATDESC(badvers, "bad EDNS version", "BadEDNSVersion");
423 SET_RESSTATDESC(badcookie, "bad cookie rcode", "BadCookieRcode");
424 SET_RESSTATDESC(zonequota, "spilled due to zone quota", "ZoneQuota");
425 SET_RESSTATDESC(serverquota, "spilled due to server quota",
426 "ServerQuota");
427 SET_RESSTATDESC(nextitem, "waited for next item", "NextItem");
428 SET_RESSTATDESC(priming, "priming queries", "Priming");
429
430 INSIST(i == dns_resstatscounter_max);
431
432 /* Initialize adb statistics */
433 for (i = 0; i < dns_adbstats_max; i++) {
434 adbstats_desc[i] = NULL;
435 }
436 #if defined(EXTENDED_STATS)
437 for (i = 0; i < dns_adbstats_max; i++) {
438 adbstats_xmldesc[i] = NULL;
439 }
440 #endif /* if defined(EXTENDED_STATS) */
441
442 #define SET_ADBSTATDESC(id, desc, xmldesc) \
443 do { \
444 set_desc(dns_adbstats_##id, dns_adbstats_max, desc, \
445 adbstats_desc, xmldesc, adbstats_xmldesc); \
446 adbstats_index[i++] = dns_adbstats_##id; \
447 } while (0)
448 i = 0;
449 SET_ADBSTATDESC(nentries, "Address hash table size", "nentries");
450 SET_ADBSTATDESC(entriescnt, "Addresses in hash table", "entriescnt");
451 SET_ADBSTATDESC(nnames, "Name hash table size", "nnames");
452 SET_ADBSTATDESC(namescnt, "Names in hash table", "namescnt");
453
454 INSIST(i == dns_adbstats_max);
455
456 /* Initialize zone statistics */
457 for (i = 0; i < dns_zonestatscounter_max; i++) {
458 zonestats_desc[i] = NULL;
459 }
460 #if defined(EXTENDED_STATS)
461 for (i = 0; i < dns_zonestatscounter_max; i++) {
462 zonestats_xmldesc[i] = NULL;
463 }
464 #endif /* if defined(EXTENDED_STATS) */
465
466 #define SET_ZONESTATDESC(counterid, desc, xmldesc) \
467 do { \
468 set_desc(dns_zonestatscounter_##counterid, \
469 dns_zonestatscounter_max, desc, zonestats_desc, \
470 xmldesc, zonestats_xmldesc); \
471 zonestats_index[i++] = dns_zonestatscounter_##counterid; \
472 } while (0)
473
474 i = 0;
475 SET_ZONESTATDESC(notifyoutv4, "IPv4 notifies sent", "NotifyOutv4");
476 SET_ZONESTATDESC(notifyoutv6, "IPv6 notifies sent", "NotifyOutv6");
477 SET_ZONESTATDESC(notifyinv4, "IPv4 notifies received", "NotifyInv4");
478 SET_ZONESTATDESC(notifyinv6, "IPv6 notifies received", "NotifyInv6");
479 SET_ZONESTATDESC(notifyrej, "notifies rejected", "NotifyRej");
480 SET_ZONESTATDESC(soaoutv4, "IPv4 SOA queries sent", "SOAOutv4");
481 SET_ZONESTATDESC(soaoutv6, "IPv6 SOA queries sent", "SOAOutv6");
482 SET_ZONESTATDESC(axfrreqv4, "IPv4 AXFR requested", "AXFRReqv4");
483 SET_ZONESTATDESC(axfrreqv6, "IPv6 AXFR requested", "AXFRReqv6");
484 SET_ZONESTATDESC(ixfrreqv4, "IPv4 IXFR requested", "IXFRReqv4");
485 SET_ZONESTATDESC(ixfrreqv6, "IPv6 IXFR requested", "IXFRReqv6");
486 SET_ZONESTATDESC(xfrsuccess, "transfer requests succeeded",
487 "XfrSuccess");
488 SET_ZONESTATDESC(xfrfail, "transfer requests failed", "XfrFail");
489 INSIST(i == dns_zonestatscounter_max);
490
491 /* Initialize socket statistics */
492 for (i = 0; i < isc_sockstatscounter_max; i++) {
493 sockstats_desc[i] = NULL;
494 }
495 #if defined(EXTENDED_STATS)
496 for (i = 0; i < isc_sockstatscounter_max; i++) {
497 sockstats_xmldesc[i] = NULL;
498 }
499 #endif /* if defined(EXTENDED_STATS) */
500
501 #define SET_SOCKSTATDESC(counterid, desc, xmldesc) \
502 do { \
503 set_desc(isc_sockstatscounter_##counterid, \
504 isc_sockstatscounter_max, desc, sockstats_desc, \
505 xmldesc, sockstats_xmldesc); \
506 sockstats_index[i++] = isc_sockstatscounter_##counterid; \
507 } while (0)
508
509 i = 0;
510 SET_SOCKSTATDESC(udp4open, "UDP/IPv4 sockets opened", "UDP4Open");
511 SET_SOCKSTATDESC(udp6open, "UDP/IPv6 sockets opened", "UDP6Open");
512 SET_SOCKSTATDESC(tcp4open, "TCP/IPv4 sockets opened", "TCP4Open");
513 SET_SOCKSTATDESC(tcp6open, "TCP/IPv6 sockets opened", "TCP6Open");
514 SET_SOCKSTATDESC(unixopen, "Unix domain sockets opened", "UnixOpen");
515 SET_SOCKSTATDESC(rawopen, "Raw sockets opened", "RawOpen");
516 SET_SOCKSTATDESC(udp4openfail, "UDP/IPv4 socket open failures",
517 "UDP4OpenFail");
518 SET_SOCKSTATDESC(udp6openfail, "UDP/IPv6 socket open failures",
519 "UDP6OpenFail");
520 SET_SOCKSTATDESC(tcp4openfail, "TCP/IPv4 socket open failures",
521 "TCP4OpenFail");
522 SET_SOCKSTATDESC(tcp6openfail, "TCP/IPv6 socket open failures",
523 "TCP6OpenFail");
524 SET_SOCKSTATDESC(unixopenfail, "Unix domain socket open failures",
525 "UnixOpenFail");
526 SET_SOCKSTATDESC(rawopenfail, "Raw socket open failures",
527 "RawOpenFail");
528 SET_SOCKSTATDESC(udp4close, "UDP/IPv4 sockets closed", "UDP4Close");
529 SET_SOCKSTATDESC(udp6close, "UDP/IPv6 sockets closed", "UDP6Close");
530 SET_SOCKSTATDESC(tcp4close, "TCP/IPv4 sockets closed", "TCP4Close");
531 SET_SOCKSTATDESC(tcp6close, "TCP/IPv6 sockets closed", "TCP6Close");
532 SET_SOCKSTATDESC(unixclose, "Unix domain sockets closed", "UnixClose");
533 SET_SOCKSTATDESC(fdwatchclose, "FDwatch sockets closed",
534 "FDWatchClose");
535 SET_SOCKSTATDESC(rawclose, "Raw sockets closed", "RawClose");
536 SET_SOCKSTATDESC(udp4bindfail, "UDP/IPv4 socket bind failures",
537 "UDP4BindFail");
538 SET_SOCKSTATDESC(udp6bindfail, "UDP/IPv6 socket bind failures",
539 "UDP6BindFail");
540 SET_SOCKSTATDESC(tcp4bindfail, "TCP/IPv4 socket bind failures",
541 "TCP4BindFail");
542 SET_SOCKSTATDESC(tcp6bindfail, "TCP/IPv6 socket bind failures",
543 "TCP6BindFail");
544 SET_SOCKSTATDESC(unixbindfail, "Unix domain socket bind failures",
545 "UnixBindFail");
546 SET_SOCKSTATDESC(fdwatchbindfail, "FDwatch socket bind failures",
547 "FdwatchBindFail");
548 SET_SOCKSTATDESC(udp4connectfail, "UDP/IPv4 socket connect failures",
549 "UDP4ConnFail");
550 SET_SOCKSTATDESC(udp6connectfail, "UDP/IPv6 socket connect failures",
551 "UDP6ConnFail");
552 SET_SOCKSTATDESC(tcp4connectfail, "TCP/IPv4 socket connect failures",
553 "TCP4ConnFail");
554 SET_SOCKSTATDESC(tcp6connectfail, "TCP/IPv6 socket connect failures",
555 "TCP6ConnFail");
556 SET_SOCKSTATDESC(unixconnectfail, "Unix domain socket connect failures",
557 "UnixConnFail");
558 SET_SOCKSTATDESC(fdwatchconnectfail, "FDwatch socket connect failures",
559 "FDwatchConnFail");
560 SET_SOCKSTATDESC(udp4connect, "UDP/IPv4 connections established",
561 "UDP4Conn");
562 SET_SOCKSTATDESC(udp6connect, "UDP/IPv6 connections established",
563 "UDP6Conn");
564 SET_SOCKSTATDESC(tcp4connect, "TCP/IPv4 connections established",
565 "TCP4Conn");
566 SET_SOCKSTATDESC(tcp6connect, "TCP/IPv6 connections established",
567 "TCP6Conn");
568 SET_SOCKSTATDESC(unixconnect, "Unix domain connections established",
569 "UnixConn");
570 SET_SOCKSTATDESC(fdwatchconnect,
571 "FDwatch domain connections established",
572 "FDwatchConn");
573 SET_SOCKSTATDESC(tcp4acceptfail, "TCP/IPv4 connection accept failures",
574 "TCP4AcceptFail");
575 SET_SOCKSTATDESC(tcp6acceptfail, "TCP/IPv6 connection accept failures",
576 "TCP6AcceptFail");
577 SET_SOCKSTATDESC(unixacceptfail,
578 "Unix domain connection accept failures",
579 "UnixAcceptFail");
580 SET_SOCKSTATDESC(tcp4accept, "TCP/IPv4 connections accepted",
581 "TCP4Accept");
582 SET_SOCKSTATDESC(tcp6accept, "TCP/IPv6 connections accepted",
583 "TCP6Accept");
584 SET_SOCKSTATDESC(unixaccept, "Unix domain connections accepted",
585 "UnixAccept");
586 SET_SOCKSTATDESC(udp4sendfail, "UDP/IPv4 send errors", "UDP4SendErr");
587 SET_SOCKSTATDESC(udp6sendfail, "UDP/IPv6 send errors", "UDP6SendErr");
588 SET_SOCKSTATDESC(tcp4sendfail, "TCP/IPv4 send errors", "TCP4SendErr");
589 SET_SOCKSTATDESC(tcp6sendfail, "TCP/IPv6 send errors", "TCP6SendErr");
590 SET_SOCKSTATDESC(unixsendfail, "Unix domain send errors",
591 "UnixSendErr");
592 SET_SOCKSTATDESC(fdwatchsendfail, "FDwatch send errors",
593 "FDwatchSendErr");
594 SET_SOCKSTATDESC(udp4recvfail, "UDP/IPv4 recv errors", "UDP4RecvErr");
595 SET_SOCKSTATDESC(udp6recvfail, "UDP/IPv6 recv errors", "UDP6RecvErr");
596 SET_SOCKSTATDESC(tcp4recvfail, "TCP/IPv4 recv errors", "TCP4RecvErr");
597 SET_SOCKSTATDESC(tcp6recvfail, "TCP/IPv6 recv errors", "TCP6RecvErr");
598 SET_SOCKSTATDESC(unixrecvfail, "Unix domain recv errors",
599 "UnixRecvErr");
600 SET_SOCKSTATDESC(fdwatchrecvfail, "FDwatch recv errors",
601 "FDwatchRecvErr");
602 SET_SOCKSTATDESC(rawrecvfail, "Raw recv errors", "RawRecvErr");
603 SET_SOCKSTATDESC(udp4active, "UDP/IPv4 sockets active", "UDP4Active");
604 SET_SOCKSTATDESC(udp6active, "UDP/IPv6 sockets active", "UDP6Active");
605 SET_SOCKSTATDESC(tcp4active, "TCP/IPv4 sockets active", "TCP4Active");
606 SET_SOCKSTATDESC(tcp6active, "TCP/IPv6 sockets active", "TCP6Active");
607 SET_SOCKSTATDESC(unixactive, "Unix domain sockets active",
608 "UnixActive");
609 SET_SOCKSTATDESC(rawactive, "Raw sockets active", "RawActive");
610 INSIST(i == isc_sockstatscounter_max);
611
612 /* Initialize DNSSEC statistics */
613 for (i = 0; i < dns_dnssecstats_max; i++) {
614 dnssecstats_desc[i] = NULL;
615 }
616 #if defined(EXTENDED_STATS)
617 for (i = 0; i < dns_dnssecstats_max; i++) {
618 dnssecstats_xmldesc[i] = NULL;
619 }
620 #endif /* if defined(EXTENDED_STATS) */
621
622 #define SET_DNSSECSTATDESC(counterid, desc, xmldesc) \
623 do { \
624 set_desc(dns_dnssecstats_##counterid, dns_dnssecstats_max, \
625 desc, dnssecstats_desc, xmldesc, \
626 dnssecstats_xmldesc); \
627 dnssecstats_index[i++] = dns_dnssecstats_##counterid; \
628 } while (0)
629
630 i = 0;
631 SET_DNSSECSTATDESC(asis,
632 "dnssec validation success with signer "
633 "\"as is\"",
634 "DNSSECasis");
635 SET_DNSSECSTATDESC(downcase,
636 "dnssec validation success with signer "
637 "lower cased",
638 "DNSSECdowncase");
639 SET_DNSSECSTATDESC(wildcard, "dnssec validation of wildcard signature",
640 "DNSSECwild");
641 SET_DNSSECSTATDESC(fail, "dnssec validation failures", "DNSSECfail");
642 INSIST(i == dns_dnssecstats_max);
643
644 /* Initialize dnstap statistics */
645 for (i = 0; i < dns_dnstapcounter_max; i++) {
646 dnstapstats_desc[i] = NULL;
647 }
648 #if defined(EXTENDED_STATS)
649 for (i = 0; i < dns_dnstapcounter_max; i++) {
650 dnstapstats_xmldesc[i] = NULL;
651 }
652 #endif /* if defined(EXTENDED_STATS) */
653
654 #define SET_DNSTAPSTATDESC(counterid, desc, xmldesc) \
655 do { \
656 set_desc(dns_dnstapcounter_##counterid, dns_dnstapcounter_max, \
657 desc, dnstapstats_desc, xmldesc, \
658 dnstapstats_xmldesc); \
659 dnstapstats_index[i++] = dns_dnstapcounter_##counterid; \
660 } while (0)
661 i = 0;
662 SET_DNSTAPSTATDESC(success, "dnstap messages written", "DNSTAPsuccess");
663 SET_DNSTAPSTATDESC(drop, "dnstap messages dropped", "DNSTAPdropped");
664 INSIST(i == dns_dnstapcounter_max);
665
666 #define SET_GLUECACHESTATDESC(counterid, desc, xmldesc) \
667 do { \
668 set_desc(dns_gluecachestatscounter_##counterid, \
669 dns_gluecachestatscounter_max, desc, \
670 gluecachestats_desc, xmldesc, \
671 gluecachestats_xmldesc); \
672 gluecachestats_index[i++] = \
673 dns_gluecachestatscounter_##counterid; \
674 } while (0)
675 i = 0;
676 SET_GLUECACHESTATDESC(hits_present, "Hits for present glue (cached)",
677 "GLUECACHEhitspresent");
678 SET_GLUECACHESTATDESC(hits_absent,
679 "Hits for non-existent glue (cached)",
680 "GLUECACHEhitsabsent");
681 SET_GLUECACHESTATDESC(inserts_present,
682 "Miss-plus-cache-inserts for present glue",
683 "GLUECACHEinsertspresent");
684 SET_GLUECACHESTATDESC(inserts_absent,
685 "Miss-plus-cache-inserts for non-existent glue",
686 "GLUECACHEinsertsabsent");
687 INSIST(i == dns_gluecachestatscounter_max);
688
689 /* Sanity check */
690 for (i = 0; i < ns_statscounter_max; i++) {
691 INSIST(nsstats_desc[i] != NULL);
692 }
693 for (i = 0; i < dns_resstatscounter_max; i++) {
694 INSIST(resstats_desc[i] != NULL);
695 }
696 for (i = 0; i < dns_adbstats_max; i++) {
697 INSIST(adbstats_desc[i] != NULL);
698 }
699 for (i = 0; i < dns_zonestatscounter_max; i++) {
700 INSIST(zonestats_desc[i] != NULL);
701 }
702 for (i = 0; i < isc_sockstatscounter_max; i++) {
703 INSIST(sockstats_desc[i] != NULL);
704 }
705 for (i = 0; i < dns_dnssecstats_max; i++) {
706 INSIST(dnssecstats_desc[i] != NULL);
707 }
708 for (i = 0; i < dns_dnstapcounter_max; i++) {
709 INSIST(dnstapstats_desc[i] != NULL);
710 }
711 for (i = 0; i < dns_gluecachestatscounter_max; i++) {
712 INSIST(gluecachestats_desc[i] != NULL);
713 }
714 #if defined(EXTENDED_STATS)
715 for (i = 0; i < ns_statscounter_max; i++) {
716 INSIST(nsstats_xmldesc[i] != NULL);
717 }
718 for (i = 0; i < dns_resstatscounter_max; i++) {
719 INSIST(resstats_xmldesc[i] != NULL);
720 }
721 for (i = 0; i < dns_adbstats_max; i++) {
722 INSIST(adbstats_xmldesc[i] != NULL);
723 }
724 for (i = 0; i < dns_zonestatscounter_max; i++) {
725 INSIST(zonestats_xmldesc[i] != NULL);
726 }
727 for (i = 0; i < isc_sockstatscounter_max; i++) {
728 INSIST(sockstats_xmldesc[i] != NULL);
729 }
730 for (i = 0; i < dns_dnssecstats_max; i++) {
731 INSIST(dnssecstats_xmldesc[i] != NULL);
732 }
733 for (i = 0; i < dns_dnstapcounter_max; i++) {
734 INSIST(dnstapstats_xmldesc[i] != NULL);
735 }
736 for (i = 0; i < dns_gluecachestatscounter_max; i++) {
737 INSIST(gluecachestats_xmldesc[i] != NULL);
738 }
739 #endif /* if defined(EXTENDED_STATS) */
740
741 /* Initialize traffic size statistics */
742 for (i = 0; i < dns_sizecounter_in_max; i++) {
743 udpinsizestats_desc[i] = NULL;
744 tcpinsizestats_desc[i] = NULL;
745 #if defined(EXTENDED_STATS)
746 udpinsizestats_xmldesc[i] = NULL;
747 tcpinsizestats_xmldesc[i] = NULL;
748 #endif /* if defined(EXTENDED_STATS) */
749 }
750 for (i = 0; i < dns_sizecounter_out_max; i++) {
751 udpoutsizestats_desc[i] = NULL;
752 tcpoutsizestats_desc[i] = NULL;
753 #if defined(EXTENDED_STATS)
754 udpoutsizestats_xmldesc[i] = NULL;
755 tcpoutsizestats_xmldesc[i] = NULL;
756 #endif /* if defined(EXTENDED_STATS) */
757 }
758
759 #define SET_SIZESTATDESC(counterid, desc, xmldesc, inout) \
760 do { \
761 set_desc(dns_sizecounter_##inout##_##counterid, \
762 dns_sizecounter_##inout##_max, desc, \
763 udp##inout##sizestats_desc, xmldesc, \
764 udp##inout##sizestats_xmldesc); \
765 set_desc(dns_sizecounter_##inout##_##counterid, \
766 dns_sizecounter_##inout##_max, desc, \
767 tcp##inout##sizestats_desc, xmldesc, \
768 tcp##inout##sizestats_xmldesc); \
769 udp##inout##sizestats_index[i] = \
770 dns_sizecounter_##inout##_##counterid; \
771 tcp##inout##sizestats_index[i] = \
772 dns_sizecounter_##inout##_##counterid; \
773 i++; \
774 } while (0)
775
776 i = 0;
777 SET_SIZESTATDESC(0, "requests received 0-15 bytes", "0-15", in);
778 SET_SIZESTATDESC(16, "requests received 16-31 bytes", "16-31", in);
779 SET_SIZESTATDESC(32, "requests received 32-47 bytes", "32-47", in);
780 SET_SIZESTATDESC(48, "requests received 48-63 bytes", "48-63", in);
781 SET_SIZESTATDESC(64, "requests received 64-79 bytes", "64-79", in);
782 SET_SIZESTATDESC(80, "requests received 80-95 bytes", "80-95", in);
783 SET_SIZESTATDESC(96, "requests received 96-111 bytes", "96-111", in);
784 SET_SIZESTATDESC(112, "requests received 112-127 bytes", "112-127", in);
785 SET_SIZESTATDESC(128, "requests received 128-143 bytes", "128-143", in);
786 SET_SIZESTATDESC(144, "requests received 144-159 bytes", "144-159", in);
787 SET_SIZESTATDESC(160, "requests received 160-175 bytes", "160-175", in);
788 SET_SIZESTATDESC(176, "requests received 176-191 bytes", "176-191", in);
789 SET_SIZESTATDESC(192, "requests received 192-207 bytes", "192-207", in);
790 SET_SIZESTATDESC(208, "requests received 208-223 bytes", "208-223", in);
791 SET_SIZESTATDESC(224, "requests received 224-239 bytes", "224-239", in);
792 SET_SIZESTATDESC(240, "requests received 240-255 bytes", "240-255", in);
793 SET_SIZESTATDESC(256, "requests received 256-271 bytes", "256-271", in);
794 SET_SIZESTATDESC(272, "requests received 272-287 bytes", "272-287", in);
795 SET_SIZESTATDESC(288, "requests received 288+ bytes", "288+", in);
796 INSIST(i == dns_sizecounter_in_max);
797
798 i = 0;
799 SET_SIZESTATDESC(0, "responses sent 0-15 bytes", "0-15", out);
800 SET_SIZESTATDESC(16, "responses sent 16-31 bytes", "16-31", out);
801 SET_SIZESTATDESC(32, "responses sent 32-47 bytes", "32-47", out);
802 SET_SIZESTATDESC(48, "responses sent 48-63 bytes", "48-63", out);
803 SET_SIZESTATDESC(64, "responses sent 64-79 bytes", "64-79", out);
804 SET_SIZESTATDESC(80, "responses sent 80-95 bytes", "80-95", out);
805 SET_SIZESTATDESC(96, "responses sent 96-111 bytes", "96-111", out);
806 SET_SIZESTATDESC(112, "responses sent 112-127 bytes", "112-127", out);
807 SET_SIZESTATDESC(128, "responses sent 128-143 bytes", "128-143", out);
808 SET_SIZESTATDESC(144, "responses sent 144-159 bytes", "144-159", out);
809 SET_SIZESTATDESC(160, "responses sent 160-175 bytes", "160-175", out);
810 SET_SIZESTATDESC(176, "responses sent 176-191 bytes", "176-191", out);
811 SET_SIZESTATDESC(192, "responses sent 192-207 bytes", "192-207", out);
812 SET_SIZESTATDESC(208, "responses sent 208-223 bytes", "208-223", out);
813 SET_SIZESTATDESC(224, "responses sent 224-239 bytes", "224-239", out);
814 SET_SIZESTATDESC(240, "responses sent 240-255 bytes", "240-255", out);
815 SET_SIZESTATDESC(256, "responses sent 256-271 bytes", "256-271", out);
816 SET_SIZESTATDESC(272, "responses sent 272-287 bytes", "272-287", out);
817 SET_SIZESTATDESC(288, "responses sent 288-303 bytes", "288-303", out);
818 SET_SIZESTATDESC(304, "responses sent 304-319 bytes", "304-319", out);
819 SET_SIZESTATDESC(320, "responses sent 320-335 bytes", "320-335", out);
820 SET_SIZESTATDESC(336, "responses sent 336-351 bytes", "336-351", out);
821 SET_SIZESTATDESC(352, "responses sent 352-367 bytes", "352-367", out);
822 SET_SIZESTATDESC(368, "responses sent 368-383 bytes", "368-383", out);
823 SET_SIZESTATDESC(384, "responses sent 384-399 bytes", "384-399", out);
824 SET_SIZESTATDESC(400, "responses sent 400-415 bytes", "400-415", out);
825 SET_SIZESTATDESC(416, "responses sent 416-431 bytes", "416-431", out);
826 SET_SIZESTATDESC(432, "responses sent 432-447 bytes", "432-447", out);
827 SET_SIZESTATDESC(448, "responses sent 448-463 bytes", "448-463", out);
828 SET_SIZESTATDESC(464, "responses sent 464-479 bytes", "464-479", out);
829 SET_SIZESTATDESC(480, "responses sent 480-495 bytes", "480-495", out);
830 SET_SIZESTATDESC(496, "responses sent 496-511 bytes", "496-511", out);
831 SET_SIZESTATDESC(512, "responses sent 512-527 bytes", "512-527", out);
832 SET_SIZESTATDESC(528, "responses sent 528-543 bytes", "528-543", out);
833 SET_SIZESTATDESC(544, "responses sent 544-559 bytes", "544-559", out);
834 SET_SIZESTATDESC(560, "responses sent 560-575 bytes", "560-575", out);
835 SET_SIZESTATDESC(576, "responses sent 576-591 bytes", "576-591", out);
836 SET_SIZESTATDESC(592, "responses sent 592-607 bytes", "592-607", out);
837 SET_SIZESTATDESC(608, "responses sent 608-623 bytes", "608-623", out);
838 SET_SIZESTATDESC(624, "responses sent 624-639 bytes", "624-639", out);
839 SET_SIZESTATDESC(640, "responses sent 640-655 bytes", "640-655", out);
840 SET_SIZESTATDESC(656, "responses sent 656-671 bytes", "656-671", out);
841 SET_SIZESTATDESC(672, "responses sent 672-687 bytes", "672-687", out);
842 SET_SIZESTATDESC(688, "responses sent 688-703 bytes", "688-703", out);
843 SET_SIZESTATDESC(704, "responses sent 704-719 bytes", "704-719", out);
844 SET_SIZESTATDESC(720, "responses sent 720-735 bytes", "720-735", out);
845 SET_SIZESTATDESC(736, "responses sent 736-751 bytes", "736-751", out);
846 SET_SIZESTATDESC(752, "responses sent 752-767 bytes", "752-767", out);
847 SET_SIZESTATDESC(768, "responses sent 768-783 bytes", "768-783", out);
848 SET_SIZESTATDESC(784, "responses sent 784-799 bytes", "784-799", out);
849 SET_SIZESTATDESC(800, "responses sent 800-815 bytes", "800-815", out);
850 SET_SIZESTATDESC(816, "responses sent 816-831 bytes", "816-831", out);
851 SET_SIZESTATDESC(832, "responses sent 832-847 bytes", "832-847", out);
852 SET_SIZESTATDESC(848, "responses sent 848-863 bytes", "848-863", out);
853 SET_SIZESTATDESC(864, "responses sent 864-879 bytes", "864-879", out);
854 SET_SIZESTATDESC(880, "responses sent 880-895 bytes", "880-895", out);
855 SET_SIZESTATDESC(896, "responses sent 896-911 bytes", "896-911", out);
856 SET_SIZESTATDESC(912, "responses sent 912-927 bytes", "912-927", out);
857 SET_SIZESTATDESC(928, "responses sent 928-943 bytes", "928-943", out);
858 SET_SIZESTATDESC(944, "responses sent 944-959 bytes", "944-959", out);
859 SET_SIZESTATDESC(960, "responses sent 960-975 bytes", "960-975", out);
860 SET_SIZESTATDESC(976, "responses sent 976-991 bytes", "976-991", out);
861 SET_SIZESTATDESC(992, "responses sent 992-1007 bytes", "992-1007", out);
862 SET_SIZESTATDESC(1008, "responses sent 1008-1023 bytes", "1008-1023",
863 out);
864 SET_SIZESTATDESC(1024, "responses sent 1024-1039 bytes", "1024-1039",
865 out);
866 SET_SIZESTATDESC(1040, "responses sent 1040-1055 bytes", "1040-1055",
867 out);
868 SET_SIZESTATDESC(1056, "responses sent 1056-1071 bytes", "1056-1071",
869 out);
870 SET_SIZESTATDESC(1072, "responses sent 1072-1087 bytes", "1072-1087",
871 out);
872 SET_SIZESTATDESC(1088, "responses sent 1088-1103 bytes", "1088-1103",
873 out);
874 SET_SIZESTATDESC(1104, "responses sent 1104-1119 bytes", "1104-1119",
875 out);
876 SET_SIZESTATDESC(1120, "responses sent 1120-1135 bytes", "1120-1135",
877 out);
878 SET_SIZESTATDESC(1136, "responses sent 1136-1151 bytes", "1136-1151",
879 out);
880 SET_SIZESTATDESC(1152, "responses sent 1152-1167 bytes", "1152-1167",
881 out);
882 SET_SIZESTATDESC(1168, "responses sent 1168-1183 bytes", "1168-1183",
883 out);
884 SET_SIZESTATDESC(1184, "responses sent 1184-1199 bytes", "1184-1199",
885 out);
886 SET_SIZESTATDESC(1200, "responses sent 1200-1215 bytes", "1200-1215",
887 out);
888 SET_SIZESTATDESC(1216, "responses sent 1216-1231 bytes", "1216-1231",
889 out);
890 SET_SIZESTATDESC(1232, "responses sent 1232-1247 bytes", "1232-1247",
891 out);
892 SET_SIZESTATDESC(1248, "responses sent 1248-1263 bytes", "1248-1263",
893 out);
894 SET_SIZESTATDESC(1264, "responses sent 1264-1279 bytes", "1264-1279",
895 out);
896 SET_SIZESTATDESC(1280, "responses sent 1280-1295 bytes", "1280-1295",
897 out);
898 SET_SIZESTATDESC(1296, "responses sent 1296-1311 bytes", "1296-1311",
899 out);
900 SET_SIZESTATDESC(1312, "responses sent 1312-1327 bytes", "1312-1327",
901 out);
902 SET_SIZESTATDESC(1328, "responses sent 1328-1343 bytes", "1328-1343",
903 out);
904 SET_SIZESTATDESC(1344, "responses sent 1344-1359 bytes", "1344-1359",
905 out);
906 SET_SIZESTATDESC(1360, "responses sent 1360-1375 bytes", "1360-1375",
907 out);
908 SET_SIZESTATDESC(1376, "responses sent 1376-1391 bytes", "1376-1391",
909 out);
910 SET_SIZESTATDESC(1392, "responses sent 1392-1407 bytes", "1392-1407",
911 out);
912 SET_SIZESTATDESC(1408, "responses sent 1408-1423 bytes", "1408-1423",
913 out);
914 SET_SIZESTATDESC(1424, "responses sent 1424-1439 bytes", "1424-1439",
915 out);
916 SET_SIZESTATDESC(1440, "responses sent 1440-1455 bytes", "1440-1455",
917 out);
918 SET_SIZESTATDESC(1456, "responses sent 1456-1471 bytes", "1456-1471",
919 out);
920 SET_SIZESTATDESC(1472, "responses sent 1472-1487 bytes", "1472-1487",
921 out);
922 SET_SIZESTATDESC(1488, "responses sent 1488-1503 bytes", "1488-1503",
923 out);
924 SET_SIZESTATDESC(1504, "responses sent 1504-1519 bytes", "1504-1519",
925 out);
926 SET_SIZESTATDESC(1520, "responses sent 1520-1535 bytes", "1520-1535",
927 out);
928 SET_SIZESTATDESC(1536, "responses sent 1536-1551 bytes", "1536-1551",
929 out);
930 SET_SIZESTATDESC(1552, "responses sent 1552-1567 bytes", "1552-1567",
931 out);
932 SET_SIZESTATDESC(1568, "responses sent 1568-1583 bytes", "1568-1583",
933 out);
934 SET_SIZESTATDESC(1584, "responses sent 1584-1599 bytes", "1584-1599",
935 out);
936 SET_SIZESTATDESC(1600, "responses sent 1600-1615 bytes", "1600-1615",
937 out);
938 SET_SIZESTATDESC(1616, "responses sent 1616-1631 bytes", "1616-1631",
939 out);
940 SET_SIZESTATDESC(1632, "responses sent 1632-1647 bytes", "1632-1647",
941 out);
942 SET_SIZESTATDESC(1648, "responses sent 1648-1663 bytes", "1648-1663",
943 out);
944 SET_SIZESTATDESC(1664, "responses sent 1664-1679 bytes", "1664-1679",
945 out);
946 SET_SIZESTATDESC(1680, "responses sent 1680-1695 bytes", "1680-1695",
947 out);
948 SET_SIZESTATDESC(1696, "responses sent 1696-1711 bytes", "1696-1711",
949 out);
950 SET_SIZESTATDESC(1712, "responses sent 1712-1727 bytes", "1712-1727",
951 out);
952 SET_SIZESTATDESC(1728, "responses sent 1728-1743 bytes", "1728-1743",
953 out);
954 SET_SIZESTATDESC(1744, "responses sent 1744-1759 bytes", "1744-1759",
955 out);
956 SET_SIZESTATDESC(1760, "responses sent 1760-1775 bytes", "1760-1775",
957 out);
958 SET_SIZESTATDESC(1776, "responses sent 1776-1791 bytes", "1776-1791",
959 out);
960 SET_SIZESTATDESC(1792, "responses sent 1792-1807 bytes", "1792-1807",
961 out);
962 SET_SIZESTATDESC(1808, "responses sent 1808-1823 bytes", "1808-1823",
963 out);
964 SET_SIZESTATDESC(1824, "responses sent 1824-1839 bytes", "1824-1839",
965 out);
966 SET_SIZESTATDESC(1840, "responses sent 1840-1855 bytes", "1840-1855",
967 out);
968 SET_SIZESTATDESC(1856, "responses sent 1856-1871 bytes", "1856-1871",
969 out);
970 SET_SIZESTATDESC(1872, "responses sent 1872-1887 bytes", "1872-1887",
971 out);
972 SET_SIZESTATDESC(1888, "responses sent 1888-1903 bytes", "1888-1903",
973 out);
974 SET_SIZESTATDESC(1904, "responses sent 1904-1919 bytes", "1904-1919",
975 out);
976 SET_SIZESTATDESC(1920, "responses sent 1920-1935 bytes", "1920-1935",
977 out);
978 SET_SIZESTATDESC(1936, "responses sent 1936-1951 bytes", "1936-1951",
979 out);
980 SET_SIZESTATDESC(1952, "responses sent 1952-1967 bytes", "1952-1967",
981 out);
982 SET_SIZESTATDESC(1968, "responses sent 1968-1983 bytes", "1968-1983",
983 out);
984 SET_SIZESTATDESC(1984, "responses sent 1984-1999 bytes", "1984-1999",
985 out);
986 SET_SIZESTATDESC(2000, "responses sent 2000-2015 bytes", "2000-2015",
987 out);
988 SET_SIZESTATDESC(2016, "responses sent 2016-2031 bytes", "2016-2031",
989 out);
990 SET_SIZESTATDESC(2032, "responses sent 2032-2047 bytes", "2032-2047",
991 out);
992 SET_SIZESTATDESC(2048, "responses sent 2048-2063 bytes", "2048-2063",
993 out);
994 SET_SIZESTATDESC(2064, "responses sent 2064-2079 bytes", "2064-2079",
995 out);
996 SET_SIZESTATDESC(2080, "responses sent 2080-2095 bytes", "2080-2095",
997 out);
998 SET_SIZESTATDESC(2096, "responses sent 2096-2111 bytes", "2096-2111",
999 out);
1000 SET_SIZESTATDESC(2112, "responses sent 2112-2127 bytes", "2112-2127",
1001 out);
1002 SET_SIZESTATDESC(2128, "responses sent 2128-2143 bytes", "2128-2143",
1003 out);
1004 SET_SIZESTATDESC(2144, "responses sent 2144-2159 bytes", "2144-2159",
1005 out);
1006 SET_SIZESTATDESC(2160, "responses sent 2160-2175 bytes", "2160-2175",
1007 out);
1008 SET_SIZESTATDESC(2176, "responses sent 2176-2191 bytes", "2176-2191",
1009 out);
1010 SET_SIZESTATDESC(2192, "responses sent 2192-2207 bytes", "2192-2207",
1011 out);
1012 SET_SIZESTATDESC(2208, "responses sent 2208-2223 bytes", "2208-2223",
1013 out);
1014 SET_SIZESTATDESC(2224, "responses sent 2224-2239 bytes", "2224-2239",
1015 out);
1016 SET_SIZESTATDESC(2240, "responses sent 2240-2255 bytes", "2240-2255",
1017 out);
1018 SET_SIZESTATDESC(2256, "responses sent 2256-2271 bytes", "2256-2271",
1019 out);
1020 SET_SIZESTATDESC(2272, "responses sent 2272-2287 bytes", "2272-2287",
1021 out);
1022 SET_SIZESTATDESC(2288, "responses sent 2288-2303 bytes", "2288-2303",
1023 out);
1024 SET_SIZESTATDESC(2304, "responses sent 2304-2319 bytes", "2304-2319",
1025 out);
1026 SET_SIZESTATDESC(2320, "responses sent 2320-2335 bytes", "2320-2335",
1027 out);
1028 SET_SIZESTATDESC(2336, "responses sent 2336-2351 bytes", "2336-2351",
1029 out);
1030 SET_SIZESTATDESC(2352, "responses sent 2352-2367 bytes", "2352-2367",
1031 out);
1032 SET_SIZESTATDESC(2368, "responses sent 2368-2383 bytes", "2368-2383",
1033 out);
1034 SET_SIZESTATDESC(2384, "responses sent 2384-2399 bytes", "2384-2399",
1035 out);
1036 SET_SIZESTATDESC(2400, "responses sent 2400-2415 bytes", "2400-2415",
1037 out);
1038 SET_SIZESTATDESC(2416, "responses sent 2416-2431 bytes", "2416-2431",
1039 out);
1040 SET_SIZESTATDESC(2432, "responses sent 2432-2447 bytes", "2432-2447",
1041 out);
1042 SET_SIZESTATDESC(2448, "responses sent 2448-2463 bytes", "2448-2463",
1043 out);
1044 SET_SIZESTATDESC(2464, "responses sent 2464-2479 bytes", "2464-2479",
1045 out);
1046 SET_SIZESTATDESC(2480, "responses sent 2480-2495 bytes", "2480-2495",
1047 out);
1048 SET_SIZESTATDESC(2496, "responses sent 2496-2511 bytes", "2496-2511",
1049 out);
1050 SET_SIZESTATDESC(2512, "responses sent 2512-2527 bytes", "2512-2527",
1051 out);
1052 SET_SIZESTATDESC(2528, "responses sent 2528-2543 bytes", "2528-2543",
1053 out);
1054 SET_SIZESTATDESC(2544, "responses sent 2544-2559 bytes", "2544-2559",
1055 out);
1056 SET_SIZESTATDESC(2560, "responses sent 2560-2575 bytes", "2560-2575",
1057 out);
1058 SET_SIZESTATDESC(2576, "responses sent 2576-2591 bytes", "2576-2591",
1059 out);
1060 SET_SIZESTATDESC(2592, "responses sent 2592-2607 bytes", "2592-2607",
1061 out);
1062 SET_SIZESTATDESC(2608, "responses sent 2608-2623 bytes", "2608-2623",
1063 out);
1064 SET_SIZESTATDESC(2624, "responses sent 2624-2639 bytes", "2624-2639",
1065 out);
1066 SET_SIZESTATDESC(2640, "responses sent 2640-2655 bytes", "2640-2655",
1067 out);
1068 SET_SIZESTATDESC(2656, "responses sent 2656-2671 bytes", "2656-2671",
1069 out);
1070 SET_SIZESTATDESC(2672, "responses sent 2672-2687 bytes", "2672-2687",
1071 out);
1072 SET_SIZESTATDESC(2688, "responses sent 2688-2703 bytes", "2688-2703",
1073 out);
1074 SET_SIZESTATDESC(2704, "responses sent 2704-2719 bytes", "2704-2719",
1075 out);
1076 SET_SIZESTATDESC(2720, "responses sent 2720-2735 bytes", "2720-2735",
1077 out);
1078 SET_SIZESTATDESC(2736, "responses sent 2736-2751 bytes", "2736-2751",
1079 out);
1080 SET_SIZESTATDESC(2752, "responses sent 2752-2767 bytes", "2752-2767",
1081 out);
1082 SET_SIZESTATDESC(2768, "responses sent 2768-2783 bytes", "2768-2783",
1083 out);
1084 SET_SIZESTATDESC(2784, "responses sent 2784-2799 bytes", "2784-2799",
1085 out);
1086 SET_SIZESTATDESC(2800, "responses sent 2800-2815 bytes", "2800-2815",
1087 out);
1088 SET_SIZESTATDESC(2816, "responses sent 2816-2831 bytes", "2816-2831",
1089 out);
1090 SET_SIZESTATDESC(2832, "responses sent 2832-2847 bytes", "2832-2847",
1091 out);
1092 SET_SIZESTATDESC(2848, "responses sent 2848-2863 bytes", "2848-2863",
1093 out);
1094 SET_SIZESTATDESC(2864, "responses sent 2864-2879 bytes", "2864-2879",
1095 out);
1096 SET_SIZESTATDESC(2880, "responses sent 2880-2895 bytes", "2880-2895",
1097 out);
1098 SET_SIZESTATDESC(2896, "responses sent 2896-2911 bytes", "2896-2911",
1099 out);
1100 SET_SIZESTATDESC(2912, "responses sent 2912-2927 bytes", "2912-2927",
1101 out);
1102 SET_SIZESTATDESC(2928, "responses sent 2928-2943 bytes", "2928-2943",
1103 out);
1104 SET_SIZESTATDESC(2944, "responses sent 2944-2959 bytes", "2944-2959",
1105 out);
1106 SET_SIZESTATDESC(2960, "responses sent 2960-2975 bytes", "2960-2975",
1107 out);
1108 SET_SIZESTATDESC(2976, "responses sent 2976-2991 bytes", "2976-2991",
1109 out);
1110 SET_SIZESTATDESC(2992, "responses sent 2992-3007 bytes", "2992-3007",
1111 out);
1112 SET_SIZESTATDESC(3008, "responses sent 3008-3023 bytes", "3008-3023",
1113 out);
1114 SET_SIZESTATDESC(3024, "responses sent 3024-3039 bytes", "3024-3039",
1115 out);
1116 SET_SIZESTATDESC(3040, "responses sent 3040-3055 bytes", "3040-3055",
1117 out);
1118 SET_SIZESTATDESC(3056, "responses sent 3056-3071 bytes", "3056-3071",
1119 out);
1120 SET_SIZESTATDESC(3072, "responses sent 3072-3087 bytes", "3072-3087",
1121 out);
1122 SET_SIZESTATDESC(3088, "responses sent 3088-3103 bytes", "3088-3103",
1123 out);
1124 SET_SIZESTATDESC(3104, "responses sent 3104-3119 bytes", "3104-3119",
1125 out);
1126 SET_SIZESTATDESC(3120, "responses sent 3120-3135 bytes", "3120-3135",
1127 out);
1128 SET_SIZESTATDESC(3136, "responses sent 3136-3151 bytes", "3136-3151",
1129 out);
1130 SET_SIZESTATDESC(3152, "responses sent 3152-3167 bytes", "3152-3167",
1131 out);
1132 SET_SIZESTATDESC(3168, "responses sent 3168-3183 bytes", "3168-3183",
1133 out);
1134 SET_SIZESTATDESC(3184, "responses sent 3184-3199 bytes", "3184-3199",
1135 out);
1136 SET_SIZESTATDESC(3200, "responses sent 3200-3215 bytes", "3200-3215",
1137 out);
1138 SET_SIZESTATDESC(3216, "responses sent 3216-3231 bytes", "3216-3231",
1139 out);
1140 SET_SIZESTATDESC(3232, "responses sent 3232-3247 bytes", "3232-3247",
1141 out);
1142 SET_SIZESTATDESC(3248, "responses sent 3248-3263 bytes", "3248-3263",
1143 out);
1144 SET_SIZESTATDESC(3264, "responses sent 3264-3279 bytes", "3264-3279",
1145 out);
1146 SET_SIZESTATDESC(3280, "responses sent 3280-3295 bytes", "3280-3295",
1147 out);
1148 SET_SIZESTATDESC(3296, "responses sent 3296-3311 bytes", "3296-3311",
1149 out);
1150 SET_SIZESTATDESC(3312, "responses sent 3312-3327 bytes", "3312-3327",
1151 out);
1152 SET_SIZESTATDESC(3328, "responses sent 3328-3343 bytes", "3328-3343",
1153 out);
1154 SET_SIZESTATDESC(3344, "responses sent 3344-3359 bytes", "3344-3359",
1155 out);
1156 SET_SIZESTATDESC(3360, "responses sent 3360-3375 bytes", "3360-3375",
1157 out);
1158 SET_SIZESTATDESC(3376, "responses sent 3376-3391 bytes", "3376-3391",
1159 out);
1160 SET_SIZESTATDESC(3392, "responses sent 3392-3407 bytes", "3392-3407",
1161 out);
1162 SET_SIZESTATDESC(3408, "responses sent 3408-3423 bytes", "3408-3423",
1163 out);
1164 SET_SIZESTATDESC(3424, "responses sent 3424-3439 bytes", "3424-3439",
1165 out);
1166 SET_SIZESTATDESC(3440, "responses sent 3440-3455 bytes", "3440-3455",
1167 out);
1168 SET_SIZESTATDESC(3456, "responses sent 3456-3471 bytes", "3456-3471",
1169 out);
1170 SET_SIZESTATDESC(3472, "responses sent 3472-3487 bytes", "3472-3487",
1171 out);
1172 SET_SIZESTATDESC(3488, "responses sent 3488-3503 bytes", "3488-3503",
1173 out);
1174 SET_SIZESTATDESC(3504, "responses sent 3504-3519 bytes", "3504-3519",
1175 out);
1176 SET_SIZESTATDESC(3520, "responses sent 3520-3535 bytes", "3520-3535",
1177 out);
1178 SET_SIZESTATDESC(3536, "responses sent 3536-3551 bytes", "3536-3551",
1179 out);
1180 SET_SIZESTATDESC(3552, "responses sent 3552-3567 bytes", "3552-3567",
1181 out);
1182 SET_SIZESTATDESC(3568, "responses sent 3568-3583 bytes", "3568-3583",
1183 out);
1184 SET_SIZESTATDESC(3584, "responses sent 3584-3599 bytes", "3584-3599",
1185 out);
1186 SET_SIZESTATDESC(3600, "responses sent 3600-3615 bytes", "3600-3615",
1187 out);
1188 SET_SIZESTATDESC(3616, "responses sent 3616-3631 bytes", "3616-3631",
1189 out);
1190 SET_SIZESTATDESC(3632, "responses sent 3632-3647 bytes", "3632-3647",
1191 out);
1192 SET_SIZESTATDESC(3648, "responses sent 3648-3663 bytes", "3648-3663",
1193 out);
1194 SET_SIZESTATDESC(3664, "responses sent 3664-3679 bytes", "3664-3679",
1195 out);
1196 SET_SIZESTATDESC(3680, "responses sent 3680-3695 bytes", "3680-3695",
1197 out);
1198 SET_SIZESTATDESC(3696, "responses sent 3696-3711 bytes", "3696-3711",
1199 out);
1200 SET_SIZESTATDESC(3712, "responses sent 3712-3727 bytes", "3712-3727",
1201 out);
1202 SET_SIZESTATDESC(3728, "responses sent 3728-3743 bytes", "3728-3743",
1203 out);
1204 SET_SIZESTATDESC(3744, "responses sent 3744-3759 bytes", "3744-3759",
1205 out);
1206 SET_SIZESTATDESC(3760, "responses sent 3760-3775 bytes", "3760-3775",
1207 out);
1208 SET_SIZESTATDESC(3776, "responses sent 3776-3791 bytes", "3776-3791",
1209 out);
1210 SET_SIZESTATDESC(3792, "responses sent 3792-3807 bytes", "3792-3807",
1211 out);
1212 SET_SIZESTATDESC(3808, "responses sent 3808-3823 bytes", "3808-3823",
1213 out);
1214 SET_SIZESTATDESC(3824, "responses sent 3824-3839 bytes", "3824-3839",
1215 out);
1216 SET_SIZESTATDESC(3840, "responses sent 3840-3855 bytes", "3840-3855",
1217 out);
1218 SET_SIZESTATDESC(3856, "responses sent 3856-3871 bytes", "3856-3871",
1219 out);
1220 SET_SIZESTATDESC(3872, "responses sent 3872-3887 bytes", "3872-3887",
1221 out);
1222 SET_SIZESTATDESC(3888, "responses sent 3888-3903 bytes", "3888-3903",
1223 out);
1224 SET_SIZESTATDESC(3904, "responses sent 3904-3919 bytes", "3904-3919",
1225 out);
1226 SET_SIZESTATDESC(3920, "responses sent 3920-3935 bytes", "3920-3935",
1227 out);
1228 SET_SIZESTATDESC(3936, "responses sent 3936-3951 bytes", "3936-3951",
1229 out);
1230 SET_SIZESTATDESC(3952, "responses sent 3952-3967 bytes", "3952-3967",
1231 out);
1232 SET_SIZESTATDESC(3968, "responses sent 3968-3983 bytes", "3968-3983",
1233 out);
1234 SET_SIZESTATDESC(3984, "responses sent 3984-3999 bytes", "3984-3999",
1235 out);
1236 SET_SIZESTATDESC(4000, "responses sent 4000-4015 bytes", "4000-4015",
1237 out);
1238 SET_SIZESTATDESC(4016, "responses sent 4016-4031 bytes", "4016-4031",
1239 out);
1240 SET_SIZESTATDESC(4032, "responses sent 4032-4047 bytes", "4032-4047",
1241 out);
1242 SET_SIZESTATDESC(4048, "responses sent 4048-4063 bytes", "4048-4063",
1243 out);
1244 SET_SIZESTATDESC(4064, "responses sent 4064-4079 bytes", "4064-4079",
1245 out);
1246 SET_SIZESTATDESC(4080, "responses sent 4080-4095 bytes", "4080-4095",
1247 out);
1248 SET_SIZESTATDESC(4096, "responses sent 4096+ bytes", "4096+", out);
1249 INSIST(i == dns_sizecounter_out_max);
1250
1251 /* Sanity check */
1252 for (i = 0; i < ns_statscounter_max; i++) {
1253 INSIST(nsstats_desc[i] != NULL);
1254 }
1255 for (i = 0; i < dns_resstatscounter_max; i++) {
1256 INSIST(resstats_desc[i] != NULL);
1257 }
1258 for (i = 0; i < dns_adbstats_max; i++) {
1259 INSIST(adbstats_desc[i] != NULL);
1260 }
1261 for (i = 0; i < dns_zonestatscounter_max; i++) {
1262 INSIST(zonestats_desc[i] != NULL);
1263 }
1264 for (i = 0; i < isc_sockstatscounter_max; i++) {
1265 INSIST(sockstats_desc[i] != NULL);
1266 }
1267 for (i = 0; i < dns_dnssecstats_max; i++) {
1268 INSIST(dnssecstats_desc[i] != NULL);
1269 }
1270 for (i = 0; i < dns_sizecounter_in_max; i++) {
1271 INSIST(udpinsizestats_desc[i] != NULL);
1272 INSIST(tcpinsizestats_desc[i] != NULL);
1273 }
1274 for (i = 0; i < dns_sizecounter_out_max; i++) {
1275 INSIST(udpoutsizestats_desc[i] != NULL);
1276 INSIST(tcpoutsizestats_desc[i] != NULL);
1277 }
1278 #if defined(EXTENDED_STATS)
1279 for (i = 0; i < ns_statscounter_max; i++) {
1280 INSIST(nsstats_xmldesc[i] != NULL);
1281 }
1282 for (i = 0; i < dns_resstatscounter_max; i++) {
1283 INSIST(resstats_xmldesc[i] != NULL);
1284 }
1285 for (i = 0; i < dns_adbstats_max; i++) {
1286 INSIST(adbstats_xmldesc[i] != NULL);
1287 }
1288 for (i = 0; i < dns_zonestatscounter_max; i++) {
1289 INSIST(zonestats_xmldesc[i] != NULL);
1290 }
1291 for (i = 0; i < isc_sockstatscounter_max; i++) {
1292 INSIST(sockstats_xmldesc[i] != NULL);
1293 }
1294 for (i = 0; i < dns_dnssecstats_max; i++) {
1295 INSIST(dnssecstats_xmldesc[i] != NULL);
1296 }
1297 for (i = 0; i < dns_sizecounter_in_max; i++) {
1298 INSIST(udpinsizestats_xmldesc[i] != NULL);
1299 INSIST(tcpinsizestats_xmldesc[i] != NULL);
1300 }
1301 for (i = 0; i < dns_sizecounter_out_max; i++) {
1302 INSIST(udpoutsizestats_xmldesc[i] != NULL);
1303 INSIST(tcpoutsizestats_xmldesc[i] != NULL);
1304 }
1305 #endif /* if defined(EXTENDED_STATS) */
1306 }
1307
1308 /*%
1309 * Dump callback functions.
1310 */
1311 static void
generalstat_dump(isc_statscounter_t counter,uint64_t val,void * arg)1312 generalstat_dump(isc_statscounter_t counter, uint64_t val, void *arg) {
1313 stats_dumparg_t *dumparg = arg;
1314
1315 REQUIRE(counter < dumparg->ncounters);
1316 dumparg->countervalues[counter] = val;
1317 }
1318
1319 static isc_result_t
dump_counters(isc_stats_t * stats,isc_statsformat_t type,void * arg,const char * category,const char ** desc,int ncounters,int * indices,uint64_t * values,int options)1320 dump_counters(isc_stats_t *stats, isc_statsformat_t type, void *arg,
1321 const char *category, const char **desc, int ncounters,
1322 int *indices, uint64_t *values, int options) {
1323 int i, idx;
1324 uint64_t value;
1325 stats_dumparg_t dumparg;
1326 FILE *fp;
1327 #ifdef HAVE_LIBXML2
1328 void *writer;
1329 int xmlrc;
1330 #endif /* ifdef HAVE_LIBXML2 */
1331 #ifdef HAVE_JSON_C
1332 json_object *job, *cat, *counter;
1333 #endif /* ifdef HAVE_JSON_C */
1334
1335 #if !defined(EXTENDED_STATS)
1336 UNUSED(category);
1337 #endif /* if !defined(EXTENDED_STATS) */
1338
1339 dumparg.type = type;
1340 dumparg.ncounters = ncounters;
1341 dumparg.counterindices = indices;
1342 dumparg.countervalues = values;
1343
1344 memset(values, 0, sizeof(values[0]) * ncounters);
1345 isc_stats_dump(stats, generalstat_dump, &dumparg, options);
1346
1347 #ifdef HAVE_JSON_C
1348 cat = job = (json_object *)arg;
1349 if (ncounters > 0 && type == isc_statsformat_json) {
1350 if (category != NULL) {
1351 cat = json_object_new_object();
1352 if (cat == NULL) {
1353 return (ISC_R_NOMEMORY);
1354 }
1355 json_object_object_add(job, category, cat);
1356 }
1357 }
1358 #endif /* ifdef HAVE_JSON_C */
1359
1360 for (i = 0; i < ncounters; i++) {
1361 idx = indices[i];
1362 value = values[idx];
1363
1364 if (value == 0 && (options & ISC_STATSDUMP_VERBOSE) == 0) {
1365 continue;
1366 }
1367
1368 switch (dumparg.type) {
1369 case isc_statsformat_file:
1370 fp = arg;
1371 fprintf(fp, "%20" PRIu64 " %s\n", value, desc[idx]);
1372 break;
1373 case isc_statsformat_xml:
1374 #ifdef HAVE_LIBXML2
1375 writer = arg;
1376
1377 if (category != NULL) {
1378 /* <NameOfCategory> */
1379 TRY0(xmlTextWriterStartElement(
1380 writer, ISC_XMLCHAR category));
1381
1382 /* <name> inside category */
1383 TRY0(xmlTextWriterStartElement(
1384 writer, ISC_XMLCHAR "name"));
1385 TRY0(xmlTextWriterWriteString(
1386 writer, ISC_XMLCHAR desc[idx]));
1387 TRY0(xmlTextWriterEndElement(writer));
1388 /* </name> */
1389
1390 /* <counter> */
1391 TRY0(xmlTextWriterStartElement(
1392 writer, ISC_XMLCHAR "counter"));
1393 TRY0(xmlTextWriterWriteFormatString(
1394 writer, "%" PRIu64, value));
1395
1396 TRY0(xmlTextWriterEndElement(writer));
1397 /* </counter> */
1398 TRY0(xmlTextWriterEndElement(writer));
1399 /* </NameOfCategory> */
1400 } else {
1401 TRY0(xmlTextWriterStartElement(
1402 writer, ISC_XMLCHAR "counter"));
1403 TRY0(xmlTextWriterWriteAttribute(
1404 writer, ISC_XMLCHAR "name",
1405 ISC_XMLCHAR desc[idx]));
1406 TRY0(xmlTextWriterWriteFormatString(
1407 writer, "%" PRIu64, value));
1408 TRY0(xmlTextWriterEndElement(writer));
1409 /* counter */
1410 }
1411
1412 #endif /* ifdef HAVE_LIBXML2 */
1413 break;
1414 case isc_statsformat_json:
1415 #ifdef HAVE_JSON_C
1416 counter = json_object_new_int64(value);
1417 if (counter == NULL) {
1418 return (ISC_R_NOMEMORY);
1419 }
1420 json_object_object_add(cat, desc[idx], counter);
1421 #endif /* ifdef HAVE_JSON_C */
1422 break;
1423 }
1424 }
1425 return (ISC_R_SUCCESS);
1426 #ifdef HAVE_LIBXML2
1427 error:
1428 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
1429 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
1430 "failed at dump_counters()");
1431 return (ISC_R_FAILURE);
1432 #endif /* ifdef HAVE_LIBXML2 */
1433 }
1434
1435 static void
rdtypestat_dump(dns_rdatastatstype_t type,uint64_t val,void * arg)1436 rdtypestat_dump(dns_rdatastatstype_t type, uint64_t val, void *arg) {
1437 char typebuf[64];
1438 const char *typestr;
1439 stats_dumparg_t *dumparg = arg;
1440 FILE *fp;
1441 #ifdef HAVE_LIBXML2
1442 void *writer;
1443 int xmlrc;
1444 #endif /* ifdef HAVE_LIBXML2 */
1445 #ifdef HAVE_JSON_C
1446 json_object *zoneobj, *obj;
1447 #endif /* ifdef HAVE_JSON_C */
1448
1449 if ((DNS_RDATASTATSTYPE_ATTR(type) &
1450 DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) == 0) {
1451 dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf,
1452 sizeof(typebuf));
1453 typestr = typebuf;
1454 } else {
1455 typestr = "Others";
1456 }
1457
1458 switch (dumparg->type) {
1459 case isc_statsformat_file:
1460 fp = dumparg->arg;
1461 fprintf(fp, "%20" PRIu64 " %s\n", val, typestr);
1462 break;
1463 case isc_statsformat_xml:
1464 #ifdef HAVE_LIBXML2
1465 writer = dumparg->arg;
1466
1467 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
1468 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
1469 ISC_XMLCHAR typestr));
1470
1471 TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, val));
1472
1473 TRY0(xmlTextWriterEndElement(writer)); /* type */
1474 #endif /* ifdef HAVE_LIBXML2 */
1475 break;
1476 case isc_statsformat_json:
1477 #ifdef HAVE_JSON_C
1478 zoneobj = (json_object *)dumparg->arg;
1479 obj = json_object_new_int64(val);
1480 if (obj == NULL) {
1481 return;
1482 }
1483 json_object_object_add(zoneobj, typestr, obj);
1484 #endif /* ifdef HAVE_JSON_C */
1485 break;
1486 }
1487 return;
1488 #ifdef HAVE_LIBXML2
1489 error:
1490 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
1491 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
1492 "failed at rdtypestat_dump()");
1493 dumparg->result = ISC_R_FAILURE;
1494 return;
1495 #endif /* ifdef HAVE_LIBXML2 */
1496 }
1497
1498 static bool
rdatastatstype_attr(dns_rdatastatstype_t type,unsigned int attr)1499 rdatastatstype_attr(dns_rdatastatstype_t type, unsigned int attr) {
1500 return ((DNS_RDATASTATSTYPE_ATTR(type) & attr) != 0);
1501 }
1502
1503 static void
rdatasetstats_dump(dns_rdatastatstype_t type,uint64_t val,void * arg)1504 rdatasetstats_dump(dns_rdatastatstype_t type, uint64_t val, void *arg) {
1505 stats_dumparg_t *dumparg = arg;
1506 FILE *fp;
1507 char typebuf[64];
1508 const char *typestr;
1509 bool nxrrset = false;
1510 bool stale = false;
1511 bool ancient = false;
1512 #ifdef HAVE_LIBXML2
1513 void *writer;
1514 int xmlrc;
1515 #endif /* ifdef HAVE_LIBXML2 */
1516 #ifdef HAVE_JSON_C
1517 json_object *zoneobj, *obj;
1518 char buf[1024];
1519 #endif /* ifdef HAVE_JSON_C */
1520
1521 if ((DNS_RDATASTATSTYPE_ATTR(type) &
1522 DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) != 0) {
1523 typestr = "NXDOMAIN";
1524 } else if ((DNS_RDATASTATSTYPE_ATTR(type) &
1525 DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) != 0)
1526 {
1527 typestr = "Others";
1528 } else {
1529 dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf,
1530 sizeof(typebuf));
1531 typestr = typebuf;
1532 }
1533
1534 nxrrset = rdatastatstype_attr(type, DNS_RDATASTATSTYPE_ATTR_NXRRSET);
1535 stale = rdatastatstype_attr(type, DNS_RDATASTATSTYPE_ATTR_STALE);
1536 ancient = rdatastatstype_attr(type, DNS_RDATASTATSTYPE_ATTR_ANCIENT);
1537
1538 switch (dumparg->type) {
1539 case isc_statsformat_file:
1540 fp = dumparg->arg;
1541 fprintf(fp, "%20" PRIu64 " %s%s%s%s\n", val, ancient ? "~" : "",
1542 stale ? "#" : "", nxrrset ? "!" : "", typestr);
1543 break;
1544 case isc_statsformat_xml:
1545 #ifdef HAVE_LIBXML2
1546 writer = dumparg->arg;
1547
1548 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset"));
1549 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
1550 TRY0(xmlTextWriterWriteFormatString(
1551 writer, "%s%s%s%s", ancient ? "~" : "",
1552 stale ? "#" : "", nxrrset ? "!" : "", typestr));
1553 TRY0(xmlTextWriterEndElement(writer)); /* name */
1554
1555 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
1556 TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, val));
1557 TRY0(xmlTextWriterEndElement(writer)); /* counter */
1558
1559 TRY0(xmlTextWriterEndElement(writer)); /* rrset */
1560 #endif /* ifdef HAVE_LIBXML2 */
1561 break;
1562 case isc_statsformat_json:
1563 #ifdef HAVE_JSON_C
1564 zoneobj = (json_object *)dumparg->arg;
1565 snprintf(buf, sizeof(buf), "%s%s%s%s", ancient ? "~" : "",
1566 stale ? "#" : "", nxrrset ? "!" : "", typestr);
1567 obj = json_object_new_int64(val);
1568 if (obj == NULL) {
1569 return;
1570 }
1571 json_object_object_add(zoneobj, buf, obj);
1572 #endif /* ifdef HAVE_JSON_C */
1573 break;
1574 }
1575 return;
1576 #ifdef HAVE_LIBXML2
1577 error:
1578 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
1579 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
1580 "failed at rdatasetstats_dump()");
1581 dumparg->result = ISC_R_FAILURE;
1582 #endif /* ifdef HAVE_LIBXML2 */
1583 }
1584
1585 static void
opcodestat_dump(dns_opcode_t code,uint64_t val,void * arg)1586 opcodestat_dump(dns_opcode_t code, uint64_t val, void *arg) {
1587 FILE *fp;
1588 isc_buffer_t b;
1589 char codebuf[64];
1590 stats_dumparg_t *dumparg = arg;
1591 #ifdef HAVE_LIBXML2
1592 void *writer;
1593 int xmlrc;
1594 #endif /* ifdef HAVE_LIBXML2 */
1595 #ifdef HAVE_JSON_C
1596 json_object *zoneobj, *obj;
1597 #endif /* ifdef HAVE_JSON_C */
1598
1599 isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1);
1600 dns_opcode_totext(code, &b);
1601 codebuf[isc_buffer_usedlength(&b)] = '\0';
1602
1603 switch (dumparg->type) {
1604 case isc_statsformat_file:
1605 fp = dumparg->arg;
1606 fprintf(fp, "%20" PRIu64 " %s\n", val, codebuf);
1607 break;
1608 case isc_statsformat_xml:
1609 #ifdef HAVE_LIBXML2
1610 writer = dumparg->arg;
1611 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
1612 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
1613 ISC_XMLCHAR codebuf));
1614 TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, val));
1615 TRY0(xmlTextWriterEndElement(writer)); /* counter */
1616 #endif /* ifdef HAVE_LIBXML2 */
1617 break;
1618 case isc_statsformat_json:
1619 #ifdef HAVE_JSON_C
1620 zoneobj = (json_object *)dumparg->arg;
1621 obj = json_object_new_int64(val);
1622 if (obj == NULL) {
1623 return;
1624 }
1625 json_object_object_add(zoneobj, codebuf, obj);
1626 #endif /* ifdef HAVE_JSON_C */
1627 break;
1628 }
1629 return;
1630
1631 #ifdef HAVE_LIBXML2
1632 error:
1633 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
1634 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
1635 "failed at opcodestat_dump()");
1636 dumparg->result = ISC_R_FAILURE;
1637 return;
1638 #endif /* ifdef HAVE_LIBXML2 */
1639 }
1640
1641 static void
rcodestat_dump(dns_rcode_t code,uint64_t val,void * arg)1642 rcodestat_dump(dns_rcode_t code, uint64_t val, void *arg) {
1643 FILE *fp;
1644 isc_buffer_t b;
1645 char codebuf[64];
1646 stats_dumparg_t *dumparg = arg;
1647 #ifdef HAVE_LIBXML2
1648 void *writer;
1649 int xmlrc;
1650 #endif /* ifdef HAVE_LIBXML2 */
1651 #ifdef HAVE_JSON_C
1652 json_object *zoneobj, *obj;
1653 #endif /* ifdef HAVE_JSON_C */
1654
1655 isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1);
1656 dns_rcode_totext(code, &b);
1657 codebuf[isc_buffer_usedlength(&b)] = '\0';
1658
1659 switch (dumparg->type) {
1660 case isc_statsformat_file:
1661 fp = dumparg->arg;
1662 fprintf(fp, "%20" PRIu64 " %s\n", val, codebuf);
1663 break;
1664 case isc_statsformat_xml:
1665 #ifdef HAVE_LIBXML2
1666 writer = dumparg->arg;
1667 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
1668 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
1669 ISC_XMLCHAR codebuf));
1670 TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, val));
1671 TRY0(xmlTextWriterEndElement(writer)); /* counter */
1672 #endif /* ifdef HAVE_LIBXML2 */
1673 break;
1674 case isc_statsformat_json:
1675 #ifdef HAVE_JSON_C
1676 zoneobj = (json_object *)dumparg->arg;
1677 obj = json_object_new_int64(val);
1678 if (obj == NULL) {
1679 return;
1680 }
1681 json_object_object_add(zoneobj, codebuf, obj);
1682 #endif /* ifdef HAVE_JSON_C */
1683 break;
1684 }
1685 return;
1686
1687 #ifdef HAVE_LIBXML2
1688 error:
1689 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
1690 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
1691 "failed at rcodestat_dump()");
1692 dumparg->result = ISC_R_FAILURE;
1693 return;
1694 #endif /* ifdef HAVE_LIBXML2 */
1695 }
1696
1697 #if defined(EXTENDED_STATS)
1698 static void
dnssecsignstat_dump(dns_keytag_t tag,uint64_t val,void * arg)1699 dnssecsignstat_dump(dns_keytag_t tag, uint64_t val, void *arg) {
1700 FILE *fp;
1701 char tagbuf[64];
1702 stats_dumparg_t *dumparg = arg;
1703 #ifdef HAVE_LIBXML2
1704 xmlTextWriterPtr writer;
1705 int xmlrc;
1706 #endif /* ifdef HAVE_LIBXML2 */
1707 #ifdef HAVE_JSON_C
1708 json_object *zoneobj, *obj;
1709 #endif /* ifdef HAVE_JSON_C */
1710
1711 snprintf(tagbuf, sizeof(tagbuf), "%u", tag);
1712
1713 switch (dumparg->type) {
1714 case isc_statsformat_file:
1715 fp = dumparg->arg;
1716 fprintf(fp, "%20" PRIu64 " %s\n", val, tagbuf);
1717 break;
1718 case isc_statsformat_xml:
1719 #ifdef HAVE_LIBXML2
1720 writer = dumparg->arg;
1721 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
1722 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
1723 ISC_XMLCHAR tagbuf));
1724 TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, val));
1725 TRY0(xmlTextWriterEndElement(writer)); /* counter */
1726 #endif /* ifdef HAVE_LIBXML2 */
1727 break;
1728 case isc_statsformat_json:
1729 #ifdef HAVE_JSON_C
1730 zoneobj = (json_object *)dumparg->arg;
1731 obj = json_object_new_int64(val);
1732 if (obj == NULL) {
1733 return;
1734 }
1735 json_object_object_add(zoneobj, tagbuf, obj);
1736 #endif /* ifdef HAVE_JSON_C */
1737 break;
1738 }
1739 return;
1740 #ifdef HAVE_LIBXML2
1741 error:
1742 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
1743 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
1744 "failed at dnssecsignstat_dump()");
1745 dumparg->result = ISC_R_FAILURE;
1746 return;
1747 #endif /* ifdef HAVE_LIBXML2 */
1748 }
1749 #endif /* defined(EXTENDED_STATS) */
1750
1751 #ifdef HAVE_LIBXML2
1752 /*
1753 * Which statistics to include when rendering to XML
1754 */
1755 #define STATS_XML_STATUS 0x00 /* display only common statistics */
1756 #define STATS_XML_SERVER 0x01
1757 #define STATS_XML_ZONES 0x02
1758 #define STATS_XML_TASKS 0x04
1759 #define STATS_XML_NET 0x08
1760 #define STATS_XML_MEM 0x10
1761 #define STATS_XML_TRAFFIC 0x20
1762 #define STATS_XML_ALL 0xff
1763
1764 static isc_result_t
zone_xmlrender(dns_zone_t * zone,void * arg)1765 zone_xmlrender(dns_zone_t *zone, void *arg) {
1766 isc_result_t result;
1767 char buf[1024 + 32]; /* sufficiently large for zone name and class */
1768 dns_rdataclass_t rdclass;
1769 uint32_t serial;
1770 xmlTextWriterPtr writer = arg;
1771 dns_zonestat_level_t statlevel;
1772 int xmlrc;
1773 stats_dumparg_t dumparg;
1774 const char *ztype;
1775
1776 statlevel = dns_zone_getstatlevel(zone);
1777 if (statlevel == dns_zonestat_none) {
1778 return (ISC_R_SUCCESS);
1779 }
1780
1781 dumparg.type = isc_statsformat_xml;
1782 dumparg.arg = writer;
1783
1784 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone"));
1785
1786 dns_zone_nameonly(zone, buf, sizeof(buf));
1787 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
1788 ISC_XMLCHAR buf));
1789
1790 rdclass = dns_zone_getclass(zone);
1791 dns_rdataclass_format(rdclass, buf, sizeof(buf));
1792 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "rdataclass",
1793 ISC_XMLCHAR buf));
1794
1795 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"));
1796 ztype = user_zonetype(zone);
1797 if (ztype != NULL) {
1798 TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR ztype));
1799 } else {
1800 TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "unknown"));
1801 }
1802 TRY0(xmlTextWriterEndElement(writer)); /* type */
1803
1804 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial"));
1805 if (dns_zone_getserial(zone, &serial) == ISC_R_SUCCESS) {
1806 TRY0(xmlTextWriterWriteFormatString(writer, "%u", serial));
1807 } else {
1808 TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
1809 }
1810 TRY0(xmlTextWriterEndElement(writer)); /* serial */
1811
1812 /*
1813 * Export zone timers to the statistics channel in XML format. For
1814 * master zones, only include the loaded time. For slave zones, also
1815 * include the expires and refresh times.
1816 */
1817 isc_time_t timestamp;
1818
1819 result = dns_zone_getloadtime(zone, ×tamp);
1820 if (result != ISC_R_SUCCESS) {
1821 goto error;
1822 }
1823
1824 isc_time_formatISO8601(×tamp, buf, 64);
1825 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "loaded"));
1826 TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
1827 TRY0(xmlTextWriterEndElement(writer));
1828
1829 if (dns_zone_gettype(zone) == dns_zone_slave) {
1830 result = dns_zone_getexpiretime(zone, ×tamp);
1831 if (result != ISC_R_SUCCESS) {
1832 goto error;
1833 }
1834 isc_time_formatISO8601(×tamp, buf, 64);
1835 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "expires"));
1836 TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
1837 TRY0(xmlTextWriterEndElement(writer));
1838
1839 result = dns_zone_getrefreshtime(zone, ×tamp);
1840 if (result != ISC_R_SUCCESS) {
1841 goto error;
1842 }
1843 isc_time_formatISO8601(×tamp, buf, 64);
1844 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "refresh"));
1845 TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
1846 TRY0(xmlTextWriterEndElement(writer));
1847 }
1848
1849 if (statlevel == dns_zonestat_full) {
1850 isc_stats_t *zonestats;
1851 isc_stats_t *gluecachestats;
1852 dns_stats_t *rcvquerystats;
1853 dns_stats_t *dnssecsignstats;
1854 uint64_t nsstat_values[ns_statscounter_max];
1855 uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
1856
1857 zonestats = dns_zone_getrequeststats(zone);
1858 if (zonestats != NULL) {
1859 TRY0(xmlTextWriterStartElement(writer,
1860 ISC_XMLCHAR "counters"));
1861 TRY0(xmlTextWriterWriteAttribute(writer,
1862 ISC_XMLCHAR "type",
1863 ISC_XMLCHAR "rcode"));
1864
1865 result = dump_counters(zonestats, isc_statsformat_xml,
1866 writer, NULL, nsstats_xmldesc,
1867 ns_statscounter_max,
1868 nsstats_index, nsstat_values,
1869 ISC_STATSDUMP_VERBOSE);
1870 if (result != ISC_R_SUCCESS) {
1871 goto error;
1872 }
1873 /* counters type="rcode"*/
1874 TRY0(xmlTextWriterEndElement(writer));
1875 }
1876
1877 gluecachestats = dns_zone_getgluecachestats(zone);
1878 if (gluecachestats != NULL) {
1879 TRY0(xmlTextWriterStartElement(writer,
1880 ISC_XMLCHAR "counters"));
1881 TRY0(xmlTextWriterWriteAttribute(
1882 writer, ISC_XMLCHAR "type",
1883 ISC_XMLCHAR "gluecache"));
1884
1885 result = dump_counters(
1886 gluecachestats, isc_statsformat_xml, writer,
1887 NULL, gluecachestats_xmldesc,
1888 dns_gluecachestatscounter_max,
1889 gluecachestats_index, gluecachestats_values,
1890 ISC_STATSDUMP_VERBOSE);
1891 if (result != ISC_R_SUCCESS) {
1892 goto error;
1893 }
1894 /* counters type="rcode"*/
1895 TRY0(xmlTextWriterEndElement(writer));
1896 }
1897
1898 rcvquerystats = dns_zone_getrcvquerystats(zone);
1899 if (rcvquerystats != NULL) {
1900 TRY0(xmlTextWriterStartElement(writer,
1901 ISC_XMLCHAR "counters"));
1902 TRY0(xmlTextWriterWriteAttribute(writer,
1903 ISC_XMLCHAR "type",
1904 ISC_XMLCHAR "qtype"));
1905
1906 dumparg.result = ISC_R_SUCCESS;
1907 dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump,
1908 &dumparg, 0);
1909 if (dumparg.result != ISC_R_SUCCESS) {
1910 goto error;
1911 }
1912
1913 /* counters type="qtype"*/
1914 TRY0(xmlTextWriterEndElement(writer));
1915 }
1916
1917 dnssecsignstats = dns_zone_getdnssecsignstats(zone);
1918 if (dnssecsignstats != NULL) {
1919 /* counters type="dnssec-sign"*/
1920 TRY0(xmlTextWriterStartElement(writer,
1921 ISC_XMLCHAR "counters"));
1922 TRY0(xmlTextWriterWriteAttribute(
1923 writer, ISC_XMLCHAR "type",
1924 ISC_XMLCHAR "dnssec-sign"));
1925
1926 dumparg.result = ISC_R_SUCCESS;
1927 dns_dnssecsignstats_dump(
1928 dnssecsignstats, dns_dnssecsignstats_sign,
1929 dnssecsignstat_dump, &dumparg, 0);
1930 if (dumparg.result != ISC_R_SUCCESS) {
1931 goto error;
1932 }
1933
1934 /* counters type="dnssec-sign"*/
1935 TRY0(xmlTextWriterEndElement(writer));
1936
1937 /* counters type="dnssec-refresh"*/
1938 TRY0(xmlTextWriterStartElement(writer,
1939 ISC_XMLCHAR "counters"));
1940 TRY0(xmlTextWriterWriteAttribute(
1941 writer, ISC_XMLCHAR "type",
1942 ISC_XMLCHAR "dnssec-refresh"));
1943
1944 dumparg.result = ISC_R_SUCCESS;
1945 dns_dnssecsignstats_dump(
1946 dnssecsignstats, dns_dnssecsignstats_refresh,
1947 dnssecsignstat_dump, &dumparg, 0);
1948 if (dumparg.result != ISC_R_SUCCESS) {
1949 goto error;
1950 }
1951
1952 /* counters type="dnssec-refresh"*/
1953 TRY0(xmlTextWriterEndElement(writer));
1954 }
1955 }
1956
1957 TRY0(xmlTextWriterEndElement(writer)); /* zone */
1958
1959 return (ISC_R_SUCCESS);
1960 error:
1961 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
1962 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
1963 "Failed at zone_xmlrender()");
1964 return (ISC_R_FAILURE);
1965 }
1966
1967 static isc_result_t
generatexml(named_server_t * server,uint32_t flags,int * buflen,xmlChar ** buf)1968 generatexml(named_server_t *server, uint32_t flags, int *buflen,
1969 xmlChar **buf) {
1970 char boottime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
1971 char configtime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
1972 char nowstr[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
1973 isc_time_t now;
1974 xmlTextWriterPtr writer = NULL;
1975 xmlDocPtr doc = NULL;
1976 int xmlrc;
1977 dns_view_t *view;
1978 stats_dumparg_t dumparg;
1979 dns_stats_t *cacherrstats;
1980 uint64_t nsstat_values[ns_statscounter_max];
1981 uint64_t resstat_values[dns_resstatscounter_max];
1982 uint64_t adbstat_values[dns_adbstats_max];
1983 uint64_t zonestat_values[dns_zonestatscounter_max];
1984 uint64_t sockstat_values[isc_sockstatscounter_max];
1985 uint64_t udpinsizestat_values[dns_sizecounter_in_max];
1986 uint64_t udpoutsizestat_values[dns_sizecounter_out_max];
1987 uint64_t tcpinsizestat_values[dns_sizecounter_in_max];
1988 uint64_t tcpoutsizestat_values[dns_sizecounter_out_max];
1989 #ifdef HAVE_DNSTAP
1990 uint64_t dnstapstat_values[dns_dnstapcounter_max];
1991 #endif /* ifdef HAVE_DNSTAP */
1992 isc_result_t result;
1993
1994 isc_time_now(&now);
1995 isc_time_formatISO8601ms(&named_g_boottime, boottime, sizeof boottime);
1996 isc_time_formatISO8601ms(&named_g_configtime, configtime,
1997 sizeof configtime);
1998 isc_time_formatISO8601ms(&now, nowstr, sizeof nowstr);
1999
2000 writer = xmlNewTextWriterDoc(&doc, 0);
2001 if (writer == NULL) {
2002 goto error;
2003 }
2004 TRY0(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL));
2005 TRY0(xmlTextWriterWritePI(writer, ISC_XMLCHAR "xml-stylesheet",
2006 ISC_XMLCHAR "type=\"text/xsl\" "
2007 "href=\"/bind9.xsl\""));
2008 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics"));
2009 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version",
2010 ISC_XMLCHAR "3.11"));
2011
2012 /* Set common fields for statistics dump */
2013 dumparg.type = isc_statsformat_xml;
2014 dumparg.arg = writer;
2015
2016 /* Render server information */
2017 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "server"));
2018 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time"));
2019 TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime));
2020 TRY0(xmlTextWriterEndElement(writer)); /* boot-time */
2021 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "config-time"));
2022 TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR configtime));
2023 TRY0(xmlTextWriterEndElement(writer)); /* config-time */
2024 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time"));
2025 TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr));
2026 TRY0(xmlTextWriterEndElement(writer)); /* current-time */
2027 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "version"));
2028 TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR named_g_version));
2029 TRY0(xmlTextWriterEndElement(writer)); /* version */
2030
2031 if ((flags & STATS_XML_SERVER) != 0) {
2032 dumparg.result = ISC_R_SUCCESS;
2033
2034 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2035 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2036 ISC_XMLCHAR "opcode"));
2037
2038 dns_opcodestats_dump(server->sctx->opcodestats, opcodestat_dump,
2039 &dumparg, ISC_STATSDUMP_VERBOSE);
2040 if (dumparg.result != ISC_R_SUCCESS) {
2041 goto error;
2042 }
2043
2044 TRY0(xmlTextWriterEndElement(writer));
2045
2046 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2047 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2048 ISC_XMLCHAR "rcode"));
2049
2050 dns_rcodestats_dump(server->sctx->rcodestats, rcodestat_dump,
2051 &dumparg, ISC_STATSDUMP_VERBOSE);
2052 if (dumparg.result != ISC_R_SUCCESS) {
2053 goto error;
2054 }
2055
2056 TRY0(xmlTextWriterEndElement(writer));
2057
2058 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2059 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2060 ISC_XMLCHAR "qtype"));
2061
2062 dumparg.result = ISC_R_SUCCESS;
2063 dns_rdatatypestats_dump(server->sctx->rcvquerystats,
2064 rdtypestat_dump, &dumparg, 0);
2065 if (dumparg.result != ISC_R_SUCCESS) {
2066 goto error;
2067 }
2068 TRY0(xmlTextWriterEndElement(writer)); /* counters */
2069
2070 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2071 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2072 ISC_XMLCHAR "nsstat"));
2073
2074 result = dump_counters(ns_stats_get(server->sctx->nsstats),
2075 isc_statsformat_xml, writer, NULL,
2076 nsstats_xmldesc, ns_statscounter_max,
2077 nsstats_index, nsstat_values,
2078 ISC_STATSDUMP_VERBOSE);
2079 if (result != ISC_R_SUCCESS) {
2080 goto error;
2081 }
2082
2083 TRY0(xmlTextWriterEndElement(writer)); /* /nsstat */
2084
2085 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2086 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2087 ISC_XMLCHAR "zonestat"));
2088
2089 result = dump_counters(server->zonestats, isc_statsformat_xml,
2090 writer, NULL, zonestats_xmldesc,
2091 dns_zonestatscounter_max,
2092 zonestats_index, zonestat_values,
2093 ISC_STATSDUMP_VERBOSE);
2094 if (result != ISC_R_SUCCESS) {
2095 goto error;
2096 }
2097
2098 TRY0(xmlTextWriterEndElement(writer)); /* /zonestat */
2099
2100 /*
2101 * Most of the common resolver statistics entries are 0, so
2102 * we don't use the verbose dump here.
2103 */
2104 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2105 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2106 ISC_XMLCHAR "resstat"));
2107 result = dump_counters(
2108 server->resolverstats, isc_statsformat_xml, writer,
2109 NULL, resstats_xmldesc, dns_resstatscounter_max,
2110 resstats_index, resstat_values, 0);
2111 if (result != ISC_R_SUCCESS) {
2112 goto error;
2113 }
2114 TRY0(xmlTextWriterEndElement(writer)); /* resstat */
2115
2116 #ifdef HAVE_DNSTAP
2117 if (server->dtenv != NULL) {
2118 isc_stats_t *dnstapstats = NULL;
2119 TRY0(xmlTextWriterStartElement(writer,
2120 ISC_XMLCHAR "counters"));
2121 TRY0(xmlTextWriterWriteAttribute(writer,
2122 ISC_XMLCHAR "type",
2123 ISC_XMLCHAR "dnstap"));
2124 dns_dt_getstats(named_g_server->dtenv, &dnstapstats);
2125 result = dump_counters(
2126 dnstapstats, isc_statsformat_xml, writer, NULL,
2127 dnstapstats_xmldesc, dns_dnstapcounter_max,
2128 dnstapstats_index, dnstapstat_values, 0);
2129 isc_stats_detach(&dnstapstats);
2130 if (result != ISC_R_SUCCESS) {
2131 goto error;
2132 }
2133 TRY0(xmlTextWriterEndElement(writer)); /* dnstap */
2134 }
2135 #endif /* ifdef HAVE_DNSTAP */
2136 }
2137
2138 if ((flags & STATS_XML_NET) != 0) {
2139 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2140 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2141 ISC_XMLCHAR "sockstat"));
2142
2143 result = dump_counters(server->sockstats, isc_statsformat_xml,
2144 writer, NULL, sockstats_xmldesc,
2145 isc_sockstatscounter_max,
2146 sockstats_index, sockstat_values,
2147 ISC_STATSDUMP_VERBOSE);
2148 if (result != ISC_R_SUCCESS) {
2149 goto error;
2150 }
2151
2152 TRY0(xmlTextWriterEndElement(writer)); /* /sockstat */
2153 }
2154 TRY0(xmlTextWriterEndElement(writer)); /* /server */
2155
2156 if ((flags & STATS_XML_TRAFFIC) != 0) {
2157 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "traffic"));
2158 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ipv4"));
2159 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "udp"));
2160 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2161 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2162 ISC_XMLCHAR "request-size"));
2163
2164 result = dump_counters(
2165 server->sctx->udpinstats4, isc_statsformat_xml, writer,
2166 NULL, udpinsizestats_xmldesc, dns_sizecounter_in_max,
2167 udpinsizestats_index, udpinsizestat_values, 0);
2168 if (result != ISC_R_SUCCESS) {
2169 goto error;
2170 }
2171
2172 TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
2173
2174 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2175 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2176 ISC_XMLCHAR "response-size"));
2177
2178 result = dump_counters(
2179 server->sctx->udpoutstats4, isc_statsformat_xml, writer,
2180 NULL, udpoutsizestats_xmldesc, dns_sizecounter_out_max,
2181 udpoutsizestats_index, udpoutsizestat_values, 0);
2182 if (result != ISC_R_SUCCESS) {
2183 goto error;
2184 }
2185
2186 TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
2187 TRY0(xmlTextWriterEndElement(writer)); /* </udp> */
2188
2189 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tcp"));
2190 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2191 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2192 ISC_XMLCHAR "request-size"));
2193
2194 result = dump_counters(
2195 server->sctx->tcpinstats4, isc_statsformat_xml, writer,
2196 NULL, tcpinsizestats_xmldesc, dns_sizecounter_in_max,
2197 tcpinsizestats_index, tcpinsizestat_values, 0);
2198 if (result != ISC_R_SUCCESS) {
2199 goto error;
2200 }
2201
2202 TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
2203
2204 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2205 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2206 ISC_XMLCHAR "response-size"));
2207
2208 result = dump_counters(
2209 server->sctx->tcpoutstats4, isc_statsformat_xml, writer,
2210 NULL, tcpoutsizestats_xmldesc, dns_sizecounter_out_max,
2211 tcpoutsizestats_index, tcpoutsizestat_values, 0);
2212 if (result != ISC_R_SUCCESS) {
2213 goto error;
2214 }
2215
2216 TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
2217 TRY0(xmlTextWriterEndElement(writer)); /* </tcp> */
2218 TRY0(xmlTextWriterEndElement(writer)); /* </ipv4> */
2219
2220 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ipv6"));
2221 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "udp"));
2222 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2223 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2224 ISC_XMLCHAR "request-size"));
2225
2226 result = dump_counters(
2227 server->sctx->udpinstats6, isc_statsformat_xml, writer,
2228 NULL, udpinsizestats_xmldesc, dns_sizecounter_in_max,
2229 udpinsizestats_index, udpinsizestat_values, 0);
2230 if (result != ISC_R_SUCCESS) {
2231 goto error;
2232 }
2233
2234 TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
2235
2236 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2237 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2238 ISC_XMLCHAR "response-size"));
2239
2240 result = dump_counters(
2241 server->sctx->udpoutstats6, isc_statsformat_xml, writer,
2242 NULL, udpoutsizestats_xmldesc, dns_sizecounter_out_max,
2243 udpoutsizestats_index, udpoutsizestat_values, 0);
2244 if (result != ISC_R_SUCCESS) {
2245 goto error;
2246 }
2247
2248 TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
2249 TRY0(xmlTextWriterEndElement(writer)); /* </udp> */
2250
2251 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tcp"));
2252 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2253 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2254 ISC_XMLCHAR "request-size"));
2255
2256 result = dump_counters(
2257 server->sctx->tcpinstats6, isc_statsformat_xml, writer,
2258 NULL, tcpinsizestats_xmldesc, dns_sizecounter_in_max,
2259 tcpinsizestats_index, tcpinsizestat_values, 0);
2260 if (result != ISC_R_SUCCESS) {
2261 goto error;
2262 }
2263
2264 TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
2265
2266 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2267 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2268 ISC_XMLCHAR "response-size"));
2269
2270 result = dump_counters(
2271 server->sctx->tcpoutstats6, isc_statsformat_xml, writer,
2272 NULL, tcpoutsizestats_xmldesc, dns_sizecounter_out_max,
2273 tcpoutsizestats_index, tcpoutsizestat_values, 0);
2274 if (result != ISC_R_SUCCESS) {
2275 goto error;
2276 }
2277
2278 TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
2279 TRY0(xmlTextWriterEndElement(writer)); /* </tcp> */
2280 TRY0(xmlTextWriterEndElement(writer)); /* </ipv6> */
2281 TRY0(xmlTextWriterEndElement(writer)); /* </traffic> */
2282 }
2283
2284 /*
2285 * Render views. For each view we know of, call its
2286 * rendering function.
2287 */
2288 view = ISC_LIST_HEAD(server->viewlist);
2289 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views"));
2290 while (view != NULL &&
2291 ((flags & (STATS_XML_SERVER | STATS_XML_ZONES)) != 0)) {
2292 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "view"));
2293 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
2294 ISC_XMLCHAR view->name));
2295
2296 if ((flags & STATS_XML_ZONES) != 0) {
2297 TRY0(xmlTextWriterStartElement(writer,
2298 ISC_XMLCHAR "zones"));
2299 result = dns_zt_apply(view->zonetable, true, NULL,
2300 zone_xmlrender, writer);
2301 if (result != ISC_R_SUCCESS) {
2302 goto error;
2303 }
2304 TRY0(xmlTextWriterEndElement(writer)); /* /zones */
2305 }
2306
2307 if ((flags & STATS_XML_SERVER) == 0) {
2308 TRY0(xmlTextWriterEndElement(writer)); /* /view */
2309 view = ISC_LIST_NEXT(view, link);
2310 continue;
2311 }
2312
2313 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2314 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2315 ISC_XMLCHAR "resqtype"));
2316
2317 if (view->resquerystats != NULL) {
2318 dumparg.result = ISC_R_SUCCESS;
2319 dns_rdatatypestats_dump(view->resquerystats,
2320 rdtypestat_dump, &dumparg, 0);
2321 if (dumparg.result != ISC_R_SUCCESS) {
2322 goto error;
2323 }
2324 }
2325 TRY0(xmlTextWriterEndElement(writer));
2326
2327 /* <resstats> */
2328 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2329 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2330 ISC_XMLCHAR "resstats"));
2331 if (view->resstats != NULL) {
2332 result = dump_counters(
2333 view->resstats, isc_statsformat_xml, writer,
2334 NULL, resstats_xmldesc, dns_resstatscounter_max,
2335 resstats_index, resstat_values,
2336 ISC_STATSDUMP_VERBOSE);
2337 if (result != ISC_R_SUCCESS) {
2338 goto error;
2339 }
2340 }
2341 TRY0(xmlTextWriterEndElement(writer)); /* </resstats> */
2342
2343 cacherrstats = dns_db_getrrsetstats(view->cachedb);
2344 if (cacherrstats != NULL) {
2345 TRY0(xmlTextWriterStartElement(writer,
2346 ISC_XMLCHAR "cache"));
2347 TRY0(xmlTextWriterWriteAttribute(
2348 writer, ISC_XMLCHAR "name",
2349 ISC_XMLCHAR dns_cache_getname(view->cache)));
2350 dumparg.result = ISC_R_SUCCESS;
2351 dns_rdatasetstats_dump(cacherrstats, rdatasetstats_dump,
2352 &dumparg, 0);
2353 if (dumparg.result != ISC_R_SUCCESS) {
2354 goto error;
2355 }
2356 TRY0(xmlTextWriterEndElement(writer)); /* cache */
2357 }
2358
2359 /* <adbstats> */
2360 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2361 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2362 ISC_XMLCHAR "adbstat"));
2363 if (view->adbstats != NULL) {
2364 result = dump_counters(
2365 view->adbstats, isc_statsformat_xml, writer,
2366 NULL, adbstats_xmldesc, dns_adbstats_max,
2367 adbstats_index, adbstat_values,
2368 ISC_STATSDUMP_VERBOSE);
2369 if (result != ISC_R_SUCCESS) {
2370 goto error;
2371 }
2372 }
2373 TRY0(xmlTextWriterEndElement(writer)); /* </adbstats> */
2374
2375 /* <cachestats> */
2376 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
2377 TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
2378 ISC_XMLCHAR "cachestats"));
2379 TRY0(dns_cache_renderxml(view->cache, writer));
2380 TRY0(xmlTextWriterEndElement(writer)); /* </cachestats> */
2381
2382 TRY0(xmlTextWriterEndElement(writer)); /* view */
2383
2384 view = ISC_LIST_NEXT(view, link);
2385 }
2386 TRY0(xmlTextWriterEndElement(writer)); /* /views */
2387
2388 if ((flags & STATS_XML_NET) != 0) {
2389 TRY0(xmlTextWriterStartElement(writer,
2390 ISC_XMLCHAR "socketmgr"));
2391 TRY0(isc_socketmgr_renderxml(named_g_socketmgr, writer));
2392 TRY0(xmlTextWriterEndElement(writer)); /* /socketmgr */
2393 }
2394
2395 if ((flags & STATS_XML_TASKS) != 0) {
2396 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "taskmgr"));
2397 TRY0(isc_taskmgr_renderxml(named_g_taskmgr, writer));
2398 TRY0(xmlTextWriterEndElement(writer)); /* /taskmgr */
2399 }
2400
2401 if ((flags & STATS_XML_MEM) != 0) {
2402 TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory"));
2403 TRY0(isc_mem_renderxml(writer));
2404 TRY0(xmlTextWriterEndElement(writer)); /* /memory */
2405 }
2406
2407 TRY0(xmlTextWriterEndElement(writer)); /* /statistics */
2408 TRY0(xmlTextWriterEndDocument(writer));
2409
2410 xmlFreeTextWriter(writer);
2411
2412 xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 0);
2413 if (*buf == NULL) {
2414 goto error;
2415 }
2416 xmlFreeDoc(doc);
2417 return (ISC_R_SUCCESS);
2418
2419 error:
2420 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
2421 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
2422 "failed generating XML response");
2423 if (writer != NULL) {
2424 xmlFreeTextWriter(writer);
2425 }
2426 if (doc != NULL) {
2427 xmlFreeDoc(doc);
2428 }
2429 return (ISC_R_FAILURE);
2430 }
2431
2432 static void
wrap_xmlfree(isc_buffer_t * buffer,void * arg)2433 wrap_xmlfree(isc_buffer_t *buffer, void *arg) {
2434 UNUSED(arg);
2435
2436 xmlFree(isc_buffer_base(buffer));
2437 }
2438
2439 static isc_result_t
render_xml(uint32_t flags,const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)2440 render_xml(uint32_t flags, const char *url, isc_httpdurl_t *urlinfo,
2441 const char *querystring, const char *headers, void *arg,
2442 unsigned int *retcode, const char **retmsg, const char **mimetype,
2443 isc_buffer_t *b, isc_httpdfree_t **freecb, void **freecb_args) {
2444 unsigned char *msg = NULL;
2445 int msglen;
2446 named_server_t *server = arg;
2447 isc_result_t result;
2448
2449 UNUSED(url);
2450 UNUSED(urlinfo);
2451 UNUSED(headers);
2452 UNUSED(querystring);
2453
2454 result = generatexml(server, flags, &msglen, &msg);
2455
2456 if (result == ISC_R_SUCCESS) {
2457 *retcode = 200;
2458 *retmsg = "OK";
2459 *mimetype = "text/xml";
2460 isc_buffer_reinit(b, msg, msglen);
2461 isc_buffer_add(b, msglen);
2462 *freecb = wrap_xmlfree;
2463 *freecb_args = NULL;
2464 } else {
2465 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
2466 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
2467 "failed at rendering XML()");
2468 }
2469
2470 return (result);
2471 }
2472
2473 static isc_result_t
render_xml_all(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)2474 render_xml_all(const char *url, isc_httpdurl_t *urlinfo,
2475 const char *querystring, const char *headers, void *arg,
2476 unsigned int *retcode, const char **retmsg,
2477 const char **mimetype, isc_buffer_t *b, isc_httpdfree_t **freecb,
2478 void **freecb_args) {
2479 return (render_xml(STATS_XML_ALL, url, urlinfo, querystring, headers,
2480 arg, retcode, retmsg, mimetype, b, freecb,
2481 freecb_args));
2482 }
2483
2484 static isc_result_t
render_xml_status(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)2485 render_xml_status(const char *url, isc_httpdurl_t *urlinfo,
2486 const char *querystring, const char *headers, void *arg,
2487 unsigned int *retcode, const char **retmsg,
2488 const char **mimetype, isc_buffer_t *b,
2489 isc_httpdfree_t **freecb, void **freecb_args) {
2490 return (render_xml(STATS_XML_STATUS, url, urlinfo, querystring, headers,
2491 arg, retcode, retmsg, mimetype, b, freecb,
2492 freecb_args));
2493 }
2494
2495 static isc_result_t
render_xml_server(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)2496 render_xml_server(const char *url, isc_httpdurl_t *urlinfo,
2497 const char *querystring, const char *headers, void *arg,
2498 unsigned int *retcode, const char **retmsg,
2499 const char **mimetype, isc_buffer_t *b,
2500 isc_httpdfree_t **freecb, void **freecb_args) {
2501 return (render_xml(STATS_XML_SERVER, url, urlinfo, querystring, headers,
2502 arg, retcode, retmsg, mimetype, b, freecb,
2503 freecb_args));
2504 }
2505
2506 static isc_result_t
render_xml_zones(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)2507 render_xml_zones(const char *url, isc_httpdurl_t *urlinfo,
2508 const char *querystring, const char *headers, void *arg,
2509 unsigned int *retcode, const char **retmsg,
2510 const char **mimetype, isc_buffer_t *b,
2511 isc_httpdfree_t **freecb, void **freecb_args) {
2512 return (render_xml(STATS_XML_ZONES, url, urlinfo, querystring, headers,
2513 arg, retcode, retmsg, mimetype, b, freecb,
2514 freecb_args));
2515 }
2516
2517 static isc_result_t
render_xml_net(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)2518 render_xml_net(const char *url, isc_httpdurl_t *urlinfo,
2519 const char *querystring, const char *headers, void *arg,
2520 unsigned int *retcode, const char **retmsg,
2521 const char **mimetype, isc_buffer_t *b, isc_httpdfree_t **freecb,
2522 void **freecb_args) {
2523 return (render_xml(STATS_XML_NET, url, urlinfo, querystring, headers,
2524 arg, retcode, retmsg, mimetype, b, freecb,
2525 freecb_args));
2526 }
2527
2528 static isc_result_t
render_xml_tasks(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)2529 render_xml_tasks(const char *url, isc_httpdurl_t *urlinfo,
2530 const char *querystring, const char *headers, void *arg,
2531 unsigned int *retcode, const char **retmsg,
2532 const char **mimetype, isc_buffer_t *b,
2533 isc_httpdfree_t **freecb, void **freecb_args) {
2534 return (render_xml(STATS_XML_TASKS, url, urlinfo, querystring, headers,
2535 arg, retcode, retmsg, mimetype, b, freecb,
2536 freecb_args));
2537 }
2538
2539 static isc_result_t
render_xml_mem(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)2540 render_xml_mem(const char *url, isc_httpdurl_t *urlinfo,
2541 const char *querystring, const char *headers, void *arg,
2542 unsigned int *retcode, const char **retmsg,
2543 const char **mimetype, isc_buffer_t *b, isc_httpdfree_t **freecb,
2544 void **freecb_args) {
2545 return (render_xml(STATS_XML_MEM, url, urlinfo, querystring, headers,
2546 arg, retcode, retmsg, mimetype, b, freecb,
2547 freecb_args));
2548 }
2549
2550 static isc_result_t
render_xml_traffic(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)2551 render_xml_traffic(const char *url, isc_httpdurl_t *urlinfo,
2552 const char *querystring, const char *headers, void *arg,
2553 unsigned int *retcode, const char **retmsg,
2554 const char **mimetype, isc_buffer_t *b,
2555 isc_httpdfree_t **freecb, void **freecb_args) {
2556 return (render_xml(STATS_XML_TRAFFIC, url, urlinfo, querystring,
2557 headers, arg, retcode, retmsg, mimetype, b, freecb,
2558 freecb_args));
2559 }
2560
2561 #endif /* HAVE_LIBXML2 */
2562
2563 #ifdef HAVE_JSON_C
2564 /*
2565 * Which statistics to include when rendering to JSON
2566 */
2567 #define STATS_JSON_STATUS 0x00 /* display only common statistics */
2568 #define STATS_JSON_SERVER 0x01
2569 #define STATS_JSON_ZONES 0x02
2570 #define STATS_JSON_TASKS 0x04
2571 #define STATS_JSON_NET 0x08
2572 #define STATS_JSON_MEM 0x10
2573 #define STATS_JSON_TRAFFIC 0x20
2574 #define STATS_JSON_ALL 0xff
2575
2576 #define CHECK(m) \
2577 do { \
2578 result = (m); \
2579 if (result != ISC_R_SUCCESS) \
2580 goto error; \
2581 } while (0)
2582
2583 #define CHECKMEM(m) \
2584 do { \
2585 if (m == NULL) { \
2586 result = ISC_R_NOMEMORY; \
2587 goto error; \
2588 } \
2589 } while (0)
2590
2591 static void
wrap_jsonfree(isc_buffer_t * buffer,void * arg)2592 wrap_jsonfree(isc_buffer_t *buffer, void *arg) {
2593 json_object_put(isc_buffer_base(buffer));
2594 if (arg != NULL) {
2595 json_object_put((json_object *)arg);
2596 }
2597 }
2598
2599 static json_object *
addzone(char * name,char * classname,const char * ztype,uint32_t serial,bool add_serial)2600 addzone(char *name, char *classname, const char *ztype, uint32_t serial,
2601 bool add_serial) {
2602 json_object *node = json_object_new_object();
2603
2604 if (node == NULL) {
2605 return (NULL);
2606 }
2607
2608 json_object_object_add(node, "name", json_object_new_string(name));
2609 json_object_object_add(node, "class",
2610 json_object_new_string(classname));
2611 if (add_serial) {
2612 json_object_object_add(node, "serial",
2613 json_object_new_int64(serial));
2614 }
2615 if (ztype != NULL) {
2616 json_object_object_add(node, "type",
2617 json_object_new_string(ztype));
2618 }
2619 return (node);
2620 }
2621
2622 static isc_result_t
zone_jsonrender(dns_zone_t * zone,void * arg)2623 zone_jsonrender(dns_zone_t *zone, void *arg) {
2624 isc_result_t result = ISC_R_SUCCESS;
2625 char buf[1024 + 32]; /* sufficiently large for zone name and class */
2626 char classbuf[64]; /* sufficiently large for class */
2627 char *zone_name_only = NULL;
2628 char *class_only = NULL;
2629 dns_rdataclass_t rdclass;
2630 uint32_t serial;
2631 json_object *zonearray = (json_object *)arg;
2632 json_object *zoneobj = NULL;
2633 dns_zonestat_level_t statlevel;
2634
2635 statlevel = dns_zone_getstatlevel(zone);
2636 if (statlevel == dns_zonestat_none) {
2637 return (ISC_R_SUCCESS);
2638 }
2639
2640 dns_zone_nameonly(zone, buf, sizeof(buf));
2641 zone_name_only = buf;
2642
2643 rdclass = dns_zone_getclass(zone);
2644 dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf));
2645 class_only = classbuf;
2646
2647 if (dns_zone_getserial(zone, &serial) != ISC_R_SUCCESS) {
2648 zoneobj = addzone(zone_name_only, class_only,
2649 user_zonetype(zone), 0, false);
2650 } else {
2651 zoneobj = addzone(zone_name_only, class_only,
2652 user_zonetype(zone), serial, true);
2653 }
2654
2655 if (zoneobj == NULL) {
2656 return (ISC_R_NOMEMORY);
2657 }
2658
2659 /*
2660 * Export zone timers to the statistics channel in JSON format. For
2661 * master zones, only include the loaded time. For slave zones, also
2662 * include the expires and refresh times.
2663 */
2664
2665 isc_time_t timestamp;
2666
2667 result = dns_zone_getloadtime(zone, ×tamp);
2668 if (result != ISC_R_SUCCESS) {
2669 goto error;
2670 }
2671
2672 isc_time_formatISO8601(×tamp, buf, 64);
2673 json_object_object_add(zoneobj, "loaded", json_object_new_string(buf));
2674
2675 if (dns_zone_gettype(zone) == dns_zone_slave) {
2676 result = dns_zone_getexpiretime(zone, ×tamp);
2677 if (result != ISC_R_SUCCESS) {
2678 goto error;
2679 }
2680 isc_time_formatISO8601(×tamp, buf, 64);
2681 json_object_object_add(zoneobj, "expires",
2682 json_object_new_string(buf));
2683
2684 result = dns_zone_getrefreshtime(zone, ×tamp);
2685 if (result != ISC_R_SUCCESS) {
2686 goto error;
2687 }
2688 isc_time_formatISO8601(×tamp, buf, 64);
2689 json_object_object_add(zoneobj, "refresh",
2690 json_object_new_string(buf));
2691 }
2692
2693 if (statlevel == dns_zonestat_full) {
2694 isc_stats_t *zonestats;
2695 isc_stats_t *gluecachestats;
2696 dns_stats_t *rcvquerystats;
2697 dns_stats_t *dnssecsignstats;
2698 uint64_t nsstat_values[ns_statscounter_max];
2699 uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
2700
2701 zonestats = dns_zone_getrequeststats(zone);
2702 if (zonestats != NULL) {
2703 json_object *counters = json_object_new_object();
2704 if (counters == NULL) {
2705 result = ISC_R_NOMEMORY;
2706 goto error;
2707 }
2708
2709 result = dump_counters(zonestats, isc_statsformat_json,
2710 counters, NULL, nsstats_xmldesc,
2711 ns_statscounter_max,
2712 nsstats_index, nsstat_values, 0);
2713 if (result != ISC_R_SUCCESS) {
2714 json_object_put(counters);
2715 goto error;
2716 }
2717
2718 if (json_object_get_object(counters)->count != 0) {
2719 json_object_object_add(zoneobj, "rcodes",
2720 counters);
2721 } else {
2722 json_object_put(counters);
2723 }
2724 }
2725
2726 gluecachestats = dns_zone_getgluecachestats(zone);
2727 if (gluecachestats != NULL) {
2728 json_object *counters = json_object_new_object();
2729 if (counters == NULL) {
2730 result = ISC_R_NOMEMORY;
2731 goto error;
2732 }
2733
2734 result = dump_counters(
2735 gluecachestats, isc_statsformat_json, counters,
2736 NULL, gluecachestats_xmldesc,
2737 dns_gluecachestatscounter_max,
2738 gluecachestats_index, gluecachestats_values, 0);
2739 if (result != ISC_R_SUCCESS) {
2740 json_object_put(counters);
2741 goto error;
2742 }
2743
2744 if (json_object_get_object(counters)->count != 0) {
2745 json_object_object_add(zoneobj, "gluecache",
2746 counters);
2747 } else {
2748 json_object_put(counters);
2749 }
2750 }
2751
2752 rcvquerystats = dns_zone_getrcvquerystats(zone);
2753 if (rcvquerystats != NULL) {
2754 stats_dumparg_t dumparg;
2755 json_object *counters = json_object_new_object();
2756 CHECKMEM(counters);
2757
2758 dumparg.type = isc_statsformat_json;
2759 dumparg.arg = counters;
2760 dumparg.result = ISC_R_SUCCESS;
2761 dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump,
2762 &dumparg, 0);
2763 if (dumparg.result != ISC_R_SUCCESS) {
2764 json_object_put(counters);
2765 goto error;
2766 }
2767
2768 if (json_object_get_object(counters)->count != 0) {
2769 json_object_object_add(zoneobj, "qtypes",
2770 counters);
2771 } else {
2772 json_object_put(counters);
2773 }
2774 }
2775
2776 dnssecsignstats = dns_zone_getdnssecsignstats(zone);
2777 if (dnssecsignstats != NULL) {
2778 stats_dumparg_t dumparg;
2779 json_object *sign_counters = json_object_new_object();
2780 CHECKMEM(sign_counters);
2781
2782 dumparg.type = isc_statsformat_json;
2783 dumparg.arg = sign_counters;
2784 dumparg.result = ISC_R_SUCCESS;
2785 dns_dnssecsignstats_dump(
2786 dnssecsignstats, dns_dnssecsignstats_sign,
2787 dnssecsignstat_dump, &dumparg, 0);
2788 if (dumparg.result != ISC_R_SUCCESS) {
2789 json_object_put(sign_counters);
2790 goto error;
2791 }
2792
2793 if (json_object_get_object(sign_counters)->count != 0) {
2794 json_object_object_add(zoneobj, "dnssec-sign",
2795 sign_counters);
2796 } else {
2797 json_object_put(sign_counters);
2798 }
2799
2800 json_object *refresh_counters =
2801 json_object_new_object();
2802 CHECKMEM(refresh_counters);
2803
2804 dumparg.type = isc_statsformat_json;
2805 dumparg.arg = refresh_counters;
2806 dumparg.result = ISC_R_SUCCESS;
2807 dns_dnssecsignstats_dump(
2808 dnssecsignstats, dns_dnssecsignstats_refresh,
2809 dnssecsignstat_dump, &dumparg, 0);
2810 if (dumparg.result != ISC_R_SUCCESS) {
2811 json_object_put(refresh_counters);
2812 goto error;
2813 }
2814
2815 if (json_object_get_object(refresh_counters)->count !=
2816 0) {
2817 json_object_object_add(zoneobj,
2818 "dnssec-refresh",
2819 refresh_counters);
2820 } else {
2821 json_object_put(refresh_counters);
2822 }
2823 }
2824 }
2825
2826 json_object_array_add(zonearray, zoneobj);
2827 zoneobj = NULL;
2828 result = ISC_R_SUCCESS;
2829
2830 error:
2831 if (zoneobj != NULL) {
2832 json_object_put(zoneobj);
2833 }
2834 return (result);
2835 }
2836
2837 static isc_result_t
generatejson(named_server_t * server,size_t * msglen,const char ** msg,json_object ** rootp,uint32_t flags)2838 generatejson(named_server_t *server, size_t *msglen, const char **msg,
2839 json_object **rootp, uint32_t flags) {
2840 dns_view_t *view;
2841 isc_result_t result = ISC_R_SUCCESS;
2842 json_object *bindstats, *viewlist, *counters, *obj;
2843 json_object *traffic = NULL;
2844 json_object *udpreq4 = NULL, *udpresp4 = NULL;
2845 json_object *tcpreq4 = NULL, *tcpresp4 = NULL;
2846 json_object *udpreq6 = NULL, *udpresp6 = NULL;
2847 json_object *tcpreq6 = NULL, *tcpresp6 = NULL;
2848 uint64_t nsstat_values[ns_statscounter_max];
2849 uint64_t resstat_values[dns_resstatscounter_max];
2850 uint64_t adbstat_values[dns_adbstats_max];
2851 uint64_t zonestat_values[dns_zonestatscounter_max];
2852 uint64_t sockstat_values[isc_sockstatscounter_max];
2853 uint64_t udpinsizestat_values[dns_sizecounter_in_max];
2854 uint64_t udpoutsizestat_values[dns_sizecounter_out_max];
2855 uint64_t tcpinsizestat_values[dns_sizecounter_in_max];
2856 uint64_t tcpoutsizestat_values[dns_sizecounter_out_max];
2857 #ifdef HAVE_DNSTAP
2858 uint64_t dnstapstat_values[dns_dnstapcounter_max];
2859 #endif /* ifdef HAVE_DNSTAP */
2860 stats_dumparg_t dumparg;
2861 char boottime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
2862 char configtime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
2863 char nowstr[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
2864 isc_time_t now;
2865
2866 REQUIRE(msglen != NULL);
2867 REQUIRE(msg != NULL && *msg == NULL);
2868 REQUIRE(rootp == NULL || *rootp == NULL);
2869
2870 bindstats = json_object_new_object();
2871 if (bindstats == NULL) {
2872 return (ISC_R_NOMEMORY);
2873 }
2874
2875 /*
2876 * These statistics are included no matter which URL we use.
2877 */
2878 obj = json_object_new_string("1.5");
2879 CHECKMEM(obj);
2880 json_object_object_add(bindstats, "json-stats-version", obj);
2881
2882 isc_time_now(&now);
2883 isc_time_formatISO8601ms(&named_g_boottime, boottime, sizeof(boottime));
2884 isc_time_formatISO8601ms(&named_g_configtime, configtime,
2885 sizeof configtime);
2886 isc_time_formatISO8601ms(&now, nowstr, sizeof(nowstr));
2887
2888 obj = json_object_new_string(boottime);
2889 CHECKMEM(obj);
2890 json_object_object_add(bindstats, "boot-time", obj);
2891
2892 obj = json_object_new_string(configtime);
2893 CHECKMEM(obj);
2894 json_object_object_add(bindstats, "config-time", obj);
2895
2896 obj = json_object_new_string(nowstr);
2897 CHECKMEM(obj);
2898 json_object_object_add(bindstats, "current-time", obj);
2899 obj = json_object_new_string(named_g_version);
2900 CHECKMEM(obj);
2901 json_object_object_add(bindstats, "version", obj);
2902
2903 if ((flags & STATS_JSON_SERVER) != 0) {
2904 /* OPCODE counters */
2905 counters = json_object_new_object();
2906
2907 dumparg.result = ISC_R_SUCCESS;
2908 dumparg.type = isc_statsformat_json;
2909 dumparg.arg = counters;
2910
2911 dns_opcodestats_dump(server->sctx->opcodestats, opcodestat_dump,
2912 &dumparg, ISC_STATSDUMP_VERBOSE);
2913 if (dumparg.result != ISC_R_SUCCESS) {
2914 json_object_put(counters);
2915 goto error;
2916 }
2917
2918 if (json_object_get_object(counters)->count != 0) {
2919 json_object_object_add(bindstats, "opcodes", counters);
2920 } else {
2921 json_object_put(counters);
2922 }
2923
2924 /* OPCODE counters */
2925 counters = json_object_new_object();
2926
2927 dumparg.type = isc_statsformat_json;
2928 dumparg.arg = counters;
2929
2930 dns_rcodestats_dump(server->sctx->rcodestats, rcodestat_dump,
2931 &dumparg, ISC_STATSDUMP_VERBOSE);
2932 if (dumparg.result != ISC_R_SUCCESS) {
2933 json_object_put(counters);
2934 goto error;
2935 }
2936
2937 if (json_object_get_object(counters)->count != 0) {
2938 json_object_object_add(bindstats, "rcodes", counters);
2939 } else {
2940 json_object_put(counters);
2941 }
2942
2943 /* QTYPE counters */
2944 counters = json_object_new_object();
2945
2946 dumparg.result = ISC_R_SUCCESS;
2947 dumparg.arg = counters;
2948
2949 dns_rdatatypestats_dump(server->sctx->rcvquerystats,
2950 rdtypestat_dump, &dumparg, 0);
2951 if (dumparg.result != ISC_R_SUCCESS) {
2952 json_object_put(counters);
2953 goto error;
2954 }
2955
2956 if (json_object_get_object(counters)->count != 0) {
2957 json_object_object_add(bindstats, "qtypes", counters);
2958 } else {
2959 json_object_put(counters);
2960 }
2961
2962 /* server stat counters */
2963 counters = json_object_new_object();
2964
2965 dumparg.result = ISC_R_SUCCESS;
2966 dumparg.arg = counters;
2967
2968 result = dump_counters(ns_stats_get(server->sctx->nsstats),
2969 isc_statsformat_json, counters, NULL,
2970 nsstats_xmldesc, ns_statscounter_max,
2971 nsstats_index, nsstat_values, 0);
2972 if (result != ISC_R_SUCCESS) {
2973 json_object_put(counters);
2974 goto error;
2975 }
2976
2977 if (json_object_get_object(counters)->count != 0) {
2978 json_object_object_add(bindstats, "nsstats", counters);
2979 } else {
2980 json_object_put(counters);
2981 }
2982
2983 /* zone stat counters */
2984 counters = json_object_new_object();
2985
2986 dumparg.result = ISC_R_SUCCESS;
2987 dumparg.arg = counters;
2988
2989 result = dump_counters(server->zonestats, isc_statsformat_json,
2990 counters, NULL, zonestats_xmldesc,
2991 dns_zonestatscounter_max,
2992 zonestats_index, zonestat_values, 0);
2993 if (result != ISC_R_SUCCESS) {
2994 json_object_put(counters);
2995 goto error;
2996 }
2997
2998 if (json_object_get_object(counters)->count != 0) {
2999 json_object_object_add(bindstats, "zonestats",
3000 counters);
3001 } else {
3002 json_object_put(counters);
3003 }
3004
3005 /* resolver stat counters */
3006 counters = json_object_new_object();
3007
3008 dumparg.result = ISC_R_SUCCESS;
3009 dumparg.arg = counters;
3010
3011 result = dump_counters(
3012 server->resolverstats, isc_statsformat_json, counters,
3013 NULL, resstats_xmldesc, dns_resstatscounter_max,
3014 resstats_index, resstat_values, 0);
3015 if (result != ISC_R_SUCCESS) {
3016 json_object_put(counters);
3017 goto error;
3018 }
3019
3020 if (json_object_get_object(counters)->count != 0) {
3021 json_object_object_add(bindstats, "resstats", counters);
3022 } else {
3023 json_object_put(counters);
3024 }
3025
3026 #ifdef HAVE_DNSTAP
3027 /* dnstap stat counters */
3028 if (named_g_server->dtenv != NULL) {
3029 isc_stats_t *dnstapstats = NULL;
3030 dns_dt_getstats(named_g_server->dtenv, &dnstapstats);
3031 counters = json_object_new_object();
3032 dumparg.result = ISC_R_SUCCESS;
3033 dumparg.arg = counters;
3034 result = dump_counters(
3035 dnstapstats, isc_statsformat_json, counters,
3036 NULL, dnstapstats_xmldesc,
3037 dns_dnstapcounter_max, dnstapstats_index,
3038 dnstapstat_values, 0);
3039 isc_stats_detach(&dnstapstats);
3040 if (result != ISC_R_SUCCESS) {
3041 json_object_put(counters);
3042 goto error;
3043 }
3044
3045 if (json_object_get_object(counters)->count != 0) {
3046 json_object_object_add(bindstats, "dnstapstats",
3047 counters);
3048 } else {
3049 json_object_put(counters);
3050 }
3051 }
3052 #endif /* ifdef HAVE_DNSTAP */
3053 }
3054
3055 if ((flags & (STATS_JSON_ZONES | STATS_JSON_SERVER)) != 0) {
3056 viewlist = json_object_new_object();
3057 CHECKMEM(viewlist);
3058
3059 json_object_object_add(bindstats, "views", viewlist);
3060
3061 view = ISC_LIST_HEAD(server->viewlist);
3062 while (view != NULL) {
3063 json_object *za, *v = json_object_new_object();
3064
3065 CHECKMEM(v);
3066 json_object_object_add(viewlist, view->name, v);
3067
3068 za = json_object_new_array();
3069 CHECKMEM(za);
3070
3071 if ((flags & STATS_JSON_ZONES) != 0) {
3072 result = dns_zt_apply(view->zonetable, true,
3073 NULL, zone_jsonrender,
3074 za);
3075 if (result != ISC_R_SUCCESS) {
3076 goto error;
3077 }
3078 }
3079
3080 if (json_object_array_length(za) != 0) {
3081 json_object_object_add(v, "zones", za);
3082 } else {
3083 json_object_put(za);
3084 }
3085
3086 if ((flags & STATS_JSON_SERVER) != 0) {
3087 json_object *res;
3088 dns_stats_t *dstats;
3089 isc_stats_t *istats;
3090
3091 res = json_object_new_object();
3092 CHECKMEM(res);
3093 json_object_object_add(v, "resolver", res);
3094
3095 istats = view->resstats;
3096 if (istats != NULL) {
3097 counters = json_object_new_object();
3098 CHECKMEM(counters);
3099
3100 result = dump_counters(
3101 istats, isc_statsformat_json,
3102 counters, NULL,
3103 resstats_xmldesc,
3104 dns_resstatscounter_max,
3105 resstats_index, resstat_values,
3106 0);
3107 if (result != ISC_R_SUCCESS) {
3108 json_object_put(counters);
3109 result = dumparg.result;
3110 goto error;
3111 }
3112
3113 json_object_object_add(res, "stats",
3114 counters);
3115 }
3116
3117 dstats = view->resquerystats;
3118 if (dstats != NULL) {
3119 counters = json_object_new_object();
3120 CHECKMEM(counters);
3121
3122 dumparg.arg = counters;
3123 dumparg.result = ISC_R_SUCCESS;
3124 dns_rdatatypestats_dump(dstats,
3125 rdtypestat_dump,
3126 &dumparg, 0);
3127 if (dumparg.result != ISC_R_SUCCESS) {
3128 json_object_put(counters);
3129 result = dumparg.result;
3130 goto error;
3131 }
3132
3133 json_object_object_add(res, "qtypes",
3134 counters);
3135 }
3136
3137 dstats = dns_db_getrrsetstats(view->cachedb);
3138 if (dstats != NULL) {
3139 counters = json_object_new_object();
3140 CHECKMEM(counters);
3141
3142 dumparg.arg = counters;
3143 dumparg.result = ISC_R_SUCCESS;
3144 dns_rdatasetstats_dump(
3145 dstats, rdatasetstats_dump,
3146 &dumparg, 0);
3147 if (dumparg.result != ISC_R_SUCCESS) {
3148 json_object_put(counters);
3149 result = dumparg.result;
3150 goto error;
3151 }
3152
3153 json_object_object_add(res, "cache",
3154 counters);
3155 }
3156
3157 counters = json_object_new_object();
3158 CHECKMEM(counters);
3159
3160 result = dns_cache_renderjson(view->cache,
3161 counters);
3162 if (result != ISC_R_SUCCESS) {
3163 json_object_put(counters);
3164 goto error;
3165 }
3166
3167 json_object_object_add(res, "cachestats",
3168 counters);
3169
3170 istats = view->adbstats;
3171 if (istats != NULL) {
3172 counters = json_object_new_object();
3173 CHECKMEM(counters);
3174
3175 result = dump_counters(
3176 istats, isc_statsformat_json,
3177 counters, NULL,
3178 adbstats_xmldesc,
3179 dns_adbstats_max,
3180 adbstats_index, adbstat_values,
3181 0);
3182 if (result != ISC_R_SUCCESS) {
3183 json_object_put(counters);
3184 result = dumparg.result;
3185 goto error;
3186 }
3187
3188 json_object_object_add(res, "adb",
3189 counters);
3190 }
3191 }
3192
3193 view = ISC_LIST_NEXT(view, link);
3194 }
3195 }
3196
3197 if ((flags & STATS_JSON_NET) != 0) {
3198 /* socket stat counters */
3199 json_object *sockets;
3200 counters = json_object_new_object();
3201
3202 dumparg.result = ISC_R_SUCCESS;
3203 dumparg.arg = counters;
3204
3205 result = dump_counters(server->sockstats, isc_statsformat_json,
3206 counters, NULL, sockstats_xmldesc,
3207 isc_sockstatscounter_max,
3208 sockstats_index, sockstat_values, 0);
3209 if (result != ISC_R_SUCCESS) {
3210 json_object_put(counters);
3211 goto error;
3212 }
3213
3214 if (json_object_get_object(counters)->count != 0) {
3215 json_object_object_add(bindstats, "sockstats",
3216 counters);
3217 } else {
3218 json_object_put(counters);
3219 }
3220
3221 sockets = json_object_new_object();
3222 CHECKMEM(sockets);
3223
3224 result = isc_socketmgr_renderjson(named_g_socketmgr, sockets);
3225 if (result != ISC_R_SUCCESS) {
3226 json_object_put(sockets);
3227 goto error;
3228 }
3229
3230 json_object_object_add(bindstats, "socketmgr", sockets);
3231 }
3232
3233 if ((flags & STATS_JSON_TASKS) != 0) {
3234 json_object *tasks = json_object_new_object();
3235 CHECKMEM(tasks);
3236
3237 result = isc_taskmgr_renderjson(named_g_taskmgr, tasks);
3238 if (result != ISC_R_SUCCESS) {
3239 json_object_put(tasks);
3240 goto error;
3241 }
3242
3243 json_object_object_add(bindstats, "taskmgr", tasks);
3244 }
3245
3246 if ((flags & STATS_JSON_MEM) != 0) {
3247 json_object *memory = json_object_new_object();
3248 CHECKMEM(memory);
3249
3250 result = isc_mem_renderjson(memory);
3251 if (result != ISC_R_SUCCESS) {
3252 json_object_put(memory);
3253 goto error;
3254 }
3255
3256 json_object_object_add(bindstats, "memory", memory);
3257 }
3258
3259 if ((flags & STATS_JSON_TRAFFIC) != 0) {
3260 traffic = json_object_new_object();
3261 CHECKMEM(traffic);
3262
3263 udpreq4 = json_object_new_object();
3264 CHECKMEM(udpreq4);
3265
3266 udpresp4 = json_object_new_object();
3267 CHECKMEM(udpresp4);
3268
3269 tcpreq4 = json_object_new_object();
3270 CHECKMEM(tcpreq4);
3271
3272 tcpresp4 = json_object_new_object();
3273 CHECKMEM(tcpresp4);
3274
3275 udpreq6 = json_object_new_object();
3276 CHECKMEM(udpreq6);
3277
3278 udpresp6 = json_object_new_object();
3279 CHECKMEM(udpresp6);
3280
3281 tcpreq6 = json_object_new_object();
3282 CHECKMEM(tcpreq6);
3283
3284 tcpresp6 = json_object_new_object();
3285 CHECKMEM(tcpresp6);
3286
3287 CHECK(dump_counters(
3288 server->sctx->udpinstats4, isc_statsformat_json,
3289 udpreq4, NULL, udpinsizestats_xmldesc,
3290 dns_sizecounter_in_max, udpinsizestats_index,
3291 udpinsizestat_values, 0));
3292
3293 CHECK(dump_counters(
3294 server->sctx->udpoutstats4, isc_statsformat_json,
3295 udpresp4, NULL, udpoutsizestats_xmldesc,
3296 dns_sizecounter_out_max, udpoutsizestats_index,
3297 udpoutsizestat_values, 0));
3298
3299 CHECK(dump_counters(
3300 server->sctx->tcpinstats4, isc_statsformat_json,
3301 tcpreq4, NULL, tcpinsizestats_xmldesc,
3302 dns_sizecounter_in_max, tcpinsizestats_index,
3303 tcpinsizestat_values, 0));
3304
3305 CHECK(dump_counters(
3306 server->sctx->tcpoutstats4, isc_statsformat_json,
3307 tcpresp4, NULL, tcpoutsizestats_xmldesc,
3308 dns_sizecounter_out_max, tcpoutsizestats_index,
3309 tcpoutsizestat_values, 0));
3310
3311 CHECK(dump_counters(
3312 server->sctx->udpinstats6, isc_statsformat_json,
3313 udpreq6, NULL, udpinsizestats_xmldesc,
3314 dns_sizecounter_in_max, udpinsizestats_index,
3315 udpinsizestat_values, 0));
3316
3317 CHECK(dump_counters(
3318 server->sctx->udpoutstats6, isc_statsformat_json,
3319 udpresp6, NULL, udpoutsizestats_xmldesc,
3320 dns_sizecounter_out_max, udpoutsizestats_index,
3321 udpoutsizestat_values, 0));
3322
3323 CHECK(dump_counters(
3324 server->sctx->tcpinstats6, isc_statsformat_json,
3325 tcpreq6, NULL, tcpinsizestats_xmldesc,
3326 dns_sizecounter_in_max, tcpinsizestats_index,
3327 tcpinsizestat_values, 0));
3328
3329 CHECK(dump_counters(
3330 server->sctx->tcpoutstats6, isc_statsformat_json,
3331 tcpresp6, NULL, tcpoutsizestats_xmldesc,
3332 dns_sizecounter_out_max, tcpoutsizestats_index,
3333 tcpoutsizestat_values, 0));
3334
3335 json_object_object_add(traffic,
3336 "dns-udp-requests-sizes-received-ipv4",
3337 udpreq4);
3338 json_object_object_add(
3339 traffic, "dns-udp-responses-sizes-sent-ipv4", udpresp4);
3340 json_object_object_add(traffic,
3341 "dns-tcp-requests-sizes-received-ipv4",
3342 tcpreq4);
3343 json_object_object_add(
3344 traffic, "dns-tcp-responses-sizes-sent-ipv4", tcpresp4);
3345 json_object_object_add(traffic,
3346 "dns-udp-requests-sizes-received-ipv6",
3347 udpreq6);
3348 json_object_object_add(
3349 traffic, "dns-udp-responses-sizes-sent-ipv6", udpresp6);
3350 json_object_object_add(traffic,
3351 "dns-tcp-requests-sizes-received-ipv6",
3352 tcpreq6);
3353 json_object_object_add(
3354 traffic, "dns-tcp-responses-sizes-sent-ipv6", tcpresp6);
3355 json_object_object_add(bindstats, "traffic", traffic);
3356 udpreq4 = NULL;
3357 udpresp4 = NULL;
3358 tcpreq4 = NULL;
3359 tcpresp4 = NULL;
3360 udpreq6 = NULL;
3361 udpresp6 = NULL;
3362 tcpreq6 = NULL;
3363 tcpresp6 = NULL;
3364 traffic = NULL;
3365 }
3366
3367 *msg = json_object_to_json_string_ext(bindstats,
3368 JSON_C_TO_STRING_PRETTY);
3369 *msglen = strlen(*msg);
3370
3371 if (rootp != NULL) {
3372 *rootp = bindstats;
3373 bindstats = NULL;
3374 }
3375
3376 result = ISC_R_SUCCESS;
3377
3378 error:
3379 if (udpreq4 != NULL) {
3380 json_object_put(udpreq4);
3381 }
3382 if (udpresp4 != NULL) {
3383 json_object_put(udpresp4);
3384 }
3385 if (tcpreq4 != NULL) {
3386 json_object_put(tcpreq4);
3387 }
3388 if (tcpresp4 != NULL) {
3389 json_object_put(tcpresp4);
3390 }
3391 if (udpreq6 != NULL) {
3392 json_object_put(udpreq6);
3393 }
3394 if (udpresp6 != NULL) {
3395 json_object_put(udpresp6);
3396 }
3397 if (tcpreq6 != NULL) {
3398 json_object_put(tcpreq6);
3399 }
3400 if (tcpresp6 != NULL) {
3401 json_object_put(tcpresp6);
3402 }
3403 if (traffic != NULL) {
3404 json_object_put(traffic);
3405 }
3406 if (bindstats != NULL) {
3407 json_object_put(bindstats);
3408 }
3409
3410 return (result);
3411 }
3412
3413 static isc_result_t
render_json(uint32_t flags,const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)3414 render_json(uint32_t flags, const char *url, isc_httpdurl_t *urlinfo,
3415 const char *querystring, const char *headers, void *arg,
3416 unsigned int *retcode, const char **retmsg, const char **mimetype,
3417 isc_buffer_t *b, isc_httpdfree_t **freecb, void **freecb_args) {
3418 isc_result_t result;
3419 json_object *bindstats = NULL;
3420 named_server_t *server = arg;
3421 const char *msg = NULL;
3422 size_t msglen = 0;
3423 char *p;
3424
3425 UNUSED(url);
3426 UNUSED(urlinfo);
3427 UNUSED(headers);
3428 UNUSED(querystring);
3429
3430 result = generatejson(server, &msglen, &msg, &bindstats, flags);
3431 if (result == ISC_R_SUCCESS) {
3432 *retcode = 200;
3433 *retmsg = "OK";
3434 *mimetype = "application/json";
3435 DE_CONST(msg, p);
3436 isc_buffer_reinit(b, p, msglen);
3437 isc_buffer_add(b, msglen);
3438 *freecb = wrap_jsonfree;
3439 *freecb_args = bindstats;
3440 } else {
3441 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
3442 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
3443 "failed at rendering JSON()");
3444 }
3445
3446 return (result);
3447 }
3448
3449 static isc_result_t
render_json_all(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)3450 render_json_all(const char *url, isc_httpdurl_t *urlinfo,
3451 const char *querystring, const char *headers, void *arg,
3452 unsigned int *retcode, const char **retmsg,
3453 const char **mimetype, isc_buffer_t *b,
3454 isc_httpdfree_t **freecb, void **freecb_args) {
3455 return (render_json(STATS_JSON_ALL, url, urlinfo, querystring, headers,
3456 arg, retcode, retmsg, mimetype, b, freecb,
3457 freecb_args));
3458 }
3459
3460 static isc_result_t
render_json_status(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)3461 render_json_status(const char *url, isc_httpdurl_t *urlinfo,
3462 const char *querystring, const char *headers, void *arg,
3463 unsigned int *retcode, const char **retmsg,
3464 const char **mimetype, isc_buffer_t *b,
3465 isc_httpdfree_t **freecb, void **freecb_args) {
3466 return (render_json(STATS_JSON_STATUS, url, urlinfo, querystring,
3467 headers, arg, retcode, retmsg, mimetype, b, freecb,
3468 freecb_args));
3469 }
3470
3471 static isc_result_t
render_json_server(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)3472 render_json_server(const char *url, isc_httpdurl_t *urlinfo,
3473 const char *querystring, const char *headers, void *arg,
3474 unsigned int *retcode, const char **retmsg,
3475 const char **mimetype, isc_buffer_t *b,
3476 isc_httpdfree_t **freecb, void **freecb_args) {
3477 return (render_json(STATS_JSON_SERVER, url, urlinfo, querystring,
3478 headers, arg, retcode, retmsg, mimetype, b, freecb,
3479 freecb_args));
3480 }
3481
3482 static isc_result_t
render_json_zones(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)3483 render_json_zones(const char *url, isc_httpdurl_t *urlinfo,
3484 const char *querystring, const char *headers, void *arg,
3485 unsigned int *retcode, const char **retmsg,
3486 const char **mimetype, isc_buffer_t *b,
3487 isc_httpdfree_t **freecb, void **freecb_args) {
3488 return (render_json(STATS_JSON_ZONES, url, urlinfo, querystring,
3489 headers, arg, retcode, retmsg, mimetype, b, freecb,
3490 freecb_args));
3491 }
3492
3493 static isc_result_t
render_json_mem(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)3494 render_json_mem(const char *url, isc_httpdurl_t *urlinfo,
3495 const char *querystring, const char *headers, void *arg,
3496 unsigned int *retcode, const char **retmsg,
3497 const char **mimetype, isc_buffer_t *b,
3498 isc_httpdfree_t **freecb, void **freecb_args) {
3499 return (render_json(STATS_JSON_MEM, url, urlinfo, querystring, headers,
3500 arg, retcode, retmsg, mimetype, b, freecb,
3501 freecb_args));
3502 }
3503
3504 static isc_result_t
render_json_tasks(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)3505 render_json_tasks(const char *url, isc_httpdurl_t *urlinfo,
3506 const char *querystring, const char *headers, void *arg,
3507 unsigned int *retcode, const char **retmsg,
3508 const char **mimetype, isc_buffer_t *b,
3509 isc_httpdfree_t **freecb, void **freecb_args) {
3510 return (render_json(STATS_JSON_TASKS, url, urlinfo, querystring,
3511 headers, arg, retcode, retmsg, mimetype, b, freecb,
3512 freecb_args));
3513 }
3514
3515 static isc_result_t
render_json_net(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)3516 render_json_net(const char *url, isc_httpdurl_t *urlinfo,
3517 const char *querystring, const char *headers, void *arg,
3518 unsigned int *retcode, const char **retmsg,
3519 const char **mimetype, isc_buffer_t *b,
3520 isc_httpdfree_t **freecb, void **freecb_args) {
3521 return (render_json(STATS_JSON_NET, url, urlinfo, querystring, headers,
3522 arg, retcode, retmsg, mimetype, b, freecb,
3523 freecb_args));
3524 }
3525
3526 static isc_result_t
render_json_traffic(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * arg,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)3527 render_json_traffic(const char *url, isc_httpdurl_t *urlinfo,
3528 const char *querystring, const char *headers, void *arg,
3529 unsigned int *retcode, const char **retmsg,
3530 const char **mimetype, isc_buffer_t *b,
3531 isc_httpdfree_t **freecb, void **freecb_args) {
3532 return (render_json(STATS_JSON_TRAFFIC, url, urlinfo, querystring,
3533 headers, arg, retcode, retmsg, mimetype, b, freecb,
3534 freecb_args));
3535 }
3536
3537 #endif /* HAVE_JSON_C */
3538
3539 static isc_result_t
render_xsl(const char * url,isc_httpdurl_t * urlinfo,const char * querystring,const char * headers,void * args,unsigned int * retcode,const char ** retmsg,const char ** mimetype,isc_buffer_t * b,isc_httpdfree_t ** freecb,void ** freecb_args)3540 render_xsl(const char *url, isc_httpdurl_t *urlinfo, const char *querystring,
3541 const char *headers, void *args, unsigned int *retcode,
3542 const char **retmsg, const char **mimetype, isc_buffer_t *b,
3543 isc_httpdfree_t **freecb, void **freecb_args) {
3544 isc_result_t result;
3545 char *_headers = NULL;
3546
3547 UNUSED(url);
3548 UNUSED(querystring);
3549 UNUSED(args);
3550
3551 *freecb = NULL;
3552 *freecb_args = NULL;
3553 *mimetype = "text/xslt+xml";
3554
3555 if (urlinfo->isstatic) {
3556 isc_time_t when;
3557 char *line, *saveptr;
3558 const char *if_modified_since = "If-Modified-Since: ";
3559 _headers = strdup(headers);
3560
3561 if (_headers == NULL) {
3562 goto send;
3563 }
3564
3565 saveptr = NULL;
3566 for (line = strtok_r(_headers, "\n", &saveptr); line;
3567 line = strtok_r(NULL, "\n", &saveptr))
3568 {
3569 if (strncasecmp(line, if_modified_since,
3570 strlen(if_modified_since)) == 0) {
3571 time_t t1, t2;
3572 line += strlen(if_modified_since);
3573 result = isc_time_parsehttptimestamp(line,
3574 &when);
3575 if (result != ISC_R_SUCCESS) {
3576 goto send;
3577 }
3578
3579 result = isc_time_secondsastimet(&when, &t1);
3580 if (result != ISC_R_SUCCESS) {
3581 goto send;
3582 }
3583
3584 result = isc_time_secondsastimet(
3585 &urlinfo->loadtime, &t2);
3586 if (result != ISC_R_SUCCESS) {
3587 goto send;
3588 }
3589
3590 if (t1 < t2) {
3591 goto send;
3592 }
3593
3594 *retcode = 304;
3595 *retmsg = "Not modified";
3596 goto end;
3597 }
3598 }
3599 }
3600
3601 send:
3602 *retcode = 200;
3603 *retmsg = "OK";
3604 isc_buffer_reinit(b, xslmsg, strlen(xslmsg));
3605 isc_buffer_add(b, strlen(xslmsg));
3606 end:
3607 free(_headers);
3608 return (ISC_R_SUCCESS);
3609 }
3610
3611 static void
shutdown_listener(named_statschannel_t * listener)3612 shutdown_listener(named_statschannel_t *listener) {
3613 char socktext[ISC_SOCKADDR_FORMATSIZE];
3614 isc_sockaddr_format(&listener->address, socktext, sizeof(socktext));
3615 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
3616 NAMED_LOGMODULE_SERVER, ISC_LOG_NOTICE,
3617 "stopping statistics channel on %s", socktext);
3618
3619 isc_httpdmgr_shutdown(&listener->httpdmgr);
3620 }
3621
3622 static bool
client_ok(const isc_sockaddr_t * fromaddr,void * arg)3623 client_ok(const isc_sockaddr_t *fromaddr, void *arg) {
3624 named_statschannel_t *listener = arg;
3625 dns_aclenv_t *env =
3626 ns_interfacemgr_getaclenv(named_g_server->interfacemgr);
3627 isc_netaddr_t netaddr;
3628 char socktext[ISC_SOCKADDR_FORMATSIZE];
3629 int match;
3630
3631 REQUIRE(listener != NULL);
3632
3633 isc_netaddr_fromsockaddr(&netaddr, fromaddr);
3634
3635 LOCK(&listener->lock);
3636 if ((dns_acl_match(&netaddr, NULL, listener->acl, env, &match, NULL) ==
3637 ISC_R_SUCCESS) &&
3638 match > 0)
3639 {
3640 UNLOCK(&listener->lock);
3641 return (true);
3642 }
3643 UNLOCK(&listener->lock);
3644
3645 isc_sockaddr_format(fromaddr, socktext, sizeof(socktext));
3646 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
3647 NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
3648 "rejected statistics connection from %s", socktext);
3649
3650 return (false);
3651 }
3652
3653 static void
destroy_listener(void * arg)3654 destroy_listener(void *arg) {
3655 named_statschannel_t *listener = arg;
3656
3657 REQUIRE(listener != NULL);
3658 REQUIRE(!ISC_LINK_LINKED(listener, link));
3659
3660 /* We don't have to acquire the lock here since it's already unlinked */
3661 dns_acl_detach(&listener->acl);
3662
3663 isc_mutex_destroy(&listener->lock);
3664 isc_mem_putanddetach(&listener->mctx, listener, sizeof(*listener));
3665 }
3666
3667 static isc_result_t
add_listener(named_server_t * server,named_statschannel_t ** listenerp,const cfg_obj_t * listen_params,const cfg_obj_t * config,isc_sockaddr_t * addr,cfg_aclconfctx_t * aclconfctx,const char * socktext)3668 add_listener(named_server_t *server, named_statschannel_t **listenerp,
3669 const cfg_obj_t *listen_params, const cfg_obj_t *config,
3670 isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx,
3671 const char *socktext) {
3672 isc_result_t result;
3673 named_statschannel_t *listener;
3674 isc_task_t *task = NULL;
3675 isc_socket_t *sock = NULL;
3676 const cfg_obj_t *allow;
3677 dns_acl_t *new_acl = NULL;
3678
3679 listener = isc_mem_get(server->mctx, sizeof(*listener));
3680
3681 listener->httpdmgr = NULL;
3682 listener->address = *addr;
3683 listener->acl = NULL;
3684 listener->mctx = NULL;
3685 ISC_LINK_INIT(listener, link);
3686
3687 isc_mutex_init(&listener->lock);
3688
3689 isc_mem_attach(server->mctx, &listener->mctx);
3690
3691 allow = cfg_tuple_get(listen_params, "allow");
3692 if (allow != NULL && cfg_obj_islist(allow)) {
3693 result = cfg_acl_fromconfig(allow, config, named_g_lctx,
3694 aclconfctx, listener->mctx, 0,
3695 &new_acl);
3696 } else {
3697 result = dns_acl_any(listener->mctx, &new_acl);
3698 }
3699 if (result != ISC_R_SUCCESS) {
3700 goto cleanup;
3701 }
3702 dns_acl_attach(new_acl, &listener->acl);
3703 dns_acl_detach(&new_acl);
3704
3705 result = isc_task_create(named_g_taskmgr, 0, &task);
3706 if (result != ISC_R_SUCCESS) {
3707 goto cleanup;
3708 }
3709 isc_task_setname(task, "statchannel", NULL);
3710
3711 result = isc_socket_create(named_g_socketmgr, isc_sockaddr_pf(addr),
3712 isc_sockettype_tcp, &sock);
3713 if (result != ISC_R_SUCCESS) {
3714 goto cleanup;
3715 }
3716 isc_socket_setname(sock, "statchannel", NULL);
3717
3718 #ifndef ISC_ALLOW_MAPPED
3719 isc_socket_ipv6only(sock, true);
3720 #endif /* ifndef ISC_ALLOW_MAPPED */
3721
3722 result = isc_socket_bind(sock, addr, ISC_SOCKET_REUSEADDRESS);
3723 if (result != ISC_R_SUCCESS) {
3724 goto cleanup;
3725 }
3726
3727 result = isc_httpdmgr_create(server->mctx, sock, task, client_ok,
3728 destroy_listener, listener,
3729 named_g_timermgr, &listener->httpdmgr);
3730 if (result != ISC_R_SUCCESS) {
3731 goto cleanup;
3732 }
3733
3734 #ifdef HAVE_LIBXML2
3735 isc_httpdmgr_addurl(listener->httpdmgr, "/", render_xml_all, server);
3736 isc_httpdmgr_addurl(listener->httpdmgr, "/xml", render_xml_all, server);
3737 isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3", render_xml_all,
3738 server);
3739 isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/status",
3740 render_xml_status, server);
3741 isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/server",
3742 render_xml_server, server);
3743 isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/zones",
3744 render_xml_zones, server);
3745 isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/net", render_xml_net,
3746 server);
3747 isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/tasks",
3748 render_xml_tasks, server);
3749 isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/mem", render_xml_mem,
3750 server);
3751 isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3/traffic",
3752 render_xml_traffic, server);
3753 #endif /* ifdef HAVE_LIBXML2 */
3754 #ifdef HAVE_JSON_C
3755 isc_httpdmgr_addurl(listener->httpdmgr, "/json", render_json_all,
3756 server);
3757 isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1", render_json_all,
3758 server);
3759 isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/status",
3760 render_json_status, server);
3761 isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/server",
3762 render_json_server, server);
3763 isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/zones",
3764 render_json_zones, server);
3765 isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/tasks",
3766 render_json_tasks, server);
3767 isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/net", render_json_net,
3768 server);
3769 isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/mem", render_json_mem,
3770 server);
3771 isc_httpdmgr_addurl(listener->httpdmgr, "/json/v1/traffic",
3772 render_json_traffic, server);
3773 #endif /* ifdef HAVE_JSON_C */
3774 isc_httpdmgr_addurl2(listener->httpdmgr, "/bind9.xsl", true, render_xsl,
3775 server);
3776
3777 *listenerp = listener;
3778 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
3779 NAMED_LOGMODULE_SERVER, ISC_LOG_NOTICE,
3780 "statistics channel listening on %s", socktext);
3781
3782 cleanup:
3783 if (result != ISC_R_SUCCESS) {
3784 if (listener->acl != NULL) {
3785 dns_acl_detach(&listener->acl);
3786 }
3787 isc_mutex_destroy(&listener->lock);
3788 isc_mem_putanddetach(&listener->mctx, listener,
3789 sizeof(*listener));
3790 }
3791 if (task != NULL) {
3792 isc_task_detach(&task);
3793 }
3794 if (sock != NULL) {
3795 isc_socket_detach(&sock);
3796 }
3797
3798 return (result);
3799 }
3800
3801 static void
update_listener(named_server_t * server,named_statschannel_t ** listenerp,const cfg_obj_t * listen_params,const cfg_obj_t * config,isc_sockaddr_t * addr,cfg_aclconfctx_t * aclconfctx,const char * socktext)3802 update_listener(named_server_t *server, named_statschannel_t **listenerp,
3803 const cfg_obj_t *listen_params, const cfg_obj_t *config,
3804 isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx,
3805 const char *socktext) {
3806 named_statschannel_t *listener;
3807 const cfg_obj_t *allow = NULL;
3808 dns_acl_t *new_acl = NULL;
3809 isc_result_t result = ISC_R_SUCCESS;
3810
3811 for (listener = ISC_LIST_HEAD(server->statschannels); listener != NULL;
3812 listener = ISC_LIST_NEXT(listener, link))
3813 {
3814 if (isc_sockaddr_equal(addr, &listener->address)) {
3815 break;
3816 }
3817 }
3818
3819 if (listener == NULL) {
3820 *listenerp = NULL;
3821 return;
3822 }
3823
3824 /*
3825 * Now, keep the old access list unless a new one can be made.
3826 */
3827 allow = cfg_tuple_get(listen_params, "allow");
3828 if (allow != NULL && cfg_obj_islist(allow)) {
3829 result = cfg_acl_fromconfig(allow, config, named_g_lctx,
3830 aclconfctx, listener->mctx, 0,
3831 &new_acl);
3832 } else {
3833 result = dns_acl_any(listener->mctx, &new_acl);
3834 }
3835
3836 if (result == ISC_R_SUCCESS) {
3837 LOCK(&listener->lock);
3838
3839 dns_acl_detach(&listener->acl);
3840 dns_acl_attach(new_acl, &listener->acl);
3841 dns_acl_detach(&new_acl);
3842
3843 UNLOCK(&listener->lock);
3844 } else {
3845 cfg_obj_log(listen_params, named_g_lctx, ISC_LOG_WARNING,
3846 "couldn't install new acl for "
3847 "statistics channel %s: %s",
3848 socktext, isc_result_totext(result));
3849 }
3850
3851 *listenerp = listener;
3852 }
3853
3854 isc_result_t
named_statschannels_configure(named_server_t * server,const cfg_obj_t * config,cfg_aclconfctx_t * aclconfctx)3855 named_statschannels_configure(named_server_t *server, const cfg_obj_t *config,
3856 cfg_aclconfctx_t *aclconfctx) {
3857 named_statschannel_t *listener, *listener_next;
3858 named_statschannellist_t new_listeners;
3859 const cfg_obj_t *statschannellist = NULL;
3860 const cfg_listelt_t *element, *element2;
3861 char socktext[ISC_SOCKADDR_FORMATSIZE];
3862
3863 RUNTIME_CHECK(isc_once_do(&once, init_desc) == ISC_R_SUCCESS);
3864
3865 ISC_LIST_INIT(new_listeners);
3866
3867 /*
3868 * Get the list of named.conf 'statistics-channels' statements.
3869 */
3870 (void)cfg_map_get(config, "statistics-channels", &statschannellist);
3871
3872 /*
3873 * Run through the new address/port list, noting sockets that are
3874 * already being listened on and moving them to the new list.
3875 *
3876 * Identifying duplicate addr/port combinations is left to either
3877 * the underlying config code, or to the bind attempt getting an
3878 * address-in-use error.
3879 */
3880 if (statschannellist != NULL) {
3881 #ifndef EXTENDED_STATS
3882 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
3883 NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
3884 "statistics-channels specified but not effective "
3885 "due to missing XML and/or JSON library");
3886 #else /* EXTENDED_STATS */
3887 #ifndef HAVE_LIBXML2
3888 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
3889 NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
3890 "statistics-channels: XML library missing, "
3891 "only JSON stats will be available");
3892 #endif /* !HAVE_LIBXML2 */
3893 #ifndef HAVE_JSON_C
3894 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
3895 NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
3896 "statistics-channels: JSON library missing, "
3897 "only XML stats will be available");
3898 #endif /* !HAVE_JSON_C */
3899 #endif /* EXTENDED_STATS */
3900
3901 for (element = cfg_list_first(statschannellist);
3902 element != NULL; element = cfg_list_next(element))
3903 {
3904 const cfg_obj_t *statschannel;
3905 const cfg_obj_t *listenercfg = NULL;
3906
3907 statschannel = cfg_listelt_value(element);
3908 (void)cfg_map_get(statschannel, "inet", &listenercfg);
3909 if (listenercfg == NULL) {
3910 continue;
3911 }
3912
3913 for (element2 = cfg_list_first(listenercfg);
3914 element2 != NULL;
3915 element2 = cfg_list_next(element2))
3916 {
3917 const cfg_obj_t *listen_params;
3918 const cfg_obj_t *obj;
3919 isc_sockaddr_t addr;
3920
3921 listen_params = cfg_listelt_value(element2);
3922
3923 obj = cfg_tuple_get(listen_params, "address");
3924 addr = *cfg_obj_assockaddr(obj);
3925 if (isc_sockaddr_getport(&addr) == 0) {
3926 isc_sockaddr_setport(
3927 &addr,
3928 NAMED_STATSCHANNEL_HTTPPORT);
3929 }
3930
3931 isc_sockaddr_format(&addr, socktext,
3932 sizeof(socktext));
3933
3934 isc_log_write(named_g_lctx,
3935 NAMED_LOGCATEGORY_GENERAL,
3936 NAMED_LOGMODULE_SERVER,
3937 ISC_LOG_DEBUG(9),
3938 "processing statistics "
3939 "channel %s",
3940 socktext);
3941
3942 update_listener(server, &listener,
3943 listen_params, config, &addr,
3944 aclconfctx, socktext);
3945
3946 if (listener != NULL) {
3947 /*
3948 * Remove the listener from the old
3949 * list, so it won't be shut down.
3950 */
3951 ISC_LIST_UNLINK(server->statschannels,
3952 listener, link);
3953 } else {
3954 /*
3955 * This is a new listener.
3956 */
3957 isc_result_t r;
3958
3959 r = add_listener(server, &listener,
3960 listen_params, config,
3961 &addr, aclconfctx,
3962 socktext);
3963 if (r != ISC_R_SUCCESS) {
3964 cfg_obj_log(
3965 listen_params,
3966 named_g_lctx,
3967 ISC_LOG_WARNING,
3968 "couldn't allocate "
3969 "statistics channel"
3970 " %s: %s",
3971 socktext,
3972 isc_result_totext(r));
3973 }
3974 }
3975
3976 if (listener != NULL) {
3977 ISC_LIST_APPEND(new_listeners, listener,
3978 link);
3979 }
3980 }
3981 }
3982 }
3983
3984 for (listener = ISC_LIST_HEAD(server->statschannels); listener != NULL;
3985 listener = listener_next)
3986 {
3987 listener_next = ISC_LIST_NEXT(listener, link);
3988 ISC_LIST_UNLINK(server->statschannels, listener, link);
3989 shutdown_listener(listener);
3990 }
3991
3992 ISC_LIST_APPENDLIST(server->statschannels, new_listeners, link);
3993 return (ISC_R_SUCCESS);
3994 }
3995
3996 void
named_statschannels_shutdown(named_server_t * server)3997 named_statschannels_shutdown(named_server_t *server) {
3998 named_statschannel_t *listener;
3999
4000 while ((listener = ISC_LIST_HEAD(server->statschannels)) != NULL) {
4001 ISC_LIST_UNLINK(server->statschannels, listener, link);
4002 shutdown_listener(listener);
4003 }
4004 }
4005
4006 isc_result_t
named_stats_dump(named_server_t * server,FILE * fp)4007 named_stats_dump(named_server_t *server, FILE *fp) {
4008 isc_stdtime_t now;
4009 isc_result_t result;
4010 dns_view_t *view;
4011 dns_zone_t *zone, *next;
4012 stats_dumparg_t dumparg;
4013 uint64_t nsstat_values[ns_statscounter_max];
4014 uint64_t resstat_values[dns_resstatscounter_max];
4015 uint64_t adbstat_values[dns_adbstats_max];
4016 uint64_t zonestat_values[dns_zonestatscounter_max];
4017 uint64_t sockstat_values[isc_sockstatscounter_max];
4018 uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
4019
4020 RUNTIME_CHECK(isc_once_do(&once, init_desc) == ISC_R_SUCCESS);
4021
4022 /* Set common fields */
4023 dumparg.type = isc_statsformat_file;
4024 dumparg.arg = fp;
4025
4026 isc_stdtime_get(&now);
4027 fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now);
4028
4029 fprintf(fp, "++ Incoming Requests ++\n");
4030 dns_opcodestats_dump(server->sctx->opcodestats, opcodestat_dump,
4031 &dumparg, 0);
4032
4033 fprintf(fp, "++ Incoming Queries ++\n");
4034 dns_rdatatypestats_dump(server->sctx->rcvquerystats, rdtypestat_dump,
4035 &dumparg, 0);
4036
4037 fprintf(fp, "++ Outgoing Rcodes ++\n");
4038 dns_rcodestats_dump(server->sctx->rcodestats, rcodestat_dump, &dumparg,
4039 0);
4040
4041 fprintf(fp, "++ Outgoing Queries ++\n");
4042 for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
4043 view = ISC_LIST_NEXT(view, link))
4044 {
4045 if (view->resquerystats == NULL) {
4046 continue;
4047 }
4048 if (strcmp(view->name, "_default") == 0) {
4049 fprintf(fp, "[View: default]\n");
4050 } else {
4051 fprintf(fp, "[View: %s]\n", view->name);
4052 }
4053 dns_rdatatypestats_dump(view->resquerystats, rdtypestat_dump,
4054 &dumparg, 0);
4055 }
4056
4057 fprintf(fp, "++ Name Server Statistics ++\n");
4058 (void)dump_counters(ns_stats_get(server->sctx->nsstats),
4059 isc_statsformat_file, fp, NULL, nsstats_desc,
4060 ns_statscounter_max, nsstats_index, nsstat_values,
4061 0);
4062
4063 fprintf(fp, "++ Zone Maintenance Statistics ++\n");
4064 (void)dump_counters(server->zonestats, isc_statsformat_file, fp, NULL,
4065 zonestats_desc, dns_zonestatscounter_max,
4066 zonestats_index, zonestat_values, 0);
4067
4068 fprintf(fp, "++ Resolver Statistics ++\n");
4069 fprintf(fp, "[Common]\n");
4070 (void)dump_counters(server->resolverstats, isc_statsformat_file, fp,
4071 NULL, resstats_desc, dns_resstatscounter_max,
4072 resstats_index, resstat_values, 0);
4073 for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
4074 view = ISC_LIST_NEXT(view, link))
4075 {
4076 if (view->resstats == NULL) {
4077 continue;
4078 }
4079 if (strcmp(view->name, "_default") == 0) {
4080 fprintf(fp, "[View: default]\n");
4081 } else {
4082 fprintf(fp, "[View: %s]\n", view->name);
4083 }
4084 (void)dump_counters(view->resstats, isc_statsformat_file, fp,
4085 NULL, resstats_desc,
4086 dns_resstatscounter_max, resstats_index,
4087 resstat_values, 0);
4088 }
4089
4090 fprintf(fp, "++ Cache Statistics ++\n");
4091 for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
4092 view = ISC_LIST_NEXT(view, link))
4093 {
4094 if (strcmp(view->name, "_default") == 0) {
4095 fprintf(fp, "[View: default]\n");
4096 } else {
4097 fprintf(fp, "[View: %s (Cache: %s)]\n", view->name,
4098 dns_cache_getname(view->cache));
4099 }
4100 /*
4101 * Avoid dumping redundant statistics when the cache is shared.
4102 */
4103 if (dns_view_iscacheshared(view)) {
4104 continue;
4105 }
4106 dns_cache_dumpstats(view->cache, fp);
4107 }
4108
4109 fprintf(fp, "++ Cache DB RRsets ++\n");
4110 for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
4111 view = ISC_LIST_NEXT(view, link))
4112 {
4113 dns_stats_t *cacherrstats;
4114
4115 cacherrstats = dns_db_getrrsetstats(view->cachedb);
4116 if (cacherrstats == NULL) {
4117 continue;
4118 }
4119 if (strcmp(view->name, "_default") == 0) {
4120 fprintf(fp, "[View: default]\n");
4121 } else {
4122 fprintf(fp, "[View: %s (Cache: %s)]\n", view->name,
4123 dns_cache_getname(view->cache));
4124 }
4125 if (dns_view_iscacheshared(view)) {
4126 /*
4127 * Avoid dumping redundant statistics when the cache is
4128 * shared.
4129 */
4130 continue;
4131 }
4132 dns_rdatasetstats_dump(cacherrstats, rdatasetstats_dump,
4133 &dumparg, 0);
4134 }
4135
4136 fprintf(fp, "++ ADB stats ++\n");
4137 for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
4138 view = ISC_LIST_NEXT(view, link))
4139 {
4140 if (view->adbstats == NULL) {
4141 continue;
4142 }
4143 if (strcmp(view->name, "_default") == 0) {
4144 fprintf(fp, "[View: default]\n");
4145 } else {
4146 fprintf(fp, "[View: %s]\n", view->name);
4147 }
4148 (void)dump_counters(view->adbstats, isc_statsformat_file, fp,
4149 NULL, adbstats_desc, dns_adbstats_max,
4150 adbstats_index, adbstat_values, 0);
4151 }
4152
4153 fprintf(fp, "++ Socket I/O Statistics ++\n");
4154 (void)dump_counters(server->sockstats, isc_statsformat_file, fp, NULL,
4155 sockstats_desc, isc_sockstatscounter_max,
4156 sockstats_index, sockstat_values, 0);
4157
4158 fprintf(fp, "++ Per Zone Query Statistics ++\n");
4159 zone = NULL;
4160 for (result = dns_zone_first(server->zonemgr, &zone);
4161 result == ISC_R_SUCCESS;
4162 next = NULL, result = dns_zone_next(zone, &next), zone = next)
4163 {
4164 isc_stats_t *zonestats = dns_zone_getrequeststats(zone);
4165 if (zonestats != NULL) {
4166 char zonename[DNS_NAME_FORMATSIZE];
4167
4168 view = dns_zone_getview(zone);
4169 if (view == NULL) {
4170 continue;
4171 }
4172
4173 dns_name_format(dns_zone_getorigin(zone), zonename,
4174 sizeof(zonename));
4175 fprintf(fp, "[%s", zonename);
4176 if (strcmp(view->name, "_default") != 0) {
4177 fprintf(fp, " (view: %s)", view->name);
4178 }
4179 fprintf(fp, "]\n");
4180
4181 (void)dump_counters(zonestats, isc_statsformat_file, fp,
4182 NULL, nsstats_desc,
4183 ns_statscounter_max, nsstats_index,
4184 nsstat_values, 0);
4185 }
4186 }
4187
4188 fprintf(fp, "++ Per Zone Glue Cache Statistics ++\n");
4189 zone = NULL;
4190 for (result = dns_zone_first(server->zonemgr, &zone);
4191 result == ISC_R_SUCCESS;
4192 next = NULL, result = dns_zone_next(zone, &next), zone = next)
4193 {
4194 isc_stats_t *gluecachestats = dns_zone_getgluecachestats(zone);
4195 if (gluecachestats != NULL) {
4196 char zonename[DNS_NAME_FORMATSIZE];
4197
4198 view = dns_zone_getview(zone);
4199 if (view == NULL) {
4200 continue;
4201 }
4202
4203 dns_name_format(dns_zone_getorigin(zone), zonename,
4204 sizeof(zonename));
4205 fprintf(fp, "[%s", zonename);
4206 if (strcmp(view->name, "_default") != 0) {
4207 fprintf(fp, " (view: %s)", view->name);
4208 }
4209 fprintf(fp, "]\n");
4210
4211 (void)dump_counters(
4212 gluecachestats, isc_statsformat_file, fp, NULL,
4213 gluecachestats_desc,
4214 dns_gluecachestatscounter_max,
4215 gluecachestats_index, gluecachestats_values, 0);
4216 }
4217 }
4218
4219 fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now);
4220
4221 return (ISC_R_SUCCESS); /* this function currently always succeeds */
4222 }
4223