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