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