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