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