2008-01-17 00:15:14 +00:00
|
|
|
/*
|
2014-01-11 07:07:56 +11:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
2008-01-17 00:15:14 +00:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
2021-06-03 08:37:05 +02:00
|
|
|
*
|
2008-01-17 00:15:14 +00:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
2008-01-17 00:15:14 +00:00
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
2009-01-27 22:30:00 +00:00
|
|
|
* information regarding copyright ownership.
|
2008-01-17 00:15:14 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*! \file */
|
|
|
|
|
2018-03-28 14:56:40 +02:00
|
|
|
#include <inttypes.h>
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
2018-03-28 14:56:40 +02:00
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
#include <isc/buffer.h>
|
|
|
|
#include <isc/httpd.h>
|
|
|
|
#include <isc/mem.h>
|
2008-04-09 22:48:17 +00:00
|
|
|
#include <isc/once.h>
|
2009-01-27 22:30:00 +00:00
|
|
|
#include <isc/stats.h>
|
2014-01-10 10:57:03 -08:00
|
|
|
#include <isc/string.h>
|
2017-10-19 12:26:32 +11:00
|
|
|
#include <isc/util.h>
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2022-05-11 15:38:54 -07:00
|
|
|
#include <dns/adb.h>
|
2009-01-09 22:24:37 +00:00
|
|
|
#include <dns/cache.h>
|
2008-04-03 05:55:52 +00:00
|
|
|
#include <dns/db.h>
|
|
|
|
#include <dns/opcode.h>
|
2016-06-23 08:44:54 +10:00
|
|
|
#include <dns/rcode.h>
|
2008-04-03 05:55:52 +00:00
|
|
|
#include <dns/rdataclass.h>
|
|
|
|
#include <dns/rdatatype.h>
|
2016-06-23 08:44:54 +10:00
|
|
|
#include <dns/resolver.h>
|
2008-01-17 00:15:14 +00:00
|
|
|
#include <dns/stats.h>
|
2023-05-30 14:58:29 +00:00
|
|
|
#include <dns/transport.h>
|
2008-01-17 00:15:14 +00:00
|
|
|
#include <dns/view.h>
|
2023-05-30 14:58:29 +00:00
|
|
|
#include <dns/xfrin.h>
|
2008-04-03 05:55:52 +00:00
|
|
|
#include <dns/zt.h>
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
#include <ns/stats.h>
|
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
#include <named/log.h>
|
|
|
|
#include <named/server.h>
|
|
|
|
#include <named/statschannel.h>
|
|
|
|
|
2019-06-24 12:21:47 +02:00
|
|
|
#if HAVE_JSON_C
|
|
|
|
#include <json_object.h>
|
2020-03-09 16:17:26 +01:00
|
|
|
#include <linkhash.h>
|
2019-06-24 12:21:47 +02:00
|
|
|
#endif /* HAVE_JSON_C */
|
|
|
|
|
2019-06-24 14:25:55 +02:00
|
|
|
#if HAVE_LIBXML2
|
|
|
|
#include <libxml/xmlwriter.h>
|
|
|
|
#define ISC_XMLCHAR (const xmlChar *)
|
|
|
|
#endif /* HAVE_LIBXML2 */
|
|
|
|
|
2018-08-07 16:46:53 +02:00
|
|
|
#include "xsl_p.h"
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2021-11-03 14:50:08 +01:00
|
|
|
#define STATS_XML_VERSION_MAJOR "3"
|
2023-02-03 09:38:25 +01:00
|
|
|
#define STATS_XML_VERSION_MINOR "14"
|
2021-11-03 14:50:08 +01:00
|
|
|
#define STATS_XML_VERSION STATS_XML_VERSION_MAJOR "." STATS_XML_VERSION_MINOR
|
|
|
|
|
|
|
|
#define STATS_JSON_VERSION_MAJOR "1"
|
2023-02-03 09:38:25 +01:00
|
|
|
#define STATS_JSON_VERSION_MINOR "8"
|
2021-11-03 14:50:08 +01:00
|
|
|
#define STATS_JSON_VERSION STATS_JSON_VERSION_MAJOR "." STATS_JSON_VERSION_MINOR
|
|
|
|
|
2020-07-09 19:36:10 -07:00
|
|
|
#define CHECK(m) \
|
|
|
|
do { \
|
|
|
|
result = (m); \
|
|
|
|
if (result != ISC_R_SUCCESS) { \
|
|
|
|
goto cleanup; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
struct named_statschannel {
|
2008-01-17 00:15:14 +00:00
|
|
|
/* Unlocked */
|
|
|
|
isc_httpdmgr_t *httpdmgr;
|
|
|
|
isc_sockaddr_t address;
|
|
|
|
isc_mem_t *mctx;
|
|
|
|
|
|
|
|
/*
|
2022-10-29 14:22:56 -07:00
|
|
|
* Locked by channel lock
|
2008-01-17 00:15:14 +00:00
|
|
|
*/
|
|
|
|
isc_mutex_t lock;
|
|
|
|
dns_acl_t *acl;
|
|
|
|
|
2022-10-29 14:22:56 -07:00
|
|
|
/* Locked by main loop. */
|
2017-09-08 13:39:09 -07:00
|
|
|
ISC_LINK(struct named_statschannel) link;
|
2008-01-17 00:15:14 +00:00
|
|
|
};
|
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
typedef struct stats_dumparg {
|
2012-05-14 10:06:05 -07:00
|
|
|
isc_statsformat_t type;
|
|
|
|
void *arg; /* type dependent argument */
|
|
|
|
int ncounters; /* for general statistics */
|
|
|
|
int *counterindices; /* for general statistics */
|
2018-03-28 14:19:37 +02:00
|
|
|
uint64_t *countervalues; /* for general statistics */
|
2012-05-14 10:06:05 -07:00
|
|
|
isc_result_t result;
|
2008-04-03 05:55:52 +00:00
|
|
|
} stats_dumparg_t;
|
|
|
|
|
2025-02-04 13:17:31 +01:00
|
|
|
static isc_once_t once = ISC_ONCE_INITIALIZER;
|
2008-04-09 22:48:17 +00:00
|
|
|
|
2019-02-06 11:56:42 +01:00
|
|
|
#if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C)
|
2014-05-21 12:06:00 +10:00
|
|
|
#define EXTENDED_STATS
|
|
|
|
#else /* if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C) */
|
|
|
|
#undef EXTENDED_STATS
|
|
|
|
#endif /* if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C) */
|
|
|
|
|
2015-10-28 09:45:46 +11:00
|
|
|
#ifdef EXTENDED_STATS
|
|
|
|
static const char *
|
|
|
|
user_zonetype(dns_zone_t *zone) {
|
|
|
|
dns_zonetype_t ztype;
|
|
|
|
dns_view_t *view;
|
|
|
|
static const struct zt {
|
|
|
|
const dns_zonetype_t type;
|
|
|
|
const char *const string;
|
|
|
|
} typemap[] = { { dns_zone_none, "none" },
|
2021-08-25 22:33:52 -07:00
|
|
|
{ dns_zone_primary, "primary" },
|
|
|
|
{ dns_zone_secondary, "secondary" },
|
2018-10-09 10:54:51 +02:00
|
|
|
{ dns_zone_mirror, "mirror" },
|
2015-10-28 09:45:46 +11:00
|
|
|
{ dns_zone_stub, "stub" },
|
|
|
|
{ dns_zone_staticstub, "static-stub" },
|
|
|
|
{ dns_zone_key, "key" },
|
|
|
|
{ dns_zone_dlz, "dlz" },
|
|
|
|
{ dns_zone_redirect, "redirect" },
|
|
|
|
{ 0, NULL } };
|
|
|
|
const struct zt *tp;
|
|
|
|
|
2018-04-03 23:56:04 +02:00
|
|
|
if ((dns_zone_getoptions(zone) & DNS_ZONEOPT_AUTOEMPTY) != 0) {
|
2015-10-28 09:45:46 +11:00
|
|
|
return "builtin";
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-10-28 09:45:46 +11:00
|
|
|
|
|
|
|
view = dns_zone_getview(zone);
|
|
|
|
if (view != NULL && strcmp(view->name, "_bind") == 0) {
|
|
|
|
return "builtin";
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-10-28 09:45:46 +11:00
|
|
|
|
|
|
|
ztype = dns_zone_gettype(zone);
|
|
|
|
for (tp = typemap; tp->string != NULL && tp->type != ztype; tp++) {
|
|
|
|
/* empty */
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-10-28 09:45:46 +11:00
|
|
|
return tp->string;
|
|
|
|
}
|
|
|
|
#endif /* ifdef EXTENDED_STATS */
|
|
|
|
|
2008-07-17 23:43:26 +00:00
|
|
|
/*%
|
|
|
|
* Statistics descriptions. These could be statistically initialized at
|
|
|
|
* compile time, but we configure them run time in the init_desc() function
|
|
|
|
* below so that they'll be less susceptible to counter name changes.
|
|
|
|
*/
|
2017-09-08 13:39:09 -07:00
|
|
|
static const char *nsstats_desc[ns_statscounter_max];
|
2008-07-17 23:43:26 +00:00
|
|
|
static const char *resstats_desc[dns_resstatscounter_max];
|
2012-05-14 10:06:05 -07:00
|
|
|
static const char *adbstats_desc[dns_adbstats_max];
|
2008-07-17 23:43:26 +00:00
|
|
|
static const char *zonestats_desc[dns_zonestatscounter_max];
|
2009-01-27 22:30:00 +00:00
|
|
|
static const char *sockstats_desc[isc_sockstatscounter_max];
|
2012-05-17 10:44:16 -07:00
|
|
|
static const char *dnssecstats_desc[dns_dnssecstats_max];
|
2015-07-06 22:20:03 -07:00
|
|
|
static const char *udpinsizestats_desc[dns_sizecounter_in_max];
|
|
|
|
static const char *udpoutsizestats_desc[dns_sizecounter_out_max];
|
|
|
|
static const char *tcpinsizestats_desc[dns_sizecounter_in_max];
|
|
|
|
static const char *tcpoutsizestats_desc[dns_sizecounter_out_max];
|
2016-08-18 11:16:06 +10:00
|
|
|
static const char *dnstapstats_desc[dns_dnstapcounter_max];
|
2017-10-06 15:24:16 +05:30
|
|
|
static const char *gluecachestats_desc[dns_gluecachestatscounter_max];
|
2014-05-21 12:06:00 +10:00
|
|
|
#if defined(EXTENDED_STATS)
|
2017-09-08 13:39:09 -07:00
|
|
|
static const char *nsstats_xmldesc[ns_statscounter_max];
|
2008-07-17 23:43:26 +00:00
|
|
|
static const char *resstats_xmldesc[dns_resstatscounter_max];
|
2012-05-14 10:06:05 -07:00
|
|
|
static const char *adbstats_xmldesc[dns_adbstats_max];
|
2008-07-17 23:43:26 +00:00
|
|
|
static const char *zonestats_xmldesc[dns_zonestatscounter_max];
|
2009-01-27 22:30:00 +00:00
|
|
|
static const char *sockstats_xmldesc[isc_sockstatscounter_max];
|
2012-05-17 10:44:16 -07:00
|
|
|
static const char *dnssecstats_xmldesc[dns_dnssecstats_max];
|
2015-07-06 22:20:03 -07:00
|
|
|
static const char *udpinsizestats_xmldesc[dns_sizecounter_in_max];
|
|
|
|
static const char *udpoutsizestats_xmldesc[dns_sizecounter_out_max];
|
|
|
|
static const char *tcpinsizestats_xmldesc[dns_sizecounter_in_max];
|
|
|
|
static const char *tcpoutsizestats_xmldesc[dns_sizecounter_out_max];
|
2016-08-18 11:16:06 +10:00
|
|
|
static const char *dnstapstats_xmldesc[dns_dnstapcounter_max];
|
2017-10-06 15:24:16 +05:30
|
|
|
static const char *gluecachestats_xmldesc[dns_gluecachestatscounter_max];
|
2008-07-17 23:43:26 +00:00
|
|
|
#else /* if defined(EXTENDED_STATS) */
|
|
|
|
#define nsstats_xmldesc NULL
|
|
|
|
#define resstats_xmldesc NULL
|
2012-05-14 10:06:05 -07:00
|
|
|
#define adbstats_xmldesc NULL
|
2008-07-17 23:43:26 +00:00
|
|
|
#define zonestats_xmldesc NULL
|
2009-01-27 22:30:00 +00:00
|
|
|
#define sockstats_xmldesc NULL
|
2012-05-17 10:44:16 -07:00
|
|
|
#define dnssecstats_xmldesc NULL
|
2015-07-06 22:20:03 -07:00
|
|
|
#define udpinsizestats_xmldesc NULL
|
|
|
|
#define udpoutsizestats_xmldesc NULL
|
|
|
|
#define tcpinsizestats_xmldesc NULL
|
|
|
|
#define tcpoutsizestats_xmldesc NULL
|
2016-08-18 11:16:06 +10:00
|
|
|
#define dnstapstats_xmldesc NULL
|
2017-10-06 15:24:16 +05:30
|
|
|
#define gluecachestats_xmldesc NULL
|
2014-05-21 12:06:00 +10:00
|
|
|
#endif /* EXTENDED_STATS */
|
2008-07-17 23:43:26 +00:00
|
|
|
|
2020-07-09 19:36:10 -07:00
|
|
|
#define TRY0(a) \
|
|
|
|
do { \
|
|
|
|
xmlrc = (a); \
|
|
|
|
if (xmlrc < 0) \
|
|
|
|
goto cleanup; \
|
2010-02-04 00:57:25 +00:00
|
|
|
} while (0)
|
|
|
|
|
2009-01-27 22:30:00 +00:00
|
|
|
/*%
|
|
|
|
* Mapping arrays to represent statistics counters in the order of our
|
|
|
|
* preference, regardless of the order of counter indices. For example,
|
|
|
|
* nsstats_desc[nsstats_index[0]] will be the description that is shown first.
|
|
|
|
*/
|
2017-09-08 13:39:09 -07:00
|
|
|
static int nsstats_index[ns_statscounter_max];
|
2009-01-27 22:30:00 +00:00
|
|
|
static int resstats_index[dns_resstatscounter_max];
|
2012-05-17 10:44:16 -07:00
|
|
|
static int adbstats_index[dns_adbstats_max];
|
2009-01-27 22:30:00 +00:00
|
|
|
static int zonestats_index[dns_zonestatscounter_max];
|
|
|
|
static int sockstats_index[isc_sockstatscounter_max];
|
2012-05-17 10:44:16 -07:00
|
|
|
static int dnssecstats_index[dns_dnssecstats_max];
|
2015-07-06 22:20:03 -07:00
|
|
|
static int udpinsizestats_index[dns_sizecounter_in_max];
|
|
|
|
static int udpoutsizestats_index[dns_sizecounter_out_max];
|
|
|
|
static int tcpinsizestats_index[dns_sizecounter_in_max];
|
|
|
|
static int tcpoutsizestats_index[dns_sizecounter_out_max];
|
2016-08-18 11:16:06 +10:00
|
|
|
static int dnstapstats_index[dns_dnstapcounter_max];
|
2017-10-06 15:24:16 +05:30
|
|
|
static int gluecachestats_index[dns_gluecachestatscounter_max];
|
2009-01-27 22:30:00 +00:00
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2008-07-17 23:43:26 +00:00
|
|
|
set_desc(int counter, int maxcounter, const char *fdesc, const char **fdescs,
|
|
|
|
const char *xdesc, const char **xdescs) {
|
|
|
|
REQUIRE(counter < maxcounter);
|
2014-05-21 12:06:00 +10:00
|
|
|
REQUIRE(fdescs != NULL && fdescs[counter] == NULL);
|
|
|
|
#if defined(EXTENDED_STATS)
|
|
|
|
REQUIRE(xdescs != NULL && xdescs[counter] == NULL);
|
2008-07-17 23:43:26 +00:00
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
|
|
|
|
|
|
|
fdescs[counter] = fdesc;
|
2014-05-21 12:06:00 +10:00
|
|
|
#if defined(EXTENDED_STATS)
|
2008-07-17 23:43:26 +00:00
|
|
|
xdescs[counter] = xdesc;
|
|
|
|
#else /* if defined(EXTENDED_STATS) */
|
|
|
|
UNUSED(xdesc);
|
|
|
|
UNUSED(xdescs);
|
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
|
|
|
}
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
static const char *
|
|
|
|
get_histo_desc(const char *prefix, int i, int inf, bool ext) {
|
|
|
|
static char buf[(DNS_SIZEHISTO_MAXIN + DNS_SIZEHISTO_MAXOUT) * 80];
|
|
|
|
static size_t used = 0;
|
|
|
|
char *desc = buf + used;
|
|
|
|
size_t space = sizeof(buf) - used;
|
|
|
|
int min = DNS_SIZEHISTO_QUANTUM * i;
|
|
|
|
int max = DNS_SIZEHISTO_QUANTUM * (i + 1) - 1;
|
|
|
|
int len = 0;
|
|
|
|
|
|
|
|
if (!ext && i < inf) {
|
|
|
|
len = snprintf(desc, space, "%s %u-%u bytes", prefix, min, max);
|
|
|
|
} else if (!ext && i >= inf) {
|
|
|
|
len = snprintf(desc, space, "%s %u+ bytes", prefix, min);
|
|
|
|
} else if (ext && i < inf) {
|
|
|
|
len = snprintf(desc, space, "%u-%u", min, max);
|
|
|
|
} else if (ext && i >= inf) {
|
|
|
|
len = snprintf(desc, space, "%u+", min);
|
|
|
|
}
|
|
|
|
INSIST(0 < len && (size_t)len < space);
|
|
|
|
used += len + 1;
|
|
|
|
return desc;
|
|
|
|
}
|
|
|
|
|
2008-07-17 23:43:26 +00:00
|
|
|
static void
|
2008-08-08 05:06:49 +00:00
|
|
|
init_desc(void) {
|
2008-07-17 23:43:26 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Initialize name server statistics */
|
2017-09-08 13:39:09 -07:00
|
|
|
for (i = 0; i < ns_statscounter_max; i++) {
|
2009-10-20 03:30:07 +00:00
|
|
|
nsstats_desc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-05-21 12:06:00 +10:00
|
|
|
#if defined(EXTENDED_STATS)
|
2017-09-08 13:39:09 -07:00
|
|
|
for (i = 0; i < ns_statscounter_max; i++) {
|
2009-10-20 03:30:07 +00:00
|
|
|
nsstats_xmldesc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-07-17 23:43:26 +00:00
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
2009-01-27 22:30:00 +00:00
|
|
|
|
|
|
|
#define SET_NSSTATDESC(counterid, desc, xmldesc) \
|
|
|
|
do { \
|
2017-09-08 13:39:09 -07:00
|
|
|
set_desc(ns_statscounter_##counterid, ns_statscounter_max, \
|
2009-01-27 23:47:54 +00:00
|
|
|
desc, nsstats_desc, xmldesc, nsstats_xmldesc); \
|
2017-09-08 13:39:09 -07:00
|
|
|
nsstats_index[i++] = ns_statscounter_##counterid; \
|
2009-01-27 22:30:00 +00:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
SET_NSSTATDESC(requestv4, "IPv4 requests received", "Requestv4");
|
|
|
|
SET_NSSTATDESC(requestv6, "IPv6 requests received", "Requestv6");
|
|
|
|
SET_NSSTATDESC(edns0in, "requests with EDNS(0) received", "ReqEdns0");
|
|
|
|
SET_NSSTATDESC(badednsver,
|
|
|
|
"requests with unsupported EDNS version received",
|
|
|
|
"ReqBadEDNSVer");
|
|
|
|
SET_NSSTATDESC(tsigin, "requests with TSIG received", "ReqTSIG");
|
|
|
|
SET_NSSTATDESC(sig0in, "requests with SIG(0) received", "ReqSIG0");
|
|
|
|
SET_NSSTATDESC(invalidsig, "requests with invalid signature",
|
|
|
|
"ReqBadSIG");
|
2014-02-15 20:57:00 -08:00
|
|
|
SET_NSSTATDESC(requesttcp, "TCP requests received", "ReqTCP");
|
2019-11-05 17:48:47 -03:00
|
|
|
SET_NSSTATDESC(tcphighwater, "TCP connection high-water",
|
|
|
|
"TCPConnHighWater");
|
2009-01-27 22:30:00 +00:00
|
|
|
SET_NSSTATDESC(authrej, "auth queries rejected", "AuthQryRej");
|
|
|
|
SET_NSSTATDESC(recurserej, "recursive queries rejected", "RecQryRej");
|
|
|
|
SET_NSSTATDESC(xfrrej, "transfer requests rejected", "XfrRej");
|
|
|
|
SET_NSSTATDESC(updaterej, "update requests rejected", "UpdateRej");
|
|
|
|
SET_NSSTATDESC(response, "responses sent", "Response");
|
|
|
|
SET_NSSTATDESC(truncatedresp, "truncated responses sent",
|
|
|
|
"TruncatedResp");
|
|
|
|
SET_NSSTATDESC(edns0out, "responses with EDNS(0) sent", "RespEDNS0");
|
|
|
|
SET_NSSTATDESC(tsigout, "responses with TSIG sent", "RespTSIG");
|
|
|
|
SET_NSSTATDESC(sig0out, "responses with SIG(0) sent", "RespSIG0");
|
|
|
|
SET_NSSTATDESC(success, "queries resulted in successful answer",
|
|
|
|
"QrySuccess");
|
|
|
|
SET_NSSTATDESC(authans, "queries resulted in authoritative answer",
|
|
|
|
"QryAuthAns");
|
|
|
|
SET_NSSTATDESC(nonauthans,
|
|
|
|
"queries resulted in non authoritative answer",
|
|
|
|
"QryNoauthAns");
|
|
|
|
SET_NSSTATDESC(referral, "queries resulted in referral answer",
|
|
|
|
"QryReferral");
|
|
|
|
SET_NSSTATDESC(nxrrset, "queries resulted in nxrrset", "QryNxrrset");
|
|
|
|
SET_NSSTATDESC(servfail, "queries resulted in SERVFAIL", "QrySERVFAIL");
|
|
|
|
SET_NSSTATDESC(formerr, "queries resulted in FORMERR", "QryFORMERR");
|
|
|
|
SET_NSSTATDESC(nxdomain, "queries resulted in NXDOMAIN", "QryNXDOMAIN");
|
2012-11-14 12:44:15 -06:00
|
|
|
SET_NSSTATDESC(recursion, "queries caused recursion", "QryRecursion");
|
2009-01-27 22:30:00 +00:00
|
|
|
SET_NSSTATDESC(duplicate, "duplicate queries received", "QryDuplicate");
|
|
|
|
SET_NSSTATDESC(dropped, "queries dropped", "QryDropped");
|
|
|
|
SET_NSSTATDESC(failure, "other query failures", "QryFailure");
|
|
|
|
SET_NSSTATDESC(xfrdone, "requested transfers completed", "XfrReqDone");
|
|
|
|
SET_NSSTATDESC(updatereqfwd, "update requests forwarded",
|
|
|
|
"UpdateReqFwd");
|
|
|
|
SET_NSSTATDESC(updaterespfwd, "update responses forwarded",
|
|
|
|
"UpdateRespFwd");
|
|
|
|
SET_NSSTATDESC(updatefwdfail, "update forward failed", "UpdateFwdFail");
|
|
|
|
SET_NSSTATDESC(updatedone, "updates completed", "UpdateDone");
|
|
|
|
SET_NSSTATDESC(updatefail, "updates failed", "UpdateFail");
|
|
|
|
SET_NSSTATDESC(updatebadprereq,
|
|
|
|
"updates rejected due to prerequisite failure",
|
|
|
|
"UpdateBadPrereq");
|
2024-04-22 17:01:16 +03:00
|
|
|
SET_NSSTATDESC(recurshighwater, "Recursive clients high-water",
|
|
|
|
"RecursHighwater");
|
2012-05-14 10:06:05 -07:00
|
|
|
SET_NSSTATDESC(recursclients, "recursing clients", "RecursClients");
|
2012-11-01 14:23:14 +11:00
|
|
|
SET_NSSTATDESC(dns64, "queries answered by DNS64", "DNS64");
|
2013-02-25 10:49:30 -08:00
|
|
|
SET_NSSTATDESC(ratedropped, "responses dropped for rate limits",
|
|
|
|
"RateDropped");
|
|
|
|
SET_NSSTATDESC(rateslipped, "responses truncated for rate limits",
|
|
|
|
"RateSlipped");
|
2013-02-25 12:46:51 -08:00
|
|
|
SET_NSSTATDESC(rpz_rewrites, "response policy zone rewrites",
|
|
|
|
"RPZRewrites");
|
2014-02-15 20:57:00 -08:00
|
|
|
SET_NSSTATDESC(udp, "UDP queries received", "QryUDP");
|
|
|
|
SET_NSSTATDESC(tcp, "TCP queries received", "QryTCP");
|
2024-10-04 13:14:52 +03:00
|
|
|
SET_NSSTATDESC(dot, "DoT queries received", "QryDoT");
|
|
|
|
SET_NSSTATDESC(doh, "DoH queries received", "QryDoH");
|
|
|
|
SET_NSSTATDESC(dohplain, "DoH-Plain queries received", "QryDoHPlain");
|
|
|
|
SET_NSSTATDESC(proxyudp, "PROXYv2 UDP queries received", "QryProxyUDP");
|
|
|
|
SET_NSSTATDESC(proxytcp, "PROXYv2 TCP queries received", "QryProxyTCP");
|
|
|
|
SET_NSSTATDESC(proxydot, "PROXYv2 DoT queries received", "QryProxyDoT");
|
|
|
|
SET_NSSTATDESC(proxydoh, "PROXYv2 DoH queries received", "QryProxyDoH");
|
|
|
|
SET_NSSTATDESC(proxydohplain, "PROXYv2/DoH-Plain queries received",
|
|
|
|
"QryProxyDoHPlain");
|
|
|
|
SET_NSSTATDESC(encryptedproxydot,
|
|
|
|
"Encrypted PROXYv2 DoT queries received",
|
|
|
|
"QryEncryptedProxyDoT");
|
|
|
|
SET_NSSTATDESC(encryptedproxydoh,
|
|
|
|
"Encrypted PROXYv2 DoH queries received",
|
|
|
|
"QryEncryptedProxyDoH");
|
2014-02-24 09:24:25 +11:00
|
|
|
SET_NSSTATDESC(nsidopt, "NSID option received", "NSIDOpt");
|
2015-03-18 09:35:27 +11:00
|
|
|
SET_NSSTATDESC(expireopt, "Expire option received", "ExpireOpt");
|
2017-01-04 09:16:30 -08:00
|
|
|
SET_NSSTATDESC(keepaliveopt, "EDNS TCP keepalive option received",
|
|
|
|
"KeepAliveOpt");
|
2024-06-13 08:13:28 +10:00
|
|
|
SET_NSSTATDESC(zoneversionopt, "ZONEVERSION option received",
|
|
|
|
"ZoneVersionOpt");
|
2017-01-04 09:16:30 -08:00
|
|
|
SET_NSSTATDESC(padopt, "EDNS padding option received", "PadOpt");
|
2015-03-18 09:35:27 +11:00
|
|
|
SET_NSSTATDESC(otheropt, "Other EDNS option received", "OtherOpt");
|
2015-07-06 09:44:24 +10:00
|
|
|
SET_NSSTATDESC(cookiein, "COOKIE option received", "CookieIn");
|
|
|
|
SET_NSSTATDESC(cookienew, "COOKIE - client only", "CookieNew");
|
|
|
|
SET_NSSTATDESC(cookiebadsize, "COOKIE - bad size", "CookieBadSize");
|
|
|
|
SET_NSSTATDESC(cookiebadtime, "COOKIE - bad time", "CookieBadTime");
|
|
|
|
SET_NSSTATDESC(cookienomatch, "COOKIE - no match", "CookieNoMatch");
|
|
|
|
SET_NSSTATDESC(cookiematch, "COOKIE - match", "CookieMatch");
|
2016-06-14 11:31:17 +10:00
|
|
|
SET_NSSTATDESC(ecsopt, "EDNS client subnet option received", "ECSOpt");
|
2015-06-25 09:21:50 +02:00
|
|
|
SET_NSSTATDESC(nxdomainredirect,
|
|
|
|
"queries resulted in NXDOMAIN that were redirected",
|
|
|
|
"QryNXRedir");
|
|
|
|
SET_NSSTATDESC(nxdomainredirect_rlookup,
|
|
|
|
"queries resulted in NXDOMAIN that were redirected and "
|
|
|
|
"resulted in a successful remote lookup",
|
|
|
|
"QryNXRedirRLookup");
|
2015-07-06 09:44:24 +10:00
|
|
|
SET_NSSTATDESC(badcookie, "sent badcookie response", "QryBADCOOKIE");
|
2017-08-31 07:57:50 +10:00
|
|
|
SET_NSSTATDESC(nxdomainsynth, "synthesized a NXDOMAIN response",
|
|
|
|
"SynthNXDOMAIN");
|
2021-10-28 13:05:33 +11:00
|
|
|
SET_NSSTATDESC(nodatasynth, "synthesized a no-data response",
|
2017-08-31 07:57:50 +10:00
|
|
|
"SynthNODATA");
|
|
|
|
SET_NSSTATDESC(wildcardsynth, "synthesized a wildcard response",
|
|
|
|
"SynthWILDCARD");
|
2017-09-06 09:58:29 +10:00
|
|
|
SET_NSSTATDESC(trystale,
|
|
|
|
"attempts to use stale cache data after lookup failure",
|
|
|
|
"QryTryStale");
|
|
|
|
SET_NSSTATDESC(usedstale,
|
|
|
|
"successful uses of stale cache data after lookup "
|
|
|
|
"failure",
|
|
|
|
"QryUsedStale");
|
2017-09-12 18:41:47 -07:00
|
|
|
SET_NSSTATDESC(prefetch, "queries triggered prefetch", "Prefetch");
|
2017-10-06 13:01:14 +11:00
|
|
|
SET_NSSTATDESC(keytagopt, "Keytag option received", "KeyTagOpt");
|
2019-11-25 21:28:10 -08:00
|
|
|
SET_NSSTATDESC(reclimitdropped,
|
|
|
|
"queries dropped due to recursive client limit",
|
|
|
|
"RecLimitDropped");
|
2022-09-01 16:05:04 -07:00
|
|
|
SET_NSSTATDESC(updatequota, "Update quota exceeded", "UpdateQuota");
|
2019-11-05 17:48:47 -03:00
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
INSIST(i == ns_statscounter_max);
|
2008-07-17 23:43:26 +00:00
|
|
|
|
|
|
|
/* Initialize resolver statistics */
|
2009-10-20 03:30:07 +00:00
|
|
|
for (i = 0; i < dns_resstatscounter_max; i++) {
|
|
|
|
resstats_desc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-05-21 12:06:00 +10:00
|
|
|
#if defined(EXTENDED_STATS)
|
2009-10-20 03:30:07 +00:00
|
|
|
for (i = 0; i < dns_resstatscounter_max; i++) {
|
|
|
|
resstats_xmldesc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-07-17 23:43:26 +00:00
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
|
|
|
|
2009-01-27 22:30:00 +00:00
|
|
|
#define SET_RESSTATDESC(counterid, desc, xmldesc) \
|
|
|
|
do { \
|
|
|
|
set_desc(dns_resstatscounter_##counterid, \
|
|
|
|
dns_resstatscounter_max, desc, resstats_desc, \
|
2009-01-27 23:47:54 +00:00
|
|
|
xmldesc, resstats_xmldesc); \
|
2009-01-27 22:30:00 +00:00
|
|
|
resstats_index[i++] = dns_resstatscounter_##counterid; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
SET_RESSTATDESC(queryv4, "IPv4 queries sent", "Queryv4");
|
|
|
|
SET_RESSTATDESC(queryv6, "IPv6 queries sent", "Queryv6");
|
|
|
|
SET_RESSTATDESC(responsev4, "IPv4 responses received", "Responsev4");
|
|
|
|
SET_RESSTATDESC(responsev6, "IPv6 responses received", "Responsev6");
|
|
|
|
SET_RESSTATDESC(nxdomain, "NXDOMAIN received", "NXDOMAIN");
|
|
|
|
SET_RESSTATDESC(servfail, "SERVFAIL received", "SERVFAIL");
|
|
|
|
SET_RESSTATDESC(formerr, "FORMERR received", "FORMERR");
|
|
|
|
SET_RESSTATDESC(othererror, "other errors received", "OtherError");
|
|
|
|
SET_RESSTATDESC(edns0fail, "EDNS(0) query failures", "EDNS0Fail");
|
|
|
|
SET_RESSTATDESC(mismatch, "mismatch responses received", "Mismatch");
|
|
|
|
SET_RESSTATDESC(truncated, "truncated responses received", "Truncated");
|
|
|
|
SET_RESSTATDESC(lame, "lame delegations received", "Lame");
|
|
|
|
SET_RESSTATDESC(retry, "query retries", "Retry");
|
|
|
|
SET_RESSTATDESC(dispabort, "queries aborted due to quota",
|
|
|
|
"QueryAbort");
|
|
|
|
SET_RESSTATDESC(dispsockfail, "failures in opening query sockets",
|
|
|
|
"QuerySockFail");
|
2012-05-14 10:06:05 -07:00
|
|
|
SET_RESSTATDESC(disprequdp, "UDP queries in progress", "QueryCurUDP");
|
|
|
|
SET_RESSTATDESC(dispreqtcp, "TCP queries in progress", "QueryCurTCP");
|
2009-01-27 22:30:00 +00:00
|
|
|
SET_RESSTATDESC(querytimeout, "query timeouts", "QueryTimeout");
|
|
|
|
SET_RESSTATDESC(gluefetchv4, "IPv4 NS address fetches", "GlueFetchv4");
|
|
|
|
SET_RESSTATDESC(gluefetchv6, "IPv6 NS address fetches", "GlueFetchv6");
|
|
|
|
SET_RESSTATDESC(gluefetchv4fail, "IPv4 NS address fetch failed",
|
|
|
|
"GlueFetchv4Fail");
|
|
|
|
SET_RESSTATDESC(gluefetchv6fail, "IPv6 NS address fetch failed",
|
|
|
|
"GlueFetchv6Fail");
|
|
|
|
SET_RESSTATDESC(val, "DNSSEC validation attempted", "ValAttempt");
|
|
|
|
SET_RESSTATDESC(valsuccess, "DNSSEC validation succeeded", "ValOk");
|
|
|
|
SET_RESSTATDESC(valnegsuccess, "DNSSEC NX validation succeeded",
|
|
|
|
"ValNegOk");
|
|
|
|
SET_RESSTATDESC(valfail, "DNSSEC validation failed", "ValFail");
|
|
|
|
SET_RESSTATDESC(queryrtt0,
|
|
|
|
"queries with RTT < " DNS_RESOLVER_QRYRTTCLASS0STR "ms",
|
|
|
|
"QryRTT" DNS_RESOLVER_QRYRTTCLASS0STR);
|
|
|
|
SET_RESSTATDESC(queryrtt1,
|
|
|
|
"queries with RTT " DNS_RESOLVER_QRYRTTCLASS0STR
|
|
|
|
"-" DNS_RESOLVER_QRYRTTCLASS1STR "ms",
|
|
|
|
"QryRTT" DNS_RESOLVER_QRYRTTCLASS1STR);
|
|
|
|
SET_RESSTATDESC(queryrtt2,
|
|
|
|
"queries with RTT " DNS_RESOLVER_QRYRTTCLASS1STR
|
|
|
|
"-" DNS_RESOLVER_QRYRTTCLASS2STR "ms",
|
|
|
|
"QryRTT" DNS_RESOLVER_QRYRTTCLASS2STR);
|
|
|
|
SET_RESSTATDESC(queryrtt3,
|
|
|
|
"queries with RTT " DNS_RESOLVER_QRYRTTCLASS2STR
|
|
|
|
"-" DNS_RESOLVER_QRYRTTCLASS3STR "ms",
|
|
|
|
"QryRTT" DNS_RESOLVER_QRYRTTCLASS3STR);
|
|
|
|
SET_RESSTATDESC(queryrtt4,
|
|
|
|
"queries with RTT " DNS_RESOLVER_QRYRTTCLASS3STR
|
|
|
|
"-" DNS_RESOLVER_QRYRTTCLASS4STR "ms",
|
|
|
|
"QryRTT" DNS_RESOLVER_QRYRTTCLASS4STR);
|
|
|
|
SET_RESSTATDESC(queryrtt5,
|
|
|
|
"queries with RTT > " DNS_RESOLVER_QRYRTTCLASS4STR "ms",
|
|
|
|
"QryRTT" DNS_RESOLVER_QRYRTTCLASS4STR "+");
|
2012-05-14 10:06:05 -07:00
|
|
|
SET_RESSTATDESC(nfetch, "active fetches", "NumFetch");
|
|
|
|
SET_RESSTATDESC(buckets, "bucket size", "BucketSize");
|
2012-10-16 10:21:22 +11:00
|
|
|
SET_RESSTATDESC(refused, "REFUSED received", "REFUSED");
|
2015-07-06 09:44:24 +10:00
|
|
|
SET_RESSTATDESC(cookienew, "COOKIE send with client cookie only",
|
|
|
|
"ClientCookieOut");
|
|
|
|
SET_RESSTATDESC(cookieout, "COOKIE sent with client and server cookie",
|
|
|
|
"ServerCookieOut");
|
|
|
|
SET_RESSTATDESC(cookiein, "COOKIE replies received", "CookieIn");
|
|
|
|
SET_RESSTATDESC(cookieok, "COOKIE client ok", "CookieClientOk");
|
2014-03-20 05:00:55 +11:00
|
|
|
SET_RESSTATDESC(badvers, "bad EDNS version", "BadEDNSVersion");
|
2015-07-06 09:44:24 +10:00
|
|
|
SET_RESSTATDESC(badcookie, "bad cookie rcode", "BadCookieRcode");
|
2015-07-08 22:53:39 -07:00
|
|
|
SET_RESSTATDESC(zonequota, "spilled due to zone quota", "ZoneQuota");
|
|
|
|
SET_RESSTATDESC(serverquota, "spilled due to server quota",
|
|
|
|
"ServerQuota");
|
2023-05-29 15:19:49 +00:00
|
|
|
SET_RESSTATDESC(clientquota, "spilled due to clients per query quota",
|
|
|
|
"ClientQuota");
|
2016-07-11 13:36:16 +10:00
|
|
|
SET_RESSTATDESC(nextitem, "waited for next item", "NextItem");
|
2017-10-26 21:38:43 -07:00
|
|
|
SET_RESSTATDESC(priming, "priming queries", "Priming");
|
2024-09-12 12:34:40 +00:00
|
|
|
SET_RESSTATDESC(forwardonlyfail, "all forwarders failed",
|
|
|
|
"ForwardOnlyFail");
|
2014-02-19 23:46:31 +00:00
|
|
|
|
2009-01-27 22:30:00 +00:00
|
|
|
INSIST(i == dns_resstatscounter_max);
|
2009-01-27 23:47:54 +00:00
|
|
|
|
2012-05-14 10:06:05 -07:00
|
|
|
/* Initialize adb statistics */
|
|
|
|
for (i = 0; i < dns_adbstats_max; i++) {
|
|
|
|
adbstats_desc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-05-21 12:06:00 +10:00
|
|
|
#if defined(EXTENDED_STATS)
|
2012-05-14 10:06:05 -07:00
|
|
|
for (i = 0; i < dns_adbstats_max; i++) {
|
|
|
|
adbstats_xmldesc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-14 10:06:05 -07:00
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
|
|
|
|
|
|
|
#define SET_ADBSTATDESC(id, desc, xmldesc) \
|
|
|
|
do { \
|
|
|
|
set_desc(dns_adbstats_##id, dns_adbstats_max, desc, \
|
|
|
|
adbstats_desc, xmldesc, adbstats_xmldesc); \
|
|
|
|
adbstats_index[i++] = dns_adbstats_##id; \
|
|
|
|
} while (0)
|
|
|
|
i = 0;
|
|
|
|
SET_ADBSTATDESC(nentries, "Address hash table size", "nentries");
|
|
|
|
SET_ADBSTATDESC(entriescnt, "Addresses in hash table", "entriescnt");
|
|
|
|
SET_ADBSTATDESC(nnames, "Name hash table size", "nnames");
|
|
|
|
SET_ADBSTATDESC(namescnt, "Names in hash table", "namescnt");
|
|
|
|
|
|
|
|
INSIST(i == dns_adbstats_max);
|
|
|
|
|
2008-07-17 23:43:26 +00:00
|
|
|
/* Initialize zone statistics */
|
2009-10-20 03:30:07 +00:00
|
|
|
for (i = 0; i < dns_zonestatscounter_max; i++) {
|
|
|
|
zonestats_desc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-05-21 12:06:00 +10:00
|
|
|
#if defined(EXTENDED_STATS)
|
2009-10-20 03:30:07 +00:00
|
|
|
for (i = 0; i < dns_zonestatscounter_max; i++) {
|
|
|
|
zonestats_xmldesc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-07-17 23:43:26 +00:00
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
2009-01-27 22:30:00 +00:00
|
|
|
|
|
|
|
#define SET_ZONESTATDESC(counterid, desc, xmldesc) \
|
|
|
|
do { \
|
|
|
|
set_desc(dns_zonestatscounter_##counterid, \
|
|
|
|
dns_zonestatscounter_max, desc, zonestats_desc, \
|
2009-01-27 23:47:54 +00:00
|
|
|
xmldesc, zonestats_xmldesc); \
|
2009-01-27 22:30:00 +00:00
|
|
|
zonestats_index[i++] = dns_zonestatscounter_##counterid; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
SET_ZONESTATDESC(notifyoutv4, "IPv4 notifies sent", "NotifyOutv4");
|
|
|
|
SET_ZONESTATDESC(notifyoutv6, "IPv6 notifies sent", "NotifyOutv6");
|
|
|
|
SET_ZONESTATDESC(notifyinv4, "IPv4 notifies received", "NotifyInv4");
|
|
|
|
SET_ZONESTATDESC(notifyinv6, "IPv6 notifies received", "NotifyInv6");
|
|
|
|
SET_ZONESTATDESC(notifyrej, "notifies rejected", "NotifyRej");
|
|
|
|
SET_ZONESTATDESC(soaoutv4, "IPv4 SOA queries sent", "SOAOutv4");
|
|
|
|
SET_ZONESTATDESC(soaoutv6, "IPv6 SOA queries sent", "SOAOutv6");
|
|
|
|
SET_ZONESTATDESC(axfrreqv4, "IPv4 AXFR requested", "AXFRReqv4");
|
|
|
|
SET_ZONESTATDESC(axfrreqv6, "IPv6 AXFR requested", "AXFRReqv6");
|
|
|
|
SET_ZONESTATDESC(ixfrreqv4, "IPv4 IXFR requested", "IXFRReqv4");
|
|
|
|
SET_ZONESTATDESC(ixfrreqv6, "IPv6 IXFR requested", "IXFRReqv6");
|
2012-11-14 12:44:15 -06:00
|
|
|
SET_ZONESTATDESC(xfrsuccess, "transfer requests succeeded",
|
|
|
|
"XfrSuccess");
|
2009-01-27 22:30:00 +00:00
|
|
|
SET_ZONESTATDESC(xfrfail, "transfer requests failed", "XfrFail");
|
|
|
|
INSIST(i == dns_zonestatscounter_max);
|
|
|
|
|
|
|
|
/* Initialize socket statistics */
|
2009-10-20 03:30:07 +00:00
|
|
|
for (i = 0; i < isc_sockstatscounter_max; i++) {
|
|
|
|
sockstats_desc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-05-21 12:06:00 +10:00
|
|
|
#if defined(EXTENDED_STATS)
|
2009-10-20 03:30:07 +00:00
|
|
|
for (i = 0; i < isc_sockstatscounter_max; i++) {
|
|
|
|
sockstats_xmldesc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2009-01-27 22:30:00 +00:00
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
|
|
|
|
|
|
|
#define SET_SOCKSTATDESC(counterid, desc, xmldesc) \
|
|
|
|
do { \
|
|
|
|
set_desc(isc_sockstatscounter_##counterid, \
|
|
|
|
isc_sockstatscounter_max, desc, sockstats_desc, \
|
2009-01-27 23:47:54 +00:00
|
|
|
xmldesc, sockstats_xmldesc); \
|
2009-01-27 22:30:00 +00:00
|
|
|
sockstats_index[i++] = isc_sockstatscounter_##counterid; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
i = 0;
|
2009-01-27 23:47:54 +00:00
|
|
|
SET_SOCKSTATDESC(udp4open, "UDP/IPv4 sockets opened", "UDP4Open");
|
|
|
|
SET_SOCKSTATDESC(udp6open, "UDP/IPv6 sockets opened", "UDP6Open");
|
2009-01-27 22:30:00 +00:00
|
|
|
SET_SOCKSTATDESC(tcp4open, "TCP/IPv4 sockets opened", "TCP4Open");
|
|
|
|
SET_SOCKSTATDESC(tcp6open, "TCP/IPv6 sockets opened", "TCP6Open");
|
|
|
|
SET_SOCKSTATDESC(udp4openfail, "UDP/IPv4 socket open failures",
|
2009-01-27 23:47:54 +00:00
|
|
|
"UDP4OpenFail");
|
2009-01-27 22:30:00 +00:00
|
|
|
SET_SOCKSTATDESC(udp6openfail, "UDP/IPv6 socket open failures",
|
2009-01-27 23:47:54 +00:00
|
|
|
"UDP6OpenFail");
|
2009-01-27 22:30:00 +00:00
|
|
|
SET_SOCKSTATDESC(tcp4openfail, "TCP/IPv4 socket open failures",
|
|
|
|
"TCP4OpenFail");
|
|
|
|
SET_SOCKSTATDESC(tcp6openfail, "TCP/IPv6 socket open failures",
|
|
|
|
"TCP6OpenFail");
|
|
|
|
SET_SOCKSTATDESC(udp4close, "UDP/IPv4 sockets closed", "UDP4Close");
|
|
|
|
SET_SOCKSTATDESC(udp6close, "UDP/IPv6 sockets closed", "UDP6Close");
|
|
|
|
SET_SOCKSTATDESC(tcp4close, "TCP/IPv4 sockets closed", "TCP4Close");
|
|
|
|
SET_SOCKSTATDESC(tcp6close, "TCP/IPv6 sockets closed", "TCP6Close");
|
|
|
|
SET_SOCKSTATDESC(udp4bindfail, "UDP/IPv4 socket bind failures",
|
|
|
|
"UDP4BindFail");
|
|
|
|
SET_SOCKSTATDESC(udp6bindfail, "UDP/IPv6 socket bind failures",
|
|
|
|
"UDP6BindFail");
|
|
|
|
SET_SOCKSTATDESC(tcp4bindfail, "TCP/IPv4 socket bind failures",
|
|
|
|
"TCP4BindFail");
|
|
|
|
SET_SOCKSTATDESC(tcp6bindfail, "TCP/IPv6 socket bind failures",
|
|
|
|
"TCP6BindFail");
|
|
|
|
SET_SOCKSTATDESC(udp4connectfail, "UDP/IPv4 socket connect failures",
|
|
|
|
"UDP4ConnFail");
|
|
|
|
SET_SOCKSTATDESC(udp6connectfail, "UDP/IPv6 socket connect failures",
|
|
|
|
"UDP6ConnFail");
|
|
|
|
SET_SOCKSTATDESC(tcp4connectfail, "TCP/IPv4 socket connect failures",
|
|
|
|
"TCP4ConnFail");
|
|
|
|
SET_SOCKSTATDESC(tcp6connectfail, "TCP/IPv6 socket connect failures",
|
|
|
|
"TCP6ConnFail");
|
|
|
|
SET_SOCKSTATDESC(udp4connect, "UDP/IPv4 connections established",
|
|
|
|
"UDP4Conn");
|
|
|
|
SET_SOCKSTATDESC(udp6connect, "UDP/IPv6 connections established",
|
|
|
|
"UDP6Conn");
|
|
|
|
SET_SOCKSTATDESC(tcp4connect, "TCP/IPv4 connections established",
|
|
|
|
"TCP4Conn");
|
|
|
|
SET_SOCKSTATDESC(tcp6connect, "TCP/IPv6 connections established",
|
|
|
|
"TCP6Conn");
|
|
|
|
SET_SOCKSTATDESC(tcp4acceptfail, "TCP/IPv4 connection accept failures",
|
|
|
|
"TCP4AcceptFail");
|
|
|
|
SET_SOCKSTATDESC(tcp6acceptfail, "TCP/IPv6 connection accept failures",
|
|
|
|
"TCP6AcceptFail");
|
|
|
|
SET_SOCKSTATDESC(tcp4accept, "TCP/IPv4 connections accepted",
|
|
|
|
"TCP4Accept");
|
|
|
|
SET_SOCKSTATDESC(tcp6accept, "TCP/IPv6 connections accepted",
|
|
|
|
"TCP6Accept");
|
|
|
|
SET_SOCKSTATDESC(udp4sendfail, "UDP/IPv4 send errors", "UDP4SendErr");
|
|
|
|
SET_SOCKSTATDESC(udp6sendfail, "UDP/IPv6 send errors", "UDP6SendErr");
|
|
|
|
SET_SOCKSTATDESC(tcp4sendfail, "TCP/IPv4 send errors", "TCP4SendErr");
|
|
|
|
SET_SOCKSTATDESC(tcp6sendfail, "TCP/IPv6 send errors", "TCP6SendErr");
|
|
|
|
SET_SOCKSTATDESC(udp4recvfail, "UDP/IPv4 recv errors", "UDP4RecvErr");
|
|
|
|
SET_SOCKSTATDESC(udp6recvfail, "UDP/IPv6 recv errors", "UDP6RecvErr");
|
|
|
|
SET_SOCKSTATDESC(tcp4recvfail, "TCP/IPv4 recv errors", "TCP4RecvErr");
|
|
|
|
SET_SOCKSTATDESC(tcp6recvfail, "TCP/IPv6 recv errors", "TCP6RecvErr");
|
2012-05-14 10:06:05 -07:00
|
|
|
SET_SOCKSTATDESC(udp4active, "UDP/IPv4 sockets active", "UDP4Active");
|
|
|
|
SET_SOCKSTATDESC(udp6active, "UDP/IPv6 sockets active", "UDP6Active");
|
|
|
|
SET_SOCKSTATDESC(tcp4active, "TCP/IPv4 sockets active", "TCP4Active");
|
|
|
|
SET_SOCKSTATDESC(tcp6active, "TCP/IPv6 sockets active", "TCP6Active");
|
2024-01-02 16:28:46 +03:00
|
|
|
SET_SOCKSTATDESC(tcp4clients, "TCP/IPv4 clients currently connected",
|
|
|
|
"TCP4Clients");
|
|
|
|
SET_SOCKSTATDESC(tcp6clients, "TCP/IPv6 clients currently connected",
|
|
|
|
"TCP6Clients");
|
2009-01-27 22:30:00 +00:00
|
|
|
INSIST(i == isc_sockstatscounter_max);
|
2008-07-17 23:43:26 +00:00
|
|
|
|
2012-05-17 10:44:16 -07:00
|
|
|
/* Initialize DNSSEC statistics */
|
|
|
|
for (i = 0; i < dns_dnssecstats_max; i++) {
|
|
|
|
dnssecstats_desc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-05-21 12:06:00 +10:00
|
|
|
#if defined(EXTENDED_STATS)
|
2012-05-17 10:44:16 -07:00
|
|
|
for (i = 0; i < dns_dnssecstats_max; i++) {
|
|
|
|
dnssecstats_xmldesc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-17 10:44:16 -07:00
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
|
|
|
|
|
|
|
#define SET_DNSSECSTATDESC(counterid, desc, xmldesc) \
|
|
|
|
do { \
|
|
|
|
set_desc(dns_dnssecstats_##counterid, dns_dnssecstats_max, \
|
2012-11-14 12:44:15 -06:00
|
|
|
desc, dnssecstats_desc, xmldesc, \
|
2012-05-17 10:44:16 -07:00
|
|
|
dnssecstats_xmldesc); \
|
|
|
|
dnssecstats_index[i++] = dns_dnssecstats_##counterid; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
SET_DNSSECSTATDESC(asis,
|
|
|
|
"dnssec validation success with signer "
|
|
|
|
"\"as is\"",
|
|
|
|
"DNSSECasis");
|
|
|
|
SET_DNSSECSTATDESC(downcase,
|
|
|
|
"dnssec validation success with signer "
|
|
|
|
"lower cased",
|
|
|
|
"DNSSECdowncase");
|
|
|
|
SET_DNSSECSTATDESC(wildcard, "dnssec validation of wildcard signature",
|
|
|
|
"DNSSECwild");
|
|
|
|
SET_DNSSECSTATDESC(fail, "dnssec validation failures", "DNSSECfail");
|
|
|
|
INSIST(i == dns_dnssecstats_max);
|
|
|
|
|
2016-08-18 11:16:06 +10:00
|
|
|
/* Initialize dnstap statistics */
|
|
|
|
for (i = 0; i < dns_dnstapcounter_max; i++) {
|
|
|
|
dnstapstats_desc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-08-18 11:16:06 +10:00
|
|
|
#if defined(EXTENDED_STATS)
|
|
|
|
for (i = 0; i < dns_dnstapcounter_max; i++) {
|
|
|
|
dnstapstats_xmldesc[i] = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-08-18 11:16:06 +10:00
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
|
|
|
|
|
|
|
#define SET_DNSTAPSTATDESC(counterid, desc, xmldesc) \
|
|
|
|
do { \
|
|
|
|
set_desc(dns_dnstapcounter_##counterid, dns_dnstapcounter_max, \
|
|
|
|
desc, dnstapstats_desc, xmldesc, \
|
|
|
|
dnstapstats_xmldesc); \
|
|
|
|
dnstapstats_index[i++] = dns_dnstapcounter_##counterid; \
|
|
|
|
} while (0)
|
|
|
|
i = 0;
|
|
|
|
SET_DNSTAPSTATDESC(success, "dnstap messages written", "DNSTAPsuccess");
|
2017-09-14 23:51:19 +00:00
|
|
|
SET_DNSTAPSTATDESC(drop, "dnstap messages dropped", "DNSTAPdropped");
|
2016-08-18 11:16:06 +10:00
|
|
|
INSIST(i == dns_dnstapcounter_max);
|
|
|
|
|
2017-10-06 15:24:16 +05:30
|
|
|
#define SET_GLUECACHESTATDESC(counterid, desc, xmldesc) \
|
|
|
|
do { \
|
|
|
|
set_desc(dns_gluecachestatscounter_##counterid, \
|
|
|
|
dns_gluecachestatscounter_max, desc, \
|
|
|
|
gluecachestats_desc, xmldesc, \
|
|
|
|
gluecachestats_xmldesc); \
|
|
|
|
gluecachestats_index[i++] = \
|
|
|
|
dns_gluecachestatscounter_##counterid; \
|
|
|
|
} while (0)
|
|
|
|
i = 0;
|
|
|
|
SET_GLUECACHESTATDESC(hits_present, "Hits for present glue (cached)",
|
|
|
|
"GLUECACHEhitspresent");
|
|
|
|
SET_GLUECACHESTATDESC(hits_absent,
|
|
|
|
"Hits for non-existent glue (cached)",
|
|
|
|
"GLUECACHEhitsabsent");
|
|
|
|
SET_GLUECACHESTATDESC(inserts_present,
|
|
|
|
"Miss-plus-cache-inserts for present glue",
|
|
|
|
"GLUECACHEinsertspresent");
|
|
|
|
SET_GLUECACHESTATDESC(inserts_absent,
|
|
|
|
"Miss-plus-cache-inserts for non-existent glue",
|
|
|
|
"GLUECACHEinsertsabsent");
|
|
|
|
INSIST(i == dns_gluecachestatscounter_max);
|
|
|
|
|
2008-07-17 23:43:26 +00:00
|
|
|
/* Sanity check */
|
2017-09-08 13:39:09 -07:00
|
|
|
for (i = 0; i < ns_statscounter_max; i++) {
|
2008-07-17 23:43:26 +00:00
|
|
|
INSIST(nsstats_desc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-07-17 23:43:26 +00:00
|
|
|
for (i = 0; i < dns_resstatscounter_max; i++) {
|
|
|
|
INSIST(resstats_desc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-14 10:06:05 -07:00
|
|
|
for (i = 0; i < dns_adbstats_max; i++) {
|
|
|
|
INSIST(adbstats_desc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-07-17 23:43:26 +00:00
|
|
|
for (i = 0; i < dns_zonestatscounter_max; i++) {
|
|
|
|
INSIST(zonestats_desc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2009-01-27 22:30:00 +00:00
|
|
|
for (i = 0; i < isc_sockstatscounter_max; i++) {
|
|
|
|
INSIST(sockstats_desc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-17 10:44:16 -07:00
|
|
|
for (i = 0; i < dns_dnssecstats_max; i++) {
|
|
|
|
INSIST(dnssecstats_desc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-08-18 11:16:06 +10:00
|
|
|
for (i = 0; i < dns_dnstapcounter_max; i++) {
|
|
|
|
INSIST(dnstapstats_desc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-10-06 15:24:16 +05:30
|
|
|
for (i = 0; i < dns_gluecachestatscounter_max; i++) {
|
|
|
|
INSIST(gluecachestats_desc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-05-21 12:06:00 +10:00
|
|
|
#if defined(EXTENDED_STATS)
|
2017-09-08 13:39:09 -07:00
|
|
|
for (i = 0; i < ns_statscounter_max; i++) {
|
2008-07-17 23:43:26 +00:00
|
|
|
INSIST(nsstats_xmldesc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-07-17 23:43:26 +00:00
|
|
|
for (i = 0; i < dns_resstatscounter_max; i++) {
|
|
|
|
INSIST(resstats_xmldesc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-14 10:06:05 -07:00
|
|
|
for (i = 0; i < dns_adbstats_max; i++) {
|
|
|
|
INSIST(adbstats_xmldesc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-07-17 23:43:26 +00:00
|
|
|
for (i = 0; i < dns_zonestatscounter_max; i++) {
|
|
|
|
INSIST(zonestats_xmldesc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2009-01-27 22:30:00 +00:00
|
|
|
for (i = 0; i < isc_sockstatscounter_max; i++) {
|
|
|
|
INSIST(sockstats_xmldesc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-17 10:44:16 -07:00
|
|
|
for (i = 0; i < dns_dnssecstats_max; i++) {
|
|
|
|
INSIST(dnssecstats_xmldesc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-08-18 11:16:06 +10:00
|
|
|
for (i = 0; i < dns_dnstapcounter_max; i++) {
|
|
|
|
INSIST(dnstapstats_xmldesc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-10-06 15:24:16 +05:30
|
|
|
for (i = 0; i < dns_gluecachestatscounter_max; i++) {
|
|
|
|
INSIST(gluecachestats_xmldesc[i] != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-07-17 23:43:26 +00:00
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
2015-07-06 22:20:03 -07:00
|
|
|
|
|
|
|
/* Initialize traffic size statistics */
|
2023-03-16 14:31:46 +00:00
|
|
|
|
|
|
|
for (i = 0; i < DNS_SIZEHISTO_MAXOUT; i++) {
|
|
|
|
udpoutsizestats_index[i] = i;
|
|
|
|
tcpoutsizestats_index[i] = i;
|
|
|
|
udpoutsizestats_desc[i] = get_histo_desc(
|
|
|
|
"responses sent", i, DNS_SIZEHISTO_MAXOUT, false);
|
|
|
|
tcpoutsizestats_desc[i] = udpoutsizestats_desc[i];
|
2015-07-06 22:20:03 -07:00
|
|
|
#if defined(EXTENDED_STATS)
|
2023-03-16 14:31:46 +00:00
|
|
|
udpoutsizestats_xmldesc[i] = get_histo_desc(
|
|
|
|
"responses sent", i, DNS_SIZEHISTO_MAXOUT, true);
|
|
|
|
tcpoutsizestats_xmldesc[i] = udpoutsizestats_xmldesc[i];
|
2015-07-06 22:20:03 -07:00
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
|
|
|
}
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
for (i = 0; i <= DNS_SIZEHISTO_MAXIN; i++) {
|
|
|
|
udpinsizestats_index[i] = i;
|
|
|
|
tcpinsizestats_index[i] = i;
|
|
|
|
udpinsizestats_desc[i] = get_histo_desc(
|
|
|
|
"requests received", i, DNS_SIZEHISTO_MAXIN, false);
|
|
|
|
tcpinsizestats_desc[i] = udpinsizestats_desc[i];
|
2015-07-06 22:20:03 -07:00
|
|
|
#if defined(EXTENDED_STATS)
|
2023-03-16 14:31:46 +00:00
|
|
|
if (i < DNS_SIZEHISTO_MAXIN) {
|
|
|
|
udpinsizestats_xmldesc[i] = udpoutsizestats_xmldesc[i];
|
|
|
|
tcpinsizestats_xmldesc[i] = tcpoutsizestats_xmldesc[i];
|
|
|
|
} else {
|
|
|
|
udpinsizestats_xmldesc[i] =
|
|
|
|
get_histo_desc("requests received", i,
|
|
|
|
DNS_SIZEHISTO_MAXIN, true);
|
|
|
|
tcpinsizestats_xmldesc[i] = udpinsizestats_xmldesc[i];
|
|
|
|
}
|
2015-07-06 22:20:03 -07:00
|
|
|
#endif /* if defined(EXTENDED_STATS) */
|
2023-03-16 14:31:46 +00:00
|
|
|
}
|
2008-07-17 23:43:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Dump callback functions.
|
|
|
|
*/
|
2023-03-16 14:31:46 +00:00
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
dump_counters(isc_statsformat_t type, void *arg, const char *category,
|
|
|
|
const char **desc, int ncounters, int *indices, uint64_t *values,
|
|
|
|
int options);
|
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
static void
|
2018-03-28 14:19:37 +02:00
|
|
|
generalstat_dump(isc_statscounter_t counter, uint64_t val, void *arg) {
|
2008-04-03 05:55:52 +00:00
|
|
|
stats_dumparg_t *dumparg = arg;
|
2009-01-27 22:30:00 +00:00
|
|
|
|
|
|
|
REQUIRE(counter < dumparg->ncounters);
|
|
|
|
dumparg->countervalues[counter] = val;
|
|
|
|
}
|
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
static isc_result_t
|
2023-03-16 14:31:46 +00:00
|
|
|
dump_stats(isc_stats_t *stats, isc_statsformat_t type, void *arg,
|
|
|
|
const char *category, const char **desc, int ncounters, int *indices,
|
|
|
|
uint64_t *values, int options) {
|
|
|
|
stats_dumparg_t dumparg;
|
|
|
|
|
|
|
|
dumparg.type = type;
|
|
|
|
dumparg.ncounters = ncounters;
|
|
|
|
dumparg.counterindices = indices;
|
|
|
|
dumparg.countervalues = values;
|
|
|
|
|
|
|
|
memset(values, 0, sizeof(values[0]) * ncounters);
|
|
|
|
isc_stats_dump(stats, generalstat_dump, &dumparg, options);
|
|
|
|
|
|
|
|
return dump_counters(type, arg, category, desc, ncounters, indices,
|
|
|
|
values, options);
|
|
|
|
}
|
|
|
|
|
2023-04-12 16:00:39 +10:00
|
|
|
#if defined(EXTENDED_STATS)
|
2023-03-16 14:31:46 +00:00
|
|
|
static isc_result_t
|
|
|
|
dump_histo(isc_histomulti_t *hm, isc_statsformat_t type, void *arg,
|
|
|
|
const char *category, const char **desc, int ncounters, int *indices,
|
|
|
|
uint64_t *values, int options) {
|
|
|
|
isc_histo_t *hg = NULL;
|
|
|
|
|
|
|
|
isc_histomulti_merge(&hg, hm);
|
|
|
|
for (int i = 0; i < ncounters; i++) {
|
|
|
|
isc_histo_get(hg, i, NULL, NULL, &values[i]);
|
|
|
|
}
|
|
|
|
isc_histo_destroy(&hg);
|
|
|
|
|
|
|
|
return dump_counters(type, arg, category, desc, ncounters, indices,
|
|
|
|
values, options);
|
|
|
|
}
|
2023-04-12 16:00:39 +10:00
|
|
|
#endif /* defined(EXTENDED_STATS) */
|
2023-03-16 14:31:46 +00:00
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
dump_counters(isc_statsformat_t type, void *arg, const char *category,
|
|
|
|
const char **desc, int ncounters, int *indices, uint64_t *values,
|
|
|
|
int options) {
|
2015-02-27 10:55:55 +11:00
|
|
|
int i, idx;
|
2018-03-28 14:19:37 +02:00
|
|
|
uint64_t value;
|
2008-04-03 05:55:52 +00:00
|
|
|
FILE *fp;
|
|
|
|
#ifdef HAVE_LIBXML2
|
2019-06-24 14:25:55 +02:00
|
|
|
void *writer;
|
2010-02-04 00:57:25 +00:00
|
|
|
int xmlrc;
|
2008-04-03 05:55:52 +00:00
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2013-03-13 14:24:50 -07:00
|
|
|
json_object *job, *cat, *counter;
|
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2014-05-21 12:06:00 +10:00
|
|
|
#if !defined(EXTENDED_STATS)
|
2009-01-29 05:11:29 +00:00
|
|
|
UNUSED(category);
|
|
|
|
#endif /* if !defined(EXTENDED_STATS) */
|
|
|
|
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2013-03-13 14:24:50 -07:00
|
|
|
cat = job = (json_object *)arg;
|
|
|
|
if (ncounters > 0 && type == isc_statsformat_json) {
|
|
|
|
if (category != NULL) {
|
|
|
|
cat = json_object_new_object();
|
|
|
|
if (cat == NULL) {
|
|
|
|
return ISC_R_NOMEMORY;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
json_object_object_add(job, category, cat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
|
|
|
|
2009-01-27 22:30:00 +00:00
|
|
|
for (i = 0; i < ncounters; i++) {
|
2015-02-27 10:55:55 +11:00
|
|
|
idx = indices[i];
|
|
|
|
value = values[idx];
|
2009-01-27 22:30:00 +00:00
|
|
|
|
|
|
|
if (value == 0 && (options & ISC_STATSDUMP_VERBOSE) == 0) {
|
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2009-01-27 22:30:00 +00:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
switch (type) {
|
2012-05-14 10:06:05 -07:00
|
|
|
case isc_statsformat_file:
|
2009-01-27 22:30:00 +00:00
|
|
|
fp = arg;
|
2018-03-28 14:56:40 +02:00
|
|
|
fprintf(fp, "%20" PRIu64 " %s\n", value, desc[idx]);
|
2009-01-27 22:30:00 +00:00
|
|
|
break;
|
2012-05-14 10:06:05 -07:00
|
|
|
case isc_statsformat_xml:
|
2009-01-27 22:30:00 +00:00
|
|
|
#ifdef HAVE_LIBXML2
|
2019-06-24 14:25:55 +02:00
|
|
|
writer = arg;
|
2009-01-27 22:30:00 +00:00
|
|
|
|
|
|
|
if (category != NULL) {
|
2012-11-14 12:44:15 -06:00
|
|
|
/* <NameOfCategory> */
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(
|
|
|
|
writer, ISC_XMLCHAR category));
|
2012-11-14 12:44:15 -06:00
|
|
|
|
|
|
|
/* <name> inside category */
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(
|
|
|
|
writer, ISC_XMLCHAR "name"));
|
|
|
|
TRY0(xmlTextWriterWriteString(
|
2015-02-27 10:55:55 +11:00
|
|
|
writer, ISC_XMLCHAR desc[idx]));
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
/* </name> */
|
2010-02-04 00:57:25 +00:00
|
|
|
|
2012-11-14 12:44:15 -06:00
|
|
|
/* <counter> */
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(
|
|
|
|
writer, ISC_XMLCHAR "counter"));
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterWriteFormatString(
|
2018-03-28 14:56:40 +02:00
|
|
|
writer, "%" PRIu64, value));
|
2012-11-14 12:44:15 -06:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
/* </counter> */
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
/* </NameOfCategory> */
|
2009-01-27 22:30:00 +00:00
|
|
|
} else {
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(
|
2012-11-14 12:44:15 -06:00
|
|
|
writer, ISC_XMLCHAR "counter"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(
|
|
|
|
writer, ISC_XMLCHAR "name",
|
2015-02-27 10:55:55 +11:00
|
|
|
ISC_XMLCHAR desc[idx]));
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterWriteFormatString(
|
2018-03-28 14:56:40 +02:00
|
|
|
writer, "%" PRIu64, value));
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
/* counter */
|
2009-01-27 22:30:00 +00:00
|
|
|
}
|
2012-11-14 12:44:15 -06:00
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2009-01-27 22:30:00 +00:00
|
|
|
break;
|
2013-03-13 14:24:50 -07:00
|
|
|
case isc_statsformat_json:
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2013-03-13 14:24:50 -07:00
|
|
|
counter = json_object_new_int64(value);
|
|
|
|
if (counter == NULL) {
|
|
|
|
return ISC_R_NOMEMORY;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-02-27 10:55:55 +11:00
|
|
|
json_object_object_add(cat, desc[idx], counter);
|
2013-03-13 14:24:50 -07:00
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
2013-03-14 11:13:39 +11:00
|
|
|
break;
|
2009-01-27 22:30:00 +00:00
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
2010-02-04 00:57:25 +00:00
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
#ifdef HAVE_LIBXML2
|
2020-07-09 19:36:10 -07:00
|
|
|
cleanup:
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR, "failed at dump_counters()");
|
2010-02-04 00:57:25 +00:00
|
|
|
return ISC_R_FAILURE;
|
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2018-03-28 14:19:37 +02:00
|
|
|
rdtypestat_dump(dns_rdatastatstype_t type, uint64_t val, void *arg) {
|
2008-04-03 05:55:52 +00:00
|
|
|
char typebuf[64];
|
|
|
|
const char *typestr;
|
|
|
|
stats_dumparg_t *dumparg = arg;
|
|
|
|
FILE *fp;
|
|
|
|
#ifdef HAVE_LIBXML2
|
2019-06-24 14:25:55 +02:00
|
|
|
void *writer;
|
2010-02-04 00:57:25 +00:00
|
|
|
int xmlrc;
|
2008-04-03 05:55:52 +00:00
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2013-03-13 14:24:50 -07:00
|
|
|
json_object *zoneobj, *obj;
|
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
2008-04-03 05:55:52 +00:00
|
|
|
|
|
|
|
if ((DNS_RDATASTATSTYPE_ATTR(type) &
|
2022-11-02 19:33:14 +01:00
|
|
|
DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) == 0)
|
|
|
|
{
|
2008-04-03 05:55:52 +00:00
|
|
|
dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf,
|
|
|
|
sizeof(typebuf));
|
|
|
|
typestr = typebuf;
|
|
|
|
} else {
|
|
|
|
typestr = "Others";
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
|
|
|
|
switch (dumparg->type) {
|
2012-05-14 10:06:05 -07:00
|
|
|
case isc_statsformat_file:
|
2008-04-03 05:55:52 +00:00
|
|
|
fp = dumparg->arg;
|
2018-03-28 14:56:40 +02:00
|
|
|
fprintf(fp, "%20" PRIu64 " %s\n", val, typestr);
|
2008-04-03 05:55:52 +00:00
|
|
|
break;
|
2012-05-14 10:06:05 -07:00
|
|
|
case isc_statsformat_xml:
|
2008-04-03 05:55:52 +00:00
|
|
|
#ifdef HAVE_LIBXML2
|
|
|
|
writer = dumparg->arg;
|
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
|
|
|
|
ISC_XMLCHAR typestr));
|
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, val));
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* type */
|
2013-03-13 14:24:50 -07:00
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
|
|
|
break;
|
|
|
|
case isc_statsformat_json:
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2013-03-13 14:24:50 -07:00
|
|
|
zoneobj = (json_object *)dumparg->arg;
|
|
|
|
obj = json_object_new_int64(val);
|
|
|
|
if (obj == NULL) {
|
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
json_object_object_add(zoneobj, typestr, obj);
|
2008-04-03 05:55:52 +00:00
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
|
|
|
break;
|
|
|
|
}
|
2010-02-04 00:57:25 +00:00
|
|
|
return;
|
|
|
|
#ifdef HAVE_LIBXML2
|
2020-07-09 19:36:10 -07:00
|
|
|
cleanup:
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR, "failed at rdtypestat_dump()");
|
2010-02-04 00:57:25 +00:00
|
|
|
dumparg->result = ISC_R_FAILURE;
|
|
|
|
return;
|
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
|
2019-08-05 16:34:28 +02:00
|
|
|
static bool
|
|
|
|
rdatastatstype_attr(dns_rdatastatstype_t type, unsigned int attr) {
|
|
|
|
return (DNS_RDATASTATSTYPE_ATTR(type) & attr) != 0;
|
|
|
|
}
|
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
static void
|
2018-03-28 14:19:37 +02:00
|
|
|
rdatasetstats_dump(dns_rdatastatstype_t type, uint64_t val, void *arg) {
|
2008-04-03 05:55:52 +00:00
|
|
|
stats_dumparg_t *dumparg = arg;
|
|
|
|
FILE *fp;
|
|
|
|
char typebuf[64];
|
|
|
|
const char *typestr;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool nxrrset = false;
|
|
|
|
bool stale = false;
|
2019-08-05 16:34:28 +02:00
|
|
|
bool ancient = false;
|
2008-04-03 05:55:52 +00:00
|
|
|
#ifdef HAVE_LIBXML2
|
2019-06-24 14:25:55 +02:00
|
|
|
void *writer;
|
2010-02-04 00:57:25 +00:00
|
|
|
int xmlrc;
|
2008-04-03 05:55:52 +00:00
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2013-03-13 14:24:50 -07:00
|
|
|
json_object *zoneobj, *obj;
|
|
|
|
char buf[1024];
|
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
2008-04-03 05:55:52 +00:00
|
|
|
|
|
|
|
if ((DNS_RDATASTATSTYPE_ATTR(type) &
|
2022-11-02 19:33:14 +01:00
|
|
|
DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) != 0)
|
|
|
|
{
|
2008-04-03 05:55:52 +00:00
|
|
|
typestr = "NXDOMAIN";
|
|
|
|
} else if ((DNS_RDATASTATSTYPE_ATTR(type) &
|
|
|
|
DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) != 0)
|
|
|
|
{
|
|
|
|
typestr = "Others";
|
|
|
|
} else {
|
|
|
|
dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf,
|
|
|
|
sizeof(typebuf));
|
|
|
|
typestr = typebuf;
|
|
|
|
}
|
|
|
|
|
2019-08-05 16:34:28 +02:00
|
|
|
nxrrset = rdatastatstype_attr(type, DNS_RDATASTATSTYPE_ATTR_NXRRSET);
|
|
|
|
stale = rdatastatstype_attr(type, DNS_RDATASTATSTYPE_ATTR_STALE);
|
|
|
|
ancient = rdatastatstype_attr(type, DNS_RDATASTATSTYPE_ATTR_ANCIENT);
|
2012-06-08 16:32:44 +10:00
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
switch (dumparg->type) {
|
2012-05-14 10:06:05 -07:00
|
|
|
case isc_statsformat_file:
|
2008-04-03 05:55:52 +00:00
|
|
|
fp = dumparg->arg;
|
2019-08-05 16:34:28 +02:00
|
|
|
fprintf(fp, "%20" PRIu64 " %s%s%s%s\n", val, ancient ? "~" : "",
|
|
|
|
stale ? "#" : "", nxrrset ? "!" : "", typestr);
|
2008-04-03 05:55:52 +00:00
|
|
|
break;
|
2012-05-14 10:06:05 -07:00
|
|
|
case isc_statsformat_xml:
|
2008-04-03 05:55:52 +00:00
|
|
|
#ifdef HAVE_LIBXML2
|
|
|
|
writer = dumparg->arg;
|
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset"));
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
|
2019-08-05 16:34:28 +02:00
|
|
|
TRY0(xmlTextWriterWriteFormatString(
|
|
|
|
writer, "%s%s%s%s", ancient ? "~" : "",
|
2010-02-04 00:57:25 +00:00
|
|
|
stale ? "#" : "", nxrrset ? "!" : "", typestr));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* name */
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
|
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, val));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* counter */
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* rrset */
|
2013-03-13 14:24:50 -07:00
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
|
|
|
break;
|
|
|
|
case isc_statsformat_json:
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2013-03-13 14:24:50 -07:00
|
|
|
zoneobj = (json_object *)dumparg->arg;
|
2019-08-05 16:34:28 +02:00
|
|
|
snprintf(buf, sizeof(buf), "%s%s%s%s", ancient ? "~" : "",
|
2017-10-03 14:54:19 +11:00
|
|
|
stale ? "#" : "", nxrrset ? "!" : "", typestr);
|
2013-03-13 14:24:50 -07:00
|
|
|
obj = json_object_new_int64(val);
|
|
|
|
if (obj == NULL) {
|
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
json_object_object_add(zoneobj, buf, obj);
|
2008-04-03 05:55:52 +00:00
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
|
|
|
break;
|
|
|
|
}
|
2010-02-04 00:57:25 +00:00
|
|
|
return;
|
|
|
|
#ifdef HAVE_LIBXML2
|
2020-07-09 19:36:10 -07:00
|
|
|
cleanup:
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR, "failed at rdatasetstats_dump()");
|
2010-02-04 00:57:25 +00:00
|
|
|
dumparg->result = ISC_R_FAILURE;
|
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2018-03-28 14:19:37 +02:00
|
|
|
opcodestat_dump(dns_opcode_t code, uint64_t val, void *arg) {
|
2011-03-11 06:11:27 +00:00
|
|
|
FILE *fp;
|
2008-04-03 05:55:52 +00:00
|
|
|
isc_buffer_t b;
|
|
|
|
char codebuf[64];
|
|
|
|
stats_dumparg_t *dumparg = arg;
|
|
|
|
#ifdef HAVE_LIBXML2
|
2019-06-24 14:25:55 +02:00
|
|
|
void *writer;
|
2010-02-04 00:57:25 +00:00
|
|
|
int xmlrc;
|
2008-04-03 05:55:52 +00:00
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2013-03-13 14:24:50 -07:00
|
|
|
json_object *zoneobj, *obj;
|
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
2008-04-03 05:55:52 +00:00
|
|
|
|
|
|
|
isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1);
|
|
|
|
dns_opcode_totext(code, &b);
|
|
|
|
codebuf[isc_buffer_usedlength(&b)] = '\0';
|
|
|
|
|
|
|
|
switch (dumparg->type) {
|
2012-05-14 10:06:05 -07:00
|
|
|
case isc_statsformat_file:
|
2008-04-03 05:55:52 +00:00
|
|
|
fp = dumparg->arg;
|
2018-03-28 14:56:40 +02:00
|
|
|
fprintf(fp, "%20" PRIu64 " %s\n", val, codebuf);
|
2008-04-03 05:55:52 +00:00
|
|
|
break;
|
2012-05-14 10:06:05 -07:00
|
|
|
case isc_statsformat_xml:
|
2008-04-03 05:55:52 +00:00
|
|
|
#ifdef HAVE_LIBXML2
|
|
|
|
writer = dumparg->arg;
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
|
|
|
|
ISC_XMLCHAR codebuf));
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, val));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* counter */
|
2013-03-13 14:24:50 -07:00
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
|
|
|
break;
|
|
|
|
case isc_statsformat_json:
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2013-03-13 14:24:50 -07:00
|
|
|
zoneobj = (json_object *)dumparg->arg;
|
|
|
|
obj = json_object_new_int64(val);
|
|
|
|
if (obj == NULL) {
|
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
json_object_object_add(zoneobj, codebuf, obj);
|
2008-04-03 05:55:52 +00:00
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
|
|
|
break;
|
|
|
|
}
|
2010-02-04 00:57:25 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBXML2
|
2020-07-09 19:36:10 -07:00
|
|
|
cleanup:
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR, "failed at opcodestat_dump()");
|
2010-02-04 00:57:25 +00:00
|
|
|
dumparg->result = ISC_R_FAILURE;
|
|
|
|
return;
|
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
|
2016-06-23 08:44:54 +10:00
|
|
|
static void
|
2018-03-28 14:19:37 +02:00
|
|
|
rcodestat_dump(dns_rcode_t code, uint64_t val, void *arg) {
|
2016-06-23 08:44:54 +10:00
|
|
|
FILE *fp;
|
|
|
|
isc_buffer_t b;
|
|
|
|
char codebuf[64];
|
|
|
|
stats_dumparg_t *dumparg = arg;
|
|
|
|
#ifdef HAVE_LIBXML2
|
2019-06-24 14:25:55 +02:00
|
|
|
void *writer;
|
2016-06-23 08:44:54 +10:00
|
|
|
int xmlrc;
|
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2016-06-23 08:44:54 +10:00
|
|
|
json_object *zoneobj, *obj;
|
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
|
|
|
|
|
|
|
isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1);
|
|
|
|
dns_rcode_totext(code, &b);
|
|
|
|
codebuf[isc_buffer_usedlength(&b)] = '\0';
|
|
|
|
|
|
|
|
switch (dumparg->type) {
|
|
|
|
case isc_statsformat_file:
|
|
|
|
fp = dumparg->arg;
|
2018-03-28 14:56:40 +02:00
|
|
|
fprintf(fp, "%20" PRIu64 " %s\n", val, codebuf);
|
2016-06-23 08:44:54 +10:00
|
|
|
break;
|
|
|
|
case isc_statsformat_xml:
|
|
|
|
#ifdef HAVE_LIBXML2
|
|
|
|
writer = dumparg->arg;
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
|
|
|
|
ISC_XMLCHAR codebuf));
|
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, val));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* counter */
|
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
|
|
|
break;
|
|
|
|
case isc_statsformat_json:
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2016-06-23 08:44:54 +10:00
|
|
|
zoneobj = (json_object *)dumparg->arg;
|
|
|
|
obj = json_object_new_int64(val);
|
|
|
|
if (obj == NULL) {
|
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-06-23 08:44:54 +10:00
|
|
|
json_object_object_add(zoneobj, codebuf, obj);
|
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBXML2
|
2020-07-09 19:36:10 -07:00
|
|
|
cleanup:
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR, "failed at rcodestat_dump()");
|
2016-06-23 08:44:54 +10:00
|
|
|
dumparg->result = ISC_R_FAILURE;
|
|
|
|
return;
|
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
|
|
|
}
|
|
|
|
|
2019-07-09 18:08:49 +02:00
|
|
|
#if defined(EXTENDED_STATS)
|
2019-06-19 16:02:50 +02:00
|
|
|
static void
|
2022-09-08 09:48:27 +10:00
|
|
|
dnssecsignstat_dump(uint32_t kval, uint64_t val, void *arg) {
|
2019-06-19 16:02:50 +02:00
|
|
|
FILE *fp;
|
|
|
|
char tagbuf[64];
|
|
|
|
stats_dumparg_t *dumparg = arg;
|
|
|
|
#ifdef HAVE_LIBXML2
|
|
|
|
xmlTextWriterPtr writer;
|
|
|
|
int xmlrc;
|
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2019-06-21 10:30:05 +02:00
|
|
|
#ifdef HAVE_JSON_C
|
2019-06-19 16:02:50 +02:00
|
|
|
json_object *zoneobj, *obj;
|
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
|
|
|
|
2022-09-08 09:48:27 +10:00
|
|
|
/*
|
|
|
|
* kval is '(algorithm << 16) | keyid'.
|
|
|
|
*/
|
|
|
|
snprintf(tagbuf, sizeof(tagbuf), "%u+%u", (kval >> 16) & 0xff,
|
|
|
|
kval & 0xffff);
|
2019-06-19 16:02:50 +02:00
|
|
|
|
|
|
|
switch (dumparg->type) {
|
|
|
|
case isc_statsformat_file:
|
|
|
|
fp = dumparg->arg;
|
|
|
|
fprintf(fp, "%20" PRIu64 " %s\n", val, tagbuf);
|
|
|
|
break;
|
|
|
|
case isc_statsformat_xml:
|
|
|
|
#ifdef HAVE_LIBXML2
|
|
|
|
writer = dumparg->arg;
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
|
|
|
|
ISC_XMLCHAR tagbuf));
|
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, val));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* counter */
|
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
|
|
|
break;
|
|
|
|
case isc_statsformat_json:
|
2019-06-21 10:30:05 +02:00
|
|
|
#ifdef HAVE_JSON_C
|
2019-06-19 16:02:50 +02:00
|
|
|
zoneobj = (json_object *)dumparg->arg;
|
|
|
|
obj = json_object_new_int64(val);
|
|
|
|
if (obj == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
json_object_object_add(zoneobj, tagbuf, obj);
|
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
#ifdef HAVE_LIBXML2
|
2020-07-09 19:36:10 -07:00
|
|
|
cleanup:
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR, "failed at dnssecsignstat_dump()");
|
2019-06-19 16:02:50 +02:00
|
|
|
dumparg->result = ISC_R_FAILURE;
|
|
|
|
return;
|
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
|
|
|
}
|
2019-07-09 18:08:49 +02:00
|
|
|
#endif /* defined(EXTENDED_STATS) */
|
2019-06-19 16:02:50 +02:00
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
#ifdef HAVE_LIBXML2
|
2014-01-09 15:14:57 -08:00
|
|
|
/*
|
|
|
|
* Which statistics to include when rendering to XML
|
|
|
|
*/
|
|
|
|
#define STATS_XML_STATUS 0x00 /* display only common statistics */
|
|
|
|
#define STATS_XML_SERVER 0x01
|
|
|
|
#define STATS_XML_ZONES 0x02
|
2023-05-30 14:58:29 +00:00
|
|
|
#define STATS_XML_XFRINS 0x04
|
2014-01-09 15:14:57 -08:00
|
|
|
#define STATS_XML_NET 0x08
|
|
|
|
#define STATS_XML_MEM 0x10
|
2015-07-06 22:20:03 -07:00
|
|
|
#define STATS_XML_TRAFFIC 0x20
|
2014-01-09 15:14:57 -08:00
|
|
|
#define STATS_XML_ALL 0xff
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
static isc_result_t
|
|
|
|
zone_xmlrender(dns_zone_t *zone, void *arg) {
|
2013-02-27 11:53:58 -08:00
|
|
|
isc_result_t result;
|
2008-04-03 05:55:52 +00:00
|
|
|
char buf[1024 + 32]; /* sufficiently large for zone name and class */
|
|
|
|
dns_rdataclass_t rdclass;
|
2018-03-28 14:19:37 +02:00
|
|
|
uint32_t serial;
|
2008-04-03 05:55:52 +00:00
|
|
|
xmlTextWriterPtr writer = arg;
|
2013-02-27 11:53:58 -08:00
|
|
|
dns_zonestat_level_t statlevel;
|
2010-02-04 00:57:25 +00:00
|
|
|
int xmlrc;
|
2013-02-28 11:21:54 +11:00
|
|
|
stats_dumparg_t dumparg;
|
2015-10-28 09:45:46 +11:00
|
|
|
const char *ztype;
|
2020-07-09 19:36:10 -07:00
|
|
|
isc_time_t timestamp;
|
2013-02-27 11:53:58 -08:00
|
|
|
|
|
|
|
statlevel = dns_zone_getstatlevel(zone);
|
|
|
|
if (statlevel == dns_zonestat_none) {
|
|
|
|
return ISC_R_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2012-11-14 12:44:15 -06:00
|
|
|
dumparg.type = isc_statsformat_xml;
|
|
|
|
dumparg.arg = writer;
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone"));
|
2013-02-27 11:53:58 -08:00
|
|
|
|
2015-06-29 18:33:18 +05:30
|
|
|
dns_zone_nameonly(zone, buf, sizeof(buf));
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
|
2015-06-29 18:33:18 +05:30
|
|
|
ISC_XMLCHAR buf));
|
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
rdclass = dns_zone_getclass(zone);
|
|
|
|
dns_rdataclass_format(rdclass, buf, sizeof(buf));
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "rdataclass",
|
|
|
|
ISC_XMLCHAR buf));
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2015-10-28 09:45:46 +11:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"));
|
|
|
|
ztype = user_zonetype(zone);
|
|
|
|
if (ztype != NULL) {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR ztype));
|
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "unknown"));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-10-28 09:45:46 +11:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* type */
|
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial"));
|
2018-04-03 16:34:41 +02:00
|
|
|
if (dns_zone_getserial(zone, &serial) == ISC_R_SUCCESS) {
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%u", serial));
|
2009-10-05 19:39:20 +00:00
|
|
|
} else {
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* serial */
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2019-10-30 17:06:06 -05:00
|
|
|
/*
|
|
|
|
* Export zone timers to the statistics channel in XML format. For
|
2021-10-05 11:07:44 +02:00
|
|
|
* primary zones, only include the loaded time. For secondary zones,
|
|
|
|
* also include the expire and refresh times.
|
2019-10-30 17:06:06 -05:00
|
|
|
*/
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dns_zone_getloadtime(zone, ×tamp));
|
2019-10-30 17:06:06 -05:00
|
|
|
|
|
|
|
isc_time_formatISO8601(×tamp, buf, 64);
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "loaded"));
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
2021-08-25 22:29:25 -07:00
|
|
|
if (dns_zone_gettype(zone) == dns_zone_secondary) {
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dns_zone_getexpiretime(zone, ×tamp));
|
2019-10-30 17:06:06 -05:00
|
|
|
isc_time_formatISO8601(×tamp, buf, 64);
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "expires"));
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dns_zone_getrefreshtime(zone, ×tamp));
|
2019-10-30 17:06:06 -05:00
|
|
|
isc_time_formatISO8601(×tamp, buf, 64);
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "refresh"));
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
}
|
|
|
|
|
2017-10-06 15:24:16 +05:30
|
|
|
if (statlevel == dns_zonestat_full) {
|
2024-12-06 19:46:39 +01:00
|
|
|
isc_stats_t *zonestats;
|
2017-10-06 15:24:16 +05:30
|
|
|
isc_stats_t *gluecachestats;
|
2024-12-06 19:46:39 +01:00
|
|
|
dns_stats_t *rcvquerystats;
|
|
|
|
dns_stats_t *dnssecsignstats;
|
2018-03-28 14:19:37 +02:00
|
|
|
uint64_t nsstat_values[ns_statscounter_max];
|
|
|
|
uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
|
2012-11-14 12:44:15 -06:00
|
|
|
|
2024-12-06 19:46:39 +01:00
|
|
|
zonestats = dns_zone_getrequeststats(zone);
|
2017-10-06 15:24:16 +05:30
|
|
|
if (zonestats != NULL) {
|
|
|
|
TRY0(xmlTextWriterStartElement(writer,
|
|
|
|
ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer,
|
|
|
|
ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "rcode"));
|
2012-11-14 12:44:15 -06:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_stats(zonestats, isc_statsformat_xml, writer,
|
|
|
|
NULL, nsstats_xmldesc,
|
|
|
|
ns_statscounter_max, nsstats_index,
|
|
|
|
nsstat_values, ISC_STATSDUMP_VERBOSE));
|
2017-10-06 15:24:16 +05:30
|
|
|
/* counters type="rcode"*/
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
}
|
2012-11-14 12:44:15 -06:00
|
|
|
|
2017-10-06 15:24:16 +05:30
|
|
|
gluecachestats = dns_zone_getgluecachestats(zone);
|
|
|
|
if (gluecachestats != NULL) {
|
|
|
|
TRY0(xmlTextWriterStartElement(writer,
|
|
|
|
ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(
|
2019-06-21 10:30:05 +02:00
|
|
|
writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "gluecache"));
|
2020-02-12 13:59:18 +01:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_stats(gluecachestats, isc_statsformat_xml,
|
|
|
|
writer, NULL, gluecachestats_xmldesc,
|
|
|
|
dns_gluecachestatscounter_max,
|
|
|
|
gluecachestats_index,
|
|
|
|
gluecachestats_values,
|
|
|
|
ISC_STATSDUMP_VERBOSE));
|
2017-10-06 15:24:16 +05:30
|
|
|
/* counters type="rcode"*/
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
}
|
2012-11-14 12:44:15 -06:00
|
|
|
|
2024-12-06 19:46:39 +01:00
|
|
|
rcvquerystats = dns_zone_getrcvquerystats(zone);
|
2017-10-06 15:24:16 +05:30
|
|
|
if (rcvquerystats != NULL) {
|
|
|
|
TRY0(xmlTextWriterStartElement(writer,
|
|
|
|
ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer,
|
|
|
|
ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "qtype"));
|
|
|
|
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump,
|
|
|
|
&dumparg, 0);
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dumparg.result);
|
2017-10-06 15:24:16 +05:30
|
|
|
|
|
|
|
/* counters type="qtype"*/
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
}
|
2019-06-19 16:02:50 +02:00
|
|
|
|
2024-12-06 19:46:39 +01:00
|
|
|
dnssecsignstats = dns_zone_getdnssecsignstats(zone);
|
2019-06-19 16:02:50 +02:00
|
|
|
if (dnssecsignstats != NULL) {
|
Redesign dnssec sign statistics
The first attempt to add DNSSEC sign statistics was naive: for each
zone we allocated 64K counters, twice. In reality each zone has at
most four keys, so the new approach only has room for four keys per
zone. If after a rollover more keys have signed the zone, existing
keys are rotated out.
The DNSSEC sign statistics has three counters per key, so twelve
counters per zone. First counter is actually a key id, so it is
clear what key contributed to the metrics. The second counter
tracks the number of generated signatures, and the third tracks
how many of those are refreshes.
This means that in the zone structure we no longer need two separate
references to DNSSEC sign metrics: both the resign and refresh stats
are kept in a single dns_stats structure.
Incrementing dnssecsignstats:
Whenever a dnssecsignstat is incremented, we look up the key id
to see if we already are counting metrics for this key. If so,
we update the corresponding operation counter (resign or
refresh).
If the key is new, store the value in a new counter and increment
corresponding counter.
If all slots are full, we rotate the keys and overwrite the last
slot with the new key.
Dumping dnssecsignstats:
Dumping dnssecsignstats is no longer a simple wrapper around
isc_stats_dump, but uses the same principle. The difference is that
rather than dumping the index (key tag) and counter, we have to look
up the corresponding counter.
2020-03-26 16:02:36 +01:00
|
|
|
/* counters type="dnssec-sign"*/
|
2019-06-19 16:02:50 +02:00
|
|
|
TRY0(xmlTextWriterStartElement(writer,
|
|
|
|
ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(
|
2019-06-21 10:30:05 +02:00
|
|
|
writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "dnssec-sign"));
|
2019-06-19 16:02:50 +02:00
|
|
|
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
2020-04-02 16:12:10 +02:00
|
|
|
dns_dnssecsignstats_dump(
|
|
|
|
dnssecsignstats, dns_dnssecsignstats_sign,
|
|
|
|
dnssecsignstat_dump, &dumparg, 0);
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dumparg.result);
|
2019-06-19 16:02:50 +02:00
|
|
|
|
2019-06-21 10:30:05 +02:00
|
|
|
/* counters type="dnssec-sign"*/
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
Redesign dnssec sign statistics
The first attempt to add DNSSEC sign statistics was naive: for each
zone we allocated 64K counters, twice. In reality each zone has at
most four keys, so the new approach only has room for four keys per
zone. If after a rollover more keys have signed the zone, existing
keys are rotated out.
The DNSSEC sign statistics has three counters per key, so twelve
counters per zone. First counter is actually a key id, so it is
clear what key contributed to the metrics. The second counter
tracks the number of generated signatures, and the third tracks
how many of those are refreshes.
This means that in the zone structure we no longer need two separate
references to DNSSEC sign metrics: both the resign and refresh stats
are kept in a single dns_stats structure.
Incrementing dnssecsignstats:
Whenever a dnssecsignstat is incremented, we look up the key id
to see if we already are counting metrics for this key. If so,
we update the corresponding operation counter (resign or
refresh).
If the key is new, store the value in a new counter and increment
corresponding counter.
If all slots are full, we rotate the keys and overwrite the last
slot with the new key.
Dumping dnssecsignstats:
Dumping dnssecsignstats is no longer a simple wrapper around
isc_stats_dump, but uses the same principle. The difference is that
rather than dumping the index (key tag) and counter, we have to look
up the corresponding counter.
2020-03-26 16:02:36 +01:00
|
|
|
/* counters type="dnssec-refresh"*/
|
2019-06-21 10:30:05 +02:00
|
|
|
TRY0(xmlTextWriterStartElement(writer,
|
|
|
|
ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(
|
|
|
|
writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "dnssec-refresh"));
|
|
|
|
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
2020-04-02 16:12:10 +02:00
|
|
|
dns_dnssecsignstats_dump(
|
|
|
|
dnssecsignstats, dns_dnssecsignstats_refresh,
|
|
|
|
dnssecsignstat_dump, &dumparg, 0);
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dumparg.result);
|
2019-06-21 10:30:05 +02:00
|
|
|
|
|
|
|
/* counters type="dnssec-refresh"*/
|
2019-06-19 16:02:50 +02:00
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* zone */
|
2008-04-03 05:55:52 +00:00
|
|
|
|
|
|
|
return ISC_R_SUCCESS;
|
2020-07-09 19:36:10 -07:00
|
|
|
cleanup:
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR, "Failed at zone_xmlrender()");
|
2010-02-04 00:57:25 +00:00
|
|
|
return ISC_R_FAILURE;
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2023-05-30 14:58:29 +00:00
|
|
|
static isc_result_t
|
|
|
|
xfrin_xmlrender(dns_zone_t *zone, void *arg) {
|
|
|
|
char buf[1024 + 32]; /* sufficiently large for zone name and class */
|
|
|
|
dns_rdataclass_t rdclass;
|
|
|
|
const char *ztype;
|
|
|
|
uint32_t serial;
|
2023-09-15 10:47:17 +00:00
|
|
|
isc_sockaddr_t addr;
|
2023-05-30 14:58:29 +00:00
|
|
|
const isc_sockaddr_t *addrp = NULL;
|
|
|
|
char addr_buf[ISC_SOCKADDR_FORMATSIZE];
|
2023-08-23 10:46:44 +00:00
|
|
|
dns_transport_type_t transport_type;
|
2023-05-30 14:58:29 +00:00
|
|
|
xmlTextWriterPtr writer = arg;
|
|
|
|
dns_zonestat_level_t statlevel;
|
|
|
|
int xmlrc;
|
|
|
|
dns_xfrin_t *xfr = NULL;
|
2023-11-10 11:06:08 +00:00
|
|
|
bool is_firstrefresh, is_running, is_deferred, is_presoa, is_pending;
|
2023-05-30 14:58:29 +00:00
|
|
|
bool needs_refresh;
|
|
|
|
bool is_first_data_received, is_ixfr;
|
|
|
|
unsigned int nmsg = 0;
|
|
|
|
unsigned int nrecs = 0;
|
|
|
|
uint64_t nbytes = 0;
|
2024-11-27 10:34:40 +00:00
|
|
|
uint64_t rate = 0;
|
2023-05-30 14:58:29 +00:00
|
|
|
|
|
|
|
statlevel = dns_zone_getstatlevel(zone);
|
|
|
|
if (statlevel == dns_zonestat_none) {
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2023-11-10 11:06:08 +00:00
|
|
|
if (dns_zone_getxfr(zone, &xfr, &is_firstrefresh, &is_running,
|
|
|
|
&is_deferred, &is_presoa, &is_pending,
|
|
|
|
&needs_refresh) != ISC_R_SUCCESS)
|
2023-09-25 09:38:03 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Failed to get information about the zone's incoming transfer
|
|
|
|
* (if any), but we still want to continue generating the
|
|
|
|
* remaining parts of the output.
|
|
|
|
*/
|
|
|
|
return ISC_R_SUCCESS;
|
2023-05-30 14:58:29 +00:00
|
|
|
}
|
|
|
|
|
2023-09-15 08:57:21 +00:00
|
|
|
if (!is_running && !is_deferred && !is_presoa && !is_pending &&
|
|
|
|
!needs_refresh)
|
|
|
|
{
|
2023-09-25 09:38:03 +00:00
|
|
|
if (xfr != NULL) {
|
|
|
|
dns_xfrin_detach(&xfr);
|
|
|
|
}
|
2023-05-30 14:58:29 +00:00
|
|
|
/* No ongoing/queued transfer. */
|
2023-09-25 09:38:03 +00:00
|
|
|
return ISC_R_SUCCESS;
|
2023-05-30 14:58:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (is_running && xfr == NULL) {
|
|
|
|
/* The transfer is finished, and it's shutting down. */
|
2023-09-25 09:38:03 +00:00
|
|
|
return ISC_R_SUCCESS;
|
2023-05-30 14:58:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "xfrin"));
|
|
|
|
|
|
|
|
dns_zone_nameonly(zone, buf, sizeof(buf));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
|
|
|
|
ISC_XMLCHAR buf));
|
|
|
|
|
|
|
|
rdclass = dns_zone_getclass(zone);
|
|
|
|
dns_rdataclass_format(rdclass, buf, sizeof(buf));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "class",
|
|
|
|
ISC_XMLCHAR buf));
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"));
|
|
|
|
ztype = user_zonetype(zone);
|
|
|
|
if (ztype != NULL) {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR ztype));
|
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial"));
|
|
|
|
if (dns_zone_getserial(zone, &serial) == ISC_R_SUCCESS) {
|
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%u", serial));
|
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "remoteserial"));
|
|
|
|
if (is_running) {
|
|
|
|
serial = dns_xfrin_getendserial(xfr);
|
|
|
|
if (serial != 0) {
|
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%u",
|
|
|
|
serial));
|
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
2023-11-10 11:06:08 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "firstrefresh"));
|
|
|
|
TRY0(xmlTextWriterWriteString(
|
|
|
|
writer, ISC_XMLCHAR(is_firstrefresh ? "Yes" : "No")));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
2023-05-30 14:58:29 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "state"));
|
|
|
|
if (is_running) {
|
|
|
|
const char *xfr_state = NULL;
|
|
|
|
|
|
|
|
dns_xfrin_getstate(xfr, &xfr_state, &is_first_data_received,
|
|
|
|
&is_ixfr);
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR xfr_state));
|
|
|
|
} else if (is_deferred) {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "Deferred"));
|
2023-09-15 08:57:21 +00:00
|
|
|
} else if (is_presoa) {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer,
|
|
|
|
ISC_XMLCHAR "Refresh SOA"));
|
2023-05-30 14:58:29 +00:00
|
|
|
} else if (is_pending) {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "Pending"));
|
|
|
|
} else if (needs_refresh) {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer,
|
|
|
|
ISC_XMLCHAR "Needs Refresh"));
|
|
|
|
} else {
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "refreshqueued"));
|
|
|
|
TRY0(xmlTextWriterWriteString(
|
Fix the incoming transfers' "Needs Refresh" state in stats channel
The "Needs Refresh" flag is exposed in two places in the statistics
channel: first - there is a state called "Needs Refresh", when the
process hasn't started yet, but the zone needs a refresh, and second
- there there is a field called "Additional Refresh Queued", when the
process is ongoing, but another refresh is queued for the same zone.
The DNS_ZONEFLG_NEEDREFRESH flag, however, is set only when there is
an ongoing zone transfer and a new notify is received. That is, the
flag is not set for the first case above.
In order to fix the issue, use the DNS_ZONEFLG_NEEDREFRESH flag only
when the zone transfer is running, otherwise, decide whether a zone
needs a refresh using its refresh and expire times.
2023-09-19 09:38:35 +00:00
|
|
|
writer,
|
|
|
|
ISC_XMLCHAR(is_running && needs_refresh ? "Yes" : "No")));
|
2023-05-30 14:58:29 +00:00
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "localaddr"));
|
|
|
|
if (is_running) {
|
|
|
|
addrp = dns_xfrin_getsourceaddr(xfr);
|
|
|
|
isc_sockaddr_format(addrp, addr_buf, sizeof(addr_buf));
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR addr_buf));
|
2023-09-15 10:47:17 +00:00
|
|
|
} else if (is_presoa) {
|
2024-09-12 12:54:25 +10:00
|
|
|
dns_zone_getsourceaddr(zone, &addr);
|
2023-09-15 10:47:17 +00:00
|
|
|
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR addr_buf));
|
2023-05-30 14:58:29 +00:00
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "remoteaddr"));
|
|
|
|
if (is_running) {
|
|
|
|
addrp = dns_xfrin_getprimaryaddr(xfr);
|
|
|
|
isc_sockaddr_format(addrp, addr_buf, sizeof(addr_buf));
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR addr_buf));
|
2023-09-15 10:47:17 +00:00
|
|
|
} else if (is_presoa) {
|
2025-02-27 11:52:30 +00:00
|
|
|
if (dns_zone_getprimaryaddr(zone, &addr) == ISC_R_SUCCESS) {
|
|
|
|
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
|
|
|
|
TRY0(xmlTextWriterWriteString(writer,
|
|
|
|
ISC_XMLCHAR addr_buf));
|
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
|
|
|
}
|
2023-05-30 14:58:29 +00:00
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
2023-08-23 10:46:44 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "soatransport"));
|
2023-09-15 08:57:21 +00:00
|
|
|
if (is_running || is_presoa) {
|
|
|
|
if (is_running) {
|
|
|
|
transport_type = dns_xfrin_getsoatransporttype(xfr);
|
|
|
|
} else {
|
|
|
|
transport_type = dns_zone_getrequesttransporttype(zone);
|
|
|
|
}
|
2023-08-23 10:46:44 +00:00
|
|
|
if (transport_type == DNS_TRANSPORT_UDP) {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer,
|
|
|
|
ISC_XMLCHAR "UDP"));
|
|
|
|
} else if (transport_type == DNS_TRANSPORT_TCP) {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer,
|
|
|
|
ISC_XMLCHAR "TCP"));
|
|
|
|
} else if (transport_type == DNS_TRANSPORT_TLS) {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer,
|
|
|
|
ISC_XMLCHAR "TLS"));
|
|
|
|
} else if (transport_type == DNS_TRANSPORT_NONE) {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer,
|
|
|
|
ISC_XMLCHAR "None"));
|
|
|
|
} else {
|
|
|
|
/* We don't expect any other SOA transport type. */
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
2023-05-30 14:58:29 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "transport"));
|
|
|
|
if (is_running) {
|
2023-08-23 10:46:44 +00:00
|
|
|
transport_type = dns_xfrin_gettransporttype(xfr);
|
|
|
|
if (transport_type == DNS_TRANSPORT_TCP) {
|
2023-05-30 14:58:29 +00:00
|
|
|
TRY0(xmlTextWriterWriteString(writer,
|
|
|
|
ISC_XMLCHAR "TCP"));
|
2023-08-23 10:46:44 +00:00
|
|
|
} else if (transport_type == DNS_TRANSPORT_TLS) {
|
2023-05-30 14:58:29 +00:00
|
|
|
TRY0(xmlTextWriterWriteString(writer,
|
|
|
|
ISC_XMLCHAR "TLS"));
|
|
|
|
} else {
|
2023-08-23 10:46:44 +00:00
|
|
|
/* We don't expect any other transport type. */
|
2023-05-30 14:58:29 +00:00
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tsigkeyname"));
|
|
|
|
if (is_running) {
|
|
|
|
const dns_name_t *tsigkeyname = dns_xfrin_gettsigkeyname(xfr);
|
|
|
|
char tsigkeyname_buf[DNS_NAME_FORMATSIZE];
|
|
|
|
|
|
|
|
if (tsigkeyname != NULL) {
|
|
|
|
dns_name_format(tsigkeyname, tsigkeyname_buf,
|
|
|
|
sizeof(tsigkeyname_buf));
|
|
|
|
TRY0(xmlTextWriterWriteString(
|
|
|
|
writer, ISC_XMLCHAR tsigkeyname_buf));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "duration"));
|
2023-09-15 10:03:29 +00:00
|
|
|
if (is_running || is_deferred || is_presoa || is_pending) {
|
|
|
|
isc_time_t start = is_running ? dns_xfrin_getstarttime(xfr)
|
|
|
|
: dns_zone_getxfrintime(zone);
|
2023-05-30 14:58:29 +00:00
|
|
|
isc_time_t now = isc_time_now();
|
|
|
|
isc_time_t diff;
|
|
|
|
uint32_t sec;
|
|
|
|
|
|
|
|
isc_time_subtract(&now, &start, &diff);
|
|
|
|
sec = isc_time_seconds(&diff);
|
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu32, sec));
|
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "0"));
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
|
|
|
if (is_running) {
|
2024-11-27 10:34:40 +00:00
|
|
|
dns_xfrin_getstats(xfr, &nmsg, &nrecs, &nbytes, &rate);
|
2023-05-30 14:58:29 +00:00
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "nmsg"));
|
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%u", nmsg));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "nrecs"));
|
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%u", nrecs));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "nbytes"));
|
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, nbytes));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
2024-11-27 10:34:40 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rate"));
|
|
|
|
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, rate));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
2023-05-30 14:58:29 +00:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ixfr"));
|
|
|
|
if (is_running && is_first_data_received) {
|
|
|
|
TRY0(xmlTextWriterWriteString(
|
|
|
|
writer, ISC_XMLCHAR(is_ixfr ? "Yes" : "No")));
|
|
|
|
} else {
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR ""));
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* xfrin */
|
|
|
|
|
|
|
|
if (xfr != NULL) {
|
|
|
|
dns_xfrin_detach(&xfr);
|
|
|
|
}
|
2023-09-25 09:38:03 +00:00
|
|
|
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (xfr != NULL) {
|
|
|
|
dns_xfrin_detach(&xfr);
|
2023-05-30 14:58:29 +00:00
|
|
|
}
|
2023-09-25 09:38:03 +00:00
|
|
|
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR, "Failed at xfrin_xmlrender()");
|
2023-09-25 09:38:03 +00:00
|
|
|
|
|
|
|
return ISC_R_FAILURE;
|
2023-05-30 14:58:29 +00:00
|
|
|
}
|
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
static isc_result_t
|
2018-03-28 14:19:37 +02:00
|
|
|
generatexml(named_server_t *server, uint32_t flags, int *buflen,
|
|
|
|
xmlChar **buf) {
|
2016-01-07 15:34:14 -08:00
|
|
|
char boottime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
|
|
|
|
char configtime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
|
|
|
|
char nowstr[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
|
2023-03-31 00:12:33 +02:00
|
|
|
isc_time_t now = isc_time_now();
|
2010-02-04 00:57:25 +00:00
|
|
|
xmlTextWriterPtr writer = NULL;
|
|
|
|
xmlDocPtr doc = NULL;
|
2008-01-17 00:15:14 +00:00
|
|
|
int xmlrc;
|
|
|
|
dns_view_t *view;
|
2008-04-03 05:55:52 +00:00
|
|
|
stats_dumparg_t dumparg;
|
2012-05-14 10:06:05 -07:00
|
|
|
dns_stats_t *cacherrstats;
|
2018-03-28 14:19:37 +02:00
|
|
|
uint64_t nsstat_values[ns_statscounter_max];
|
|
|
|
uint64_t resstat_values[dns_resstatscounter_max];
|
|
|
|
uint64_t adbstat_values[dns_adbstats_max];
|
|
|
|
uint64_t zonestat_values[dns_zonestatscounter_max];
|
|
|
|
uint64_t sockstat_values[isc_sockstatscounter_max];
|
2023-03-16 14:31:46 +00:00
|
|
|
uint64_t udpinsizestat_values[DNS_SIZEHISTO_MAXIN + 1];
|
|
|
|
uint64_t udpoutsizestat_values[DNS_SIZEHISTO_MAXOUT + 1];
|
|
|
|
uint64_t tcpinsizestat_values[DNS_SIZEHISTO_MAXIN + 1];
|
|
|
|
uint64_t tcpoutsizestat_values[DNS_SIZEHISTO_MAXOUT + 1];
|
2018-02-24 17:55:24 -08:00
|
|
|
#ifdef HAVE_DNSTAP
|
2018-03-28 14:19:37 +02:00
|
|
|
uint64_t dnstapstat_values[dns_dnstapcounter_max];
|
2016-08-18 11:16:06 +10:00
|
|
|
#endif /* ifdef HAVE_DNSTAP */
|
2010-02-04 00:57:25 +00:00
|
|
|
isc_result_t result;
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
isc_time_formatISO8601ms(&named_g_boottime, boottime, sizeof boottime);
|
2025-04-22 13:46:47 +02:00
|
|
|
isc_time_formatISO8601ms(&named_g_defaultconfigtime, configtime,
|
2017-09-08 13:39:09 -07:00
|
|
|
sizeof configtime);
|
2016-01-07 15:34:14 -08:00
|
|
|
isc_time_formatISO8601ms(&now, nowstr, sizeof nowstr);
|
2008-01-17 00:15:14 +00:00
|
|
|
|
|
|
|
writer = xmlNewTextWriterDoc(&doc, 0);
|
2010-02-04 00:57:25 +00:00
|
|
|
if (writer == NULL) {
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-01-17 00:15:14 +00:00
|
|
|
TRY0(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL));
|
|
|
|
TRY0(xmlTextWriterWritePI(writer, ISC_XMLCHAR "xml-stylesheet",
|
|
|
|
ISC_XMLCHAR "type=\"text/xsl\" "
|
|
|
|
"href=\"/bind9.xsl\""));
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version",
|
2021-11-03 14:50:08 +01:00
|
|
|
ISC_XMLCHAR STATS_XML_VERSION));
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
/* Set common fields for statistics dump */
|
2012-05-14 10:06:05 -07:00
|
|
|
dumparg.type = isc_statsformat_xml;
|
2008-04-03 05:55:52 +00:00
|
|
|
dumparg.arg = writer;
|
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
/* Render server information */
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "server"));
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time"));
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* boot-time */
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "config-time"));
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR configtime));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* config-time */
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time"));
|
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* current-time */
|
2015-10-28 09:45:46 +11:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "version"));
|
2018-08-07 16:46:53 +02:00
|
|
|
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR PACKAGE_VERSION));
|
2015-10-28 09:45:46 +11:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* version */
|
2014-01-09 15:14:57 -08:00
|
|
|
|
|
|
|
if ((flags & STATS_XML_SERVER) != 0) {
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "opcode"));
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_opcodestats_dump(server->sctx->opcodestats, opcodestat_dump,
|
|
|
|
&dumparg, ISC_STATSDUMP_VERBOSE);
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dumparg.result);
|
2014-01-09 15:14:57 -08:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
2016-06-23 08:44:54 +10:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "rcode"));
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_rcodestats_dump(server->sctx->rcodestats, rcodestat_dump,
|
|
|
|
&dumparg, ISC_STATSDUMP_VERBOSE);
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dumparg.result);
|
2016-06-23 08:44:54 +10:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "qtype"));
|
|
|
|
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_rdatatypestats_dump(server->sctx->rcvquerystats,
|
|
|
|
rdtypestat_dump, &dumparg, 0);
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dumparg.result);
|
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* counters */
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "nsstat"));
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_stats(ns_stats_get(server->sctx->nsstats),
|
|
|
|
isc_statsformat_xml, writer, NULL,
|
|
|
|
nsstats_xmldesc, ns_statscounter_max,
|
|
|
|
nsstats_index, nsstat_values,
|
|
|
|
ISC_STATSDUMP_VERBOSE));
|
2014-01-09 15:14:57 -08:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* /nsstat */
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "zonestat"));
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_stats(server->zonestats, isc_statsformat_xml, writer,
|
|
|
|
NULL, zonestats_xmldesc,
|
|
|
|
dns_zonestatscounter_max, zonestats_index,
|
|
|
|
zonestat_values, ISC_STATSDUMP_VERBOSE));
|
2014-01-09 15:14:57 -08:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* /zonestat */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Most of the common resolver statistics entries are 0, so
|
|
|
|
* we don't use the verbose dump here.
|
|
|
|
*/
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "resstat"));
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_stats(server->resolverstats, isc_statsformat_xml,
|
|
|
|
writer, NULL, resstats_xmldesc,
|
|
|
|
dns_resstatscounter_max, resstats_index,
|
|
|
|
resstat_values, 0));
|
2020-07-09 19:36:10 -07:00
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* resstat */
|
2016-08-18 11:16:06 +10:00
|
|
|
|
2018-02-24 17:55:24 -08:00
|
|
|
#ifdef HAVE_DNSTAP
|
2016-08-18 11:16:06 +10:00
|
|
|
if (server->dtenv != NULL) {
|
|
|
|
isc_stats_t *dnstapstats = NULL;
|
|
|
|
TRY0(xmlTextWriterStartElement(writer,
|
|
|
|
ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer,
|
|
|
|
ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "dnstap"));
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_dt_getstats(named_g_server->dtenv, &dnstapstats);
|
2023-03-16 14:31:46 +00:00
|
|
|
result = dump_stats(
|
2016-08-18 11:16:06 +10:00
|
|
|
dnstapstats, isc_statsformat_xml, writer, NULL,
|
|
|
|
dnstapstats_xmldesc, dns_dnstapcounter_max,
|
|
|
|
dnstapstats_index, dnstapstat_values, 0);
|
|
|
|
isc_stats_detach(&dnstapstats);
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(result);
|
|
|
|
|
2016-08-18 11:16:06 +10:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* dnstap */
|
|
|
|
}
|
|
|
|
#endif /* ifdef HAVE_DNSTAP */
|
2014-01-09 15:14:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & STATS_XML_NET) != 0) {
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "sockstat"));
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_stats(server->sockstats, isc_statsformat_xml, writer,
|
|
|
|
NULL, sockstats_xmldesc,
|
|
|
|
isc_sockstatscounter_max, sockstats_index,
|
|
|
|
sockstat_values, ISC_STATSDUMP_VERBOSE));
|
2014-01-09 15:14:57 -08:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* /sockstat */
|
|
|
|
}
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* /server */
|
|
|
|
|
2015-07-06 22:20:03 -07:00
|
|
|
if ((flags & STATS_XML_TRAFFIC) != 0) {
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "traffic"));
|
2016-06-23 08:44:54 +10:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ipv4"));
|
2015-07-06 22:20:03 -07:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "udp"));
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "request-size"));
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_histo(server->sctx->udpinstats4, isc_statsformat_xml,
|
|
|
|
writer, NULL, udpinsizestats_xmldesc,
|
|
|
|
dns_sizecounter_in_max, udpinsizestats_index,
|
|
|
|
udpinsizestat_values, 0));
|
2015-07-06 22:20:03 -07:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "response-size"));
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_histo(
|
2015-07-06 22:20:03 -07:00
|
|
|
server->sctx->udpoutstats4, isc_statsformat_xml, writer,
|
|
|
|
NULL, udpoutsizestats_xmldesc, dns_sizecounter_out_max,
|
2020-07-09 19:36:10 -07:00
|
|
|
udpoutsizestats_index, udpoutsizestat_values, 0));
|
2015-07-06 22:20:03 -07:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </udp> */
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tcp"));
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "request-size"));
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_histo(server->sctx->tcpinstats4, isc_statsformat_xml,
|
|
|
|
writer, NULL, tcpinsizestats_xmldesc,
|
|
|
|
dns_sizecounter_in_max, tcpinsizestats_index,
|
|
|
|
tcpinsizestat_values, 0));
|
2015-07-06 22:20:03 -07:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "response-size"));
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_histo(
|
2015-07-06 22:20:03 -07:00
|
|
|
server->sctx->tcpoutstats4, isc_statsformat_xml, writer,
|
|
|
|
NULL, tcpoutsizestats_xmldesc, dns_sizecounter_out_max,
|
2020-07-09 19:36:10 -07:00
|
|
|
tcpoutsizestats_index, tcpoutsizestat_values, 0));
|
2015-07-06 22:20:03 -07:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </tcp> */
|
2016-06-23 08:44:54 +10:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </ipv4> */
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ipv6"));
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "udp"));
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "request-size"));
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_histo(server->sctx->udpinstats6, isc_statsformat_xml,
|
|
|
|
writer, NULL, udpinsizestats_xmldesc,
|
|
|
|
dns_sizecounter_in_max, udpinsizestats_index,
|
|
|
|
udpinsizestat_values, 0));
|
2016-06-23 08:44:54 +10:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "response-size"));
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_histo(
|
2016-06-23 08:44:54 +10:00
|
|
|
server->sctx->udpoutstats6, isc_statsformat_xml, writer,
|
|
|
|
NULL, udpoutsizestats_xmldesc, dns_sizecounter_out_max,
|
2020-07-09 19:36:10 -07:00
|
|
|
udpoutsizestats_index, udpoutsizestat_values, 0));
|
2016-06-23 08:44:54 +10:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </udp> */
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tcp"));
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "request-size"));
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_histo(server->sctx->tcpinstats6, isc_statsformat_xml,
|
|
|
|
writer, NULL, tcpinsizestats_xmldesc,
|
|
|
|
dns_sizecounter_in_max, tcpinsizestats_index,
|
|
|
|
tcpinsizestat_values, 0));
|
2016-06-23 08:44:54 +10:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
|
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "response-size"));
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_histo(
|
2016-06-23 08:44:54 +10:00
|
|
|
server->sctx->tcpoutstats6, isc_statsformat_xml, writer,
|
|
|
|
NULL, tcpoutsizestats_xmldesc, dns_sizecounter_out_max,
|
2020-07-09 19:36:10 -07:00
|
|
|
tcpoutsizestats_index, tcpoutsizestat_values, 0));
|
2016-06-23 08:44:54 +10:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </tcp> */
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </ipv6> */
|
2015-07-06 22:20:03 -07:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </traffic> */
|
|
|
|
}
|
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
/*
|
2014-01-09 15:14:57 -08:00
|
|
|
* Render views. For each view we know of, call its
|
|
|
|
* rendering function.
|
2008-01-17 00:15:14 +00:00
|
|
|
*/
|
|
|
|
view = ISC_LIST_HEAD(server->viewlist);
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views"));
|
2023-05-30 14:58:29 +00:00
|
|
|
while (view != NULL && ((flags & (STATS_XML_SERVER | STATS_XML_ZONES |
|
|
|
|
STATS_XML_XFRINS)) != 0))
|
2022-11-02 19:33:14 +01:00
|
|
|
{
|
2022-05-11 15:38:54 -07:00
|
|
|
isc_stats_t *istats = NULL;
|
|
|
|
dns_stats_t *dstats = NULL;
|
2023-06-08 16:58:45 +10:00
|
|
|
dns_adb_t *adb = NULL;
|
2022-05-11 15:38:54 -07:00
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "view"));
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
|
|
|
|
ISC_XMLCHAR view->name));
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
if ((flags & STATS_XML_ZONES) != 0) {
|
|
|
|
TRY0(xmlTextWriterStartElement(writer,
|
|
|
|
ISC_XMLCHAR "zones"));
|
2023-05-31 15:52:36 +10:00
|
|
|
CHECK(dns_view_apply(view, true, NULL, zone_xmlrender,
|
|
|
|
writer));
|
2014-01-09 15:14:57 -08:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* /zones */
|
|
|
|
}
|
|
|
|
|
2023-05-30 14:58:29 +00:00
|
|
|
if ((flags & STATS_XML_XFRINS) != 0) {
|
|
|
|
TRY0(xmlTextWriterStartElement(writer,
|
|
|
|
ISC_XMLCHAR "xfrins"));
|
|
|
|
CHECK(dns_zt_apply(view->zonetable, true, NULL,
|
|
|
|
xfrin_xmlrender, writer));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* /xfrins */
|
|
|
|
}
|
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
if ((flags & STATS_XML_SERVER) == 0) {
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* /view */
|
|
|
|
view = ISC_LIST_NEXT(view, link);
|
|
|
|
continue;
|
|
|
|
}
|
2012-11-14 12:44:15 -06:00
|
|
|
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "resqtype"));
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2022-05-11 15:38:54 -07:00
|
|
|
dns_resolver_getquerystats(view->resolver, &dstats);
|
|
|
|
if (dstats != NULL) {
|
2010-02-04 00:57:25 +00:00
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
2022-05-11 15:38:54 -07:00
|
|
|
dns_rdatatypestats_dump(dstats, rdtypestat_dump,
|
|
|
|
&dumparg, 0);
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dumparg.result);
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
2022-05-11 15:38:54 -07:00
|
|
|
dns_stats_detach(&dstats);
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterEndElement(writer));
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2012-11-14 12:44:15 -06:00
|
|
|
/* <resstats> */
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "resstats"));
|
2022-05-11 15:38:54 -07:00
|
|
|
dns_resolver_getstats(view->resolver, &istats);
|
|
|
|
if (istats != NULL) {
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_stats(istats, isc_statsformat_xml, writer,
|
|
|
|
NULL, resstats_xmldesc,
|
|
|
|
dns_resstatscounter_max,
|
|
|
|
resstats_index, resstat_values,
|
|
|
|
ISC_STATSDUMP_VERBOSE));
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
2022-05-11 15:38:54 -07:00
|
|
|
isc_stats_detach(&istats);
|
2012-11-14 12:44:15 -06:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </resstats> */
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2012-05-14 10:06:05 -07:00
|
|
|
cacherrstats = dns_db_getrrsetstats(view->cachedb);
|
|
|
|
if (cacherrstats != NULL) {
|
2009-01-09 22:24:37 +00:00
|
|
|
TRY0(xmlTextWriterStartElement(writer,
|
|
|
|
ISC_XMLCHAR "cache"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(
|
|
|
|
writer, ISC_XMLCHAR "name",
|
|
|
|
ISC_XMLCHAR dns_cache_getname(view->cache)));
|
2010-02-04 00:57:25 +00:00
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
2012-05-14 10:06:05 -07:00
|
|
|
dns_rdatasetstats_dump(cacherrstats, rdatasetstats_dump,
|
2008-04-03 05:55:52 +00:00
|
|
|
&dumparg, 0);
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dumparg.result);
|
2009-01-09 22:24:37 +00:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* cache */
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
|
2013-02-08 14:53:14 -08:00
|
|
|
/* <adbstats> */
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "adbstat"));
|
2023-06-08 16:58:45 +10:00
|
|
|
dns_view_getadb(view, &adb);
|
|
|
|
if (adb != NULL) {
|
|
|
|
result = dump_stats(dns_adb_getstats(adb),
|
|
|
|
isc_statsformat_xml, writer, NULL,
|
|
|
|
adbstats_xmldesc, dns_adbstats_max,
|
|
|
|
adbstats_index, adbstat_values,
|
|
|
|
ISC_STATSDUMP_VERBOSE);
|
|
|
|
dns_adb_detach(&adb);
|
|
|
|
CHECK(result);
|
|
|
|
}
|
2013-02-08 14:53:14 -08:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </adbstats> */
|
|
|
|
|
|
|
|
/* <cachestats> */
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
|
|
|
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
|
|
|
|
ISC_XMLCHAR "cachestats"));
|
|
|
|
TRY0(dns_cache_renderxml(view->cache, writer));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* </cachestats> */
|
2012-05-14 10:06:05 -07:00
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* view */
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
view = ISC_LIST_NEXT(view, link);
|
|
|
|
}
|
2014-01-09 15:14:57 -08:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* /views */
|
2012-11-14 12:44:15 -06:00
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
if ((flags & STATS_XML_MEM) != 0) {
|
|
|
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory"));
|
|
|
|
TRY0(isc_mem_renderxml(writer));
|
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* /memory */
|
|
|
|
}
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
TRY0(xmlTextWriterEndElement(writer)); /* /statistics */
|
2008-01-17 00:15:14 +00:00
|
|
|
TRY0(xmlTextWriterEndDocument(writer));
|
|
|
|
|
2012-11-14 12:44:15 -06:00
|
|
|
xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 0);
|
2013-06-06 10:55:08 +10:00
|
|
|
if (*buf == NULL) {
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2021-01-27 12:16:55 +11:00
|
|
|
|
|
|
|
xmlFreeTextWriter(writer);
|
2008-01-17 00:15:14 +00:00
|
|
|
xmlFreeDoc(doc);
|
2010-02-04 00:57:25 +00:00
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
|
2020-07-09 19:36:10 -07:00
|
|
|
cleanup:
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR, "failed generating XML response");
|
2010-02-04 00:57:25 +00:00
|
|
|
if (writer != NULL) {
|
|
|
|
xmlFreeTextWriter(writer);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2010-02-04 00:57:25 +00:00
|
|
|
if (doc != NULL) {
|
|
|
|
xmlFreeDoc(doc);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2010-02-04 00:57:25 +00:00
|
|
|
return ISC_R_FAILURE;
|
2008-01-17 00:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
wrap_xmlfree(isc_buffer_t *buffer, void *arg) {
|
|
|
|
UNUSED(arg);
|
|
|
|
|
|
|
|
xmlFree(isc_buffer_base(buffer));
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_xml(uint32_t flags, void *arg, unsigned int *retcode,
|
|
|
|
const char **retmsg, const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2013-06-06 10:55:08 +10:00
|
|
|
unsigned char *msg = NULL;
|
2008-01-17 00:15:14 +00:00
|
|
|
int msglen;
|
2017-09-08 13:39:09 -07:00
|
|
|
named_server_t *server = arg;
|
2010-02-04 00:57:25 +00:00
|
|
|
isc_result_t result;
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
result = generatexml(server, flags, &msglen, &msg);
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
*retcode = 200;
|
|
|
|
*retmsg = "OK";
|
|
|
|
*mimetype = "text/xml";
|
|
|
|
isc_buffer_reinit(b, msg, msglen);
|
|
|
|
isc_buffer_add(b, msglen);
|
|
|
|
*freecb = wrap_xmlfree;
|
|
|
|
*freecb_args = NULL;
|
2012-11-14 12:44:15 -06:00
|
|
|
} else {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR, "failed at rendering XML()");
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2010-02-04 00:57:25 +00:00
|
|
|
return result;
|
2008-01-17 00:15:14 +00:00
|
|
|
}
|
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_xml_all(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2014-01-09 15:14:57 -08:00
|
|
|
const char **mimetype, isc_buffer_t *b, isc_httpdfree_t **freecb,
|
|
|
|
void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_xml(STATS_XML_ALL, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2014-01-09 15:14:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_xml_status(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2014-01-09 15:14:57 -08:00
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_xml(STATS_XML_STATUS, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2014-01-09 15:14:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_xml_server(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2014-01-09 15:14:57 -08:00
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_xml(STATS_XML_SERVER, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2014-01-09 15:14:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_xml_zones(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2014-01-09 15:14:57 -08:00
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_xml(STATS_XML_ZONES, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2014-01-09 15:14:57 -08:00
|
|
|
}
|
|
|
|
|
2023-05-30 14:58:29 +00:00
|
|
|
static isc_result_t
|
|
|
|
render_xml_xfrins(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_xml(STATS_XML_XFRINS, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
|
|
|
}
|
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_xml_net(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2014-01-09 15:14:57 -08:00
|
|
|
const char **mimetype, isc_buffer_t *b, isc_httpdfree_t **freecb,
|
|
|
|
void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_xml(STATS_XML_NET, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2014-01-09 15:14:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_xml_mem(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2014-01-09 15:14:57 -08:00
|
|
|
const char **mimetype, isc_buffer_t *b, isc_httpdfree_t **freecb,
|
|
|
|
void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_xml(STATS_XML_MEM, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2014-01-09 15:14:57 -08:00
|
|
|
}
|
|
|
|
|
2015-07-06 22:20:03 -07:00
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_xml_traffic(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2015-07-06 22:20:03 -07:00
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_xml(STATS_XML_TRAFFIC, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2015-07-06 22:20:03 -07:00
|
|
|
}
|
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
#endif /* HAVE_LIBXML2 */
|
|
|
|
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2013-03-13 14:24:50 -07:00
|
|
|
/*
|
|
|
|
* Which statistics to include when rendering to JSON
|
|
|
|
*/
|
2014-01-09 15:14:57 -08:00
|
|
|
#define STATS_JSON_STATUS 0x00 /* display only common statistics */
|
2013-03-13 14:24:50 -07:00
|
|
|
#define STATS_JSON_SERVER 0x01
|
|
|
|
#define STATS_JSON_ZONES 0x02
|
2023-05-30 14:58:29 +00:00
|
|
|
#define STATS_JSON_XFRINS 0x04
|
2013-03-13 14:24:50 -07:00
|
|
|
#define STATS_JSON_NET 0x08
|
|
|
|
#define STATS_JSON_MEM 0x10
|
2015-07-06 22:20:03 -07:00
|
|
|
#define STATS_JSON_TRAFFIC 0x20
|
2013-03-13 14:24:50 -07:00
|
|
|
#define STATS_JSON_ALL 0xff
|
2020-02-12 13:59:18 +01:00
|
|
|
|
2013-03-13 14:24:50 -07:00
|
|
|
#define CHECKMEM(m) \
|
|
|
|
do { \
|
|
|
|
if (m == NULL) { \
|
|
|
|
result = ISC_R_NOMEMORY; \
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup; \
|
2013-03-13 14:24:50 -07:00
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
static void
|
|
|
|
wrap_jsonfree(isc_buffer_t *buffer, void *arg) {
|
|
|
|
json_object_put(isc_buffer_base(buffer));
|
|
|
|
if (arg != NULL) {
|
|
|
|
json_object_put((json_object *)arg);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static json_object *
|
2017-08-10 08:42:04 +10:00
|
|
|
addzone(char *name, char *classname, const char *ztype, uint32_t serial,
|
2018-04-17 08:29:14 -07:00
|
|
|
bool add_serial) {
|
2013-03-13 14:24:50 -07:00
|
|
|
json_object *node = json_object_new_object();
|
|
|
|
|
|
|
|
if (node == NULL) {
|
|
|
|
return NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
json_object_object_add(node, "name", json_object_new_string(name));
|
2017-08-10 08:42:04 +10:00
|
|
|
json_object_object_add(node, "class",
|
|
|
|
json_object_new_string(classname));
|
2015-02-25 16:55:25 -08:00
|
|
|
if (add_serial) {
|
|
|
|
json_object_object_add(node, "serial",
|
|
|
|
json_object_new_int64(serial));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-10-28 09:45:46 +11:00
|
|
|
if (ztype != NULL) {
|
|
|
|
json_object_object_add(node, "type",
|
|
|
|
json_object_new_string(ztype));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
zone_jsonrender(dns_zone_t *zone, void *arg) {
|
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
|
|
|
char buf[1024 + 32]; /* sufficiently large for zone name and class */
|
2017-08-10 08:42:04 +10:00
|
|
|
char classbuf[64]; /* sufficiently large for class */
|
2013-03-13 14:24:50 -07:00
|
|
|
char *zone_name_only = NULL;
|
|
|
|
char *class_only = NULL;
|
|
|
|
dns_rdataclass_t rdclass;
|
2018-03-28 14:19:37 +02:00
|
|
|
uint32_t serial;
|
2013-03-13 14:24:50 -07:00
|
|
|
json_object *zonearray = (json_object *)arg;
|
|
|
|
json_object *zoneobj = NULL;
|
|
|
|
dns_zonestat_level_t statlevel;
|
2021-10-05 11:07:44 +02:00
|
|
|
isc_time_t timestamp;
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
statlevel = dns_zone_getstatlevel(zone);
|
|
|
|
if (statlevel == dns_zonestat_none) {
|
|
|
|
return ISC_R_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
2015-06-29 18:33:18 +05:30
|
|
|
dns_zone_nameonly(zone, buf, sizeof(buf));
|
|
|
|
zone_name_only = buf;
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
rdclass = dns_zone_getclass(zone);
|
2017-08-10 08:42:04 +10:00
|
|
|
dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf));
|
|
|
|
class_only = classbuf;
|
2013-03-13 14:24:50 -07:00
|
|
|
|
2018-04-03 16:34:41 +02:00
|
|
|
if (dns_zone_getserial(zone, &serial) != ISC_R_SUCCESS) {
|
2015-10-28 09:45:46 +11:00
|
|
|
zoneobj = addzone(zone_name_only, class_only,
|
2018-04-17 08:29:14 -07:00
|
|
|
user_zonetype(zone), 0, false);
|
2015-02-25 16:55:25 -08:00
|
|
|
} else {
|
2015-10-28 09:45:46 +11:00
|
|
|
zoneobj = addzone(zone_name_only, class_only,
|
2018-04-17 08:29:14 -07:00
|
|
|
user_zonetype(zone), serial, true);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
if (zoneobj == NULL) {
|
|
|
|
return ISC_R_NOMEMORY;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
2019-10-30 17:06:06 -05:00
|
|
|
/*
|
2021-10-05 11:07:44 +02:00
|
|
|
* Export zone timers to the statistics channel in JSON format.
|
|
|
|
* For primary zones, only include the loaded time. For secondary
|
|
|
|
* zones, also include the expire and refresh times.
|
2019-10-30 17:06:06 -05:00
|
|
|
*/
|
|
|
|
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dns_zone_getloadtime(zone, ×tamp));
|
2019-10-30 17:06:06 -05:00
|
|
|
|
|
|
|
isc_time_formatISO8601(×tamp, buf, 64);
|
|
|
|
json_object_object_add(zoneobj, "loaded", json_object_new_string(buf));
|
|
|
|
|
2021-08-25 22:29:25 -07:00
|
|
|
if (dns_zone_gettype(zone) == dns_zone_secondary) {
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dns_zone_getexpiretime(zone, ×tamp));
|
2019-10-30 17:06:06 -05:00
|
|
|
isc_time_formatISO8601(×tamp, buf, 64);
|
|
|
|
json_object_object_add(zoneobj, "expires",
|
|
|
|
json_object_new_string(buf));
|
|
|
|
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(dns_zone_getrefreshtime(zone, ×tamp));
|
2019-10-30 17:06:06 -05:00
|
|
|
isc_time_formatISO8601(×tamp, buf, 64);
|
|
|
|
json_object_object_add(zoneobj, "refresh",
|
|
|
|
json_object_new_string(buf));
|
|
|
|
}
|
|
|
|
|
2017-10-06 15:24:16 +05:30
|
|
|
if (statlevel == dns_zonestat_full) {
|
2024-12-06 19:46:39 +01:00
|
|
|
isc_stats_t *zonestats;
|
2017-10-06 15:24:16 +05:30
|
|
|
isc_stats_t *gluecachestats;
|
2024-12-06 19:46:39 +01:00
|
|
|
dns_stats_t *rcvquerystats;
|
|
|
|
dns_stats_t *dnssecsignstats;
|
2018-03-28 14:19:37 +02:00
|
|
|
uint64_t nsstat_values[ns_statscounter_max];
|
|
|
|
uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
|
2013-03-13 14:24:50 -07:00
|
|
|
|
2024-12-06 19:46:39 +01:00
|
|
|
zonestats = dns_zone_getrequeststats(zone);
|
2017-10-06 15:24:16 +05:30
|
|
|
if (zonestats != NULL) {
|
|
|
|
json_object *counters = json_object_new_object();
|
|
|
|
if (counters == NULL) {
|
|
|
|
result = ISC_R_NOMEMORY;
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2017-10-06 15:24:16 +05:30
|
|
|
}
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
result = dump_stats(zonestats, isc_statsformat_json,
|
|
|
|
counters, NULL, nsstats_xmldesc,
|
|
|
|
ns_statscounter_max, nsstats_index,
|
|
|
|
nsstat_values, 0);
|
2017-10-06 15:24:16 +05:30
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2017-10-06 15:24:16 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_get_object(counters)->count != 0) {
|
|
|
|
json_object_object_add(zoneobj, "rcodes",
|
|
|
|
counters);
|
|
|
|
} else {
|
|
|
|
json_object_put(counters);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
2017-10-06 15:24:16 +05:30
|
|
|
gluecachestats = dns_zone_getgluecachestats(zone);
|
|
|
|
if (gluecachestats != NULL) {
|
|
|
|
json_object *counters = json_object_new_object();
|
|
|
|
if (counters == NULL) {
|
|
|
|
result = ISC_R_NOMEMORY;
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2017-10-06 15:24:16 +05:30
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
result = dump_stats(
|
2017-10-06 15:24:16 +05:30
|
|
|
gluecachestats, isc_statsformat_json, counters,
|
|
|
|
NULL, gluecachestats_xmldesc,
|
|
|
|
dns_gluecachestatscounter_max,
|
|
|
|
gluecachestats_index, gluecachestats_values, 0);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2017-10-06 15:24:16 +05:30
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
2017-10-06 15:24:16 +05:30
|
|
|
if (json_object_get_object(counters)->count != 0) {
|
|
|
|
json_object_object_add(zoneobj, "gluecache",
|
|
|
|
counters);
|
|
|
|
} else {
|
|
|
|
json_object_put(counters);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
2024-12-06 19:46:39 +01:00
|
|
|
rcvquerystats = dns_zone_getrcvquerystats(zone);
|
2017-10-06 15:24:16 +05:30
|
|
|
if (rcvquerystats != NULL) {
|
|
|
|
stats_dumparg_t dumparg;
|
|
|
|
json_object *counters = json_object_new_object();
|
|
|
|
CHECKMEM(counters);
|
|
|
|
|
|
|
|
dumparg.type = isc_statsformat_json;
|
|
|
|
dumparg.arg = counters;
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump,
|
|
|
|
&dumparg, 0);
|
|
|
|
if (dumparg.result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2017-10-06 15:24:16 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_get_object(counters)->count != 0) {
|
|
|
|
json_object_object_add(zoneobj, "qtypes",
|
|
|
|
counters);
|
|
|
|
} else {
|
|
|
|
json_object_put(counters);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-10-06 15:24:16 +05:30
|
|
|
}
|
2019-06-19 16:02:50 +02:00
|
|
|
|
2024-12-06 19:46:39 +01:00
|
|
|
dnssecsignstats = dns_zone_getdnssecsignstats(zone);
|
2019-06-19 16:02:50 +02:00
|
|
|
if (dnssecsignstats != NULL) {
|
|
|
|
stats_dumparg_t dumparg;
|
2020-04-02 18:53:53 +02:00
|
|
|
json_object *sign_counters = json_object_new_object();
|
|
|
|
CHECKMEM(sign_counters);
|
2019-06-19 16:02:50 +02:00
|
|
|
|
|
|
|
dumparg.type = isc_statsformat_json;
|
2020-04-02 18:53:53 +02:00
|
|
|
dumparg.arg = sign_counters;
|
2019-06-19 16:02:50 +02:00
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
2020-04-02 16:12:10 +02:00
|
|
|
dns_dnssecsignstats_dump(
|
|
|
|
dnssecsignstats, dns_dnssecsignstats_sign,
|
|
|
|
dnssecsignstat_dump, &dumparg, 0);
|
2019-06-19 16:02:50 +02:00
|
|
|
if (dumparg.result != ISC_R_SUCCESS) {
|
2020-04-02 18:53:53 +02:00
|
|
|
json_object_put(sign_counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2019-06-19 16:02:50 +02:00
|
|
|
}
|
|
|
|
|
2020-04-02 18:53:53 +02:00
|
|
|
if (json_object_get_object(sign_counters)->count != 0) {
|
2019-06-19 16:02:50 +02:00
|
|
|
json_object_object_add(zoneobj, "dnssec-sign",
|
2020-04-02 18:53:53 +02:00
|
|
|
sign_counters);
|
2019-06-21 10:30:05 +02:00
|
|
|
} else {
|
2020-04-02 18:53:53 +02:00
|
|
|
json_object_put(sign_counters);
|
2019-06-21 10:30:05 +02:00
|
|
|
}
|
|
|
|
|
2020-04-02 18:53:53 +02:00
|
|
|
json_object *refresh_counters =
|
|
|
|
json_object_new_object();
|
|
|
|
CHECKMEM(refresh_counters);
|
2019-06-21 10:30:05 +02:00
|
|
|
|
|
|
|
dumparg.type = isc_statsformat_json;
|
2020-04-02 18:53:53 +02:00
|
|
|
dumparg.arg = refresh_counters;
|
2019-06-21 10:30:05 +02:00
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
2020-04-02 16:12:10 +02:00
|
|
|
dns_dnssecsignstats_dump(
|
|
|
|
dnssecsignstats, dns_dnssecsignstats_refresh,
|
|
|
|
dnssecsignstat_dump, &dumparg, 0);
|
2019-06-21 10:30:05 +02:00
|
|
|
if (dumparg.result != ISC_R_SUCCESS) {
|
2020-04-02 18:53:53 +02:00
|
|
|
json_object_put(refresh_counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2019-06-21 10:30:05 +02:00
|
|
|
}
|
|
|
|
|
2020-04-02 18:53:53 +02:00
|
|
|
if (json_object_get_object(refresh_counters)->count !=
|
2022-11-02 19:33:14 +01:00
|
|
|
0)
|
|
|
|
{
|
2020-04-02 18:53:53 +02:00
|
|
|
json_object_object_add(zoneobj,
|
|
|
|
"dnssec-refresh",
|
|
|
|
refresh_counters);
|
2019-06-21 10:30:05 +02:00
|
|
|
} else {
|
2020-04-02 18:53:53 +02:00
|
|
|
json_object_put(refresh_counters);
|
2019-06-21 10:30:05 +02:00
|
|
|
}
|
2019-06-19 16:02:50 +02:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
json_object_array_add(zonearray, zoneobj);
|
|
|
|
zoneobj = NULL;
|
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
|
2020-07-09 19:36:10 -07:00
|
|
|
cleanup:
|
2013-03-13 14:24:50 -07:00
|
|
|
if (zoneobj != NULL) {
|
|
|
|
json_object_put(zoneobj);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-05-30 14:58:29 +00:00
|
|
|
static isc_result_t
|
|
|
|
xfrin_jsonrender(dns_zone_t *zone, void *arg) {
|
|
|
|
isc_result_t result;
|
|
|
|
char buf[1024 + 32]; /* sufficiently large for zone name and class */
|
|
|
|
char classbuf[64]; /* sufficiently large for class */
|
|
|
|
char *zone_name_only = NULL;
|
|
|
|
char *class_only = NULL;
|
|
|
|
dns_rdataclass_t rdclass;
|
|
|
|
uint32_t serial;
|
|
|
|
json_object *xfrinarray = (json_object *)arg;
|
|
|
|
json_object *xfrinobj = NULL;
|
2023-09-15 10:47:17 +00:00
|
|
|
isc_sockaddr_t addr;
|
2023-05-30 14:58:29 +00:00
|
|
|
const isc_sockaddr_t *addrp = NULL;
|
|
|
|
char addr_buf[ISC_SOCKADDR_FORMATSIZE];
|
2023-08-23 10:46:44 +00:00
|
|
|
dns_transport_type_t transport_type;
|
2023-05-30 14:58:29 +00:00
|
|
|
dns_zonestat_level_t statlevel;
|
|
|
|
dns_xfrin_t *xfr = NULL;
|
2023-11-10 11:06:08 +00:00
|
|
|
bool is_firstrefresh, is_running, is_deferred, is_presoa, is_pending;
|
2023-05-30 14:58:29 +00:00
|
|
|
bool needs_refresh;
|
|
|
|
bool is_first_data_received, is_ixfr;
|
|
|
|
unsigned int nmsg = 0;
|
|
|
|
unsigned int nrecs = 0;
|
|
|
|
uint64_t nbytes = 0;
|
2024-11-27 10:34:40 +00:00
|
|
|
uint64_t rate = 0;
|
2023-05-30 14:58:29 +00:00
|
|
|
|
|
|
|
statlevel = dns_zone_getstatlevel(zone);
|
|
|
|
if (statlevel == dns_zonestat_none) {
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
dns_zone_nameonly(zone, buf, sizeof(buf));
|
|
|
|
zone_name_only = buf;
|
|
|
|
|
|
|
|
rdclass = dns_zone_getclass(zone);
|
|
|
|
dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf));
|
|
|
|
class_only = classbuf;
|
|
|
|
|
|
|
|
if (dns_zone_getserial(zone, &serial) != ISC_R_SUCCESS) {
|
|
|
|
xfrinobj = addzone(zone_name_only, class_only,
|
|
|
|
user_zonetype(zone), 0, false);
|
|
|
|
} else {
|
|
|
|
xfrinobj = addzone(zone_name_only, class_only,
|
|
|
|
user_zonetype(zone), serial, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xfrinobj == NULL) {
|
|
|
|
result = ISC_R_NOMEMORY;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2023-11-10 11:06:08 +00:00
|
|
|
result = dns_zone_getxfr(zone, &xfr, &is_firstrefresh, &is_running,
|
|
|
|
&is_deferred, &is_presoa, &is_pending,
|
|
|
|
&needs_refresh);
|
2023-05-30 14:58:29 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2023-09-15 08:57:21 +00:00
|
|
|
if (!is_running && !is_deferred && !is_presoa && !is_pending &&
|
|
|
|
!needs_refresh)
|
|
|
|
{
|
2023-05-30 14:58:29 +00:00
|
|
|
/* No ongoing/queued transfer. */
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_running && xfr == NULL) {
|
|
|
|
/* The transfer is finished, and it's shutting down. */
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_running) {
|
|
|
|
serial = dns_xfrin_getendserial(xfr);
|
|
|
|
if (serial != 0) {
|
|
|
|
json_object_object_add(xfrinobj, "remoteserial",
|
|
|
|
json_object_new_int64(serial));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-10 11:06:08 +00:00
|
|
|
json_object_object_add(
|
|
|
|
xfrinobj, "firstrefresh",
|
|
|
|
json_object_new_string(is_firstrefresh ? "Yes" : "No"));
|
|
|
|
|
2023-05-30 14:58:29 +00:00
|
|
|
if (is_running) {
|
|
|
|
const char *xfr_state = NULL;
|
|
|
|
|
|
|
|
dns_xfrin_getstate(xfr, &xfr_state, &is_first_data_received,
|
|
|
|
&is_ixfr);
|
|
|
|
json_object_object_add(xfrinobj, "state",
|
|
|
|
json_object_new_string(xfr_state));
|
|
|
|
} else if (is_deferred) {
|
|
|
|
json_object_object_add(xfrinobj, "state",
|
|
|
|
json_object_new_string("Deferred"));
|
2023-09-15 08:57:21 +00:00
|
|
|
} else if (is_presoa) {
|
|
|
|
json_object_object_add(xfrinobj, "state",
|
|
|
|
json_object_new_string("Refresh SOA"));
|
2023-05-30 14:58:29 +00:00
|
|
|
} else if (is_pending) {
|
|
|
|
json_object_object_add(xfrinobj, "state",
|
|
|
|
json_object_new_string("Pending"));
|
|
|
|
} else if (needs_refresh) {
|
|
|
|
json_object_object_add(xfrinobj, "state",
|
|
|
|
json_object_new_string("Needs Refresh"));
|
|
|
|
} else {
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
|
|
|
|
json_object_object_add(
|
|
|
|
xfrinobj, "refreshqueued",
|
Fix the incoming transfers' "Needs Refresh" state in stats channel
The "Needs Refresh" flag is exposed in two places in the statistics
channel: first - there is a state called "Needs Refresh", when the
process hasn't started yet, but the zone needs a refresh, and second
- there there is a field called "Additional Refresh Queued", when the
process is ongoing, but another refresh is queued for the same zone.
The DNS_ZONEFLG_NEEDREFRESH flag, however, is set only when there is
an ongoing zone transfer and a new notify is received. That is, the
flag is not set for the first case above.
In order to fix the issue, use the DNS_ZONEFLG_NEEDREFRESH flag only
when the zone transfer is running, otherwise, decide whether a zone
needs a refresh using its refresh and expire times.
2023-09-19 09:38:35 +00:00
|
|
|
json_object_new_string(is_running && needs_refresh ? "Yes"
|
|
|
|
: "No"));
|
2023-05-30 14:58:29 +00:00
|
|
|
|
|
|
|
if (is_running) {
|
|
|
|
addrp = dns_xfrin_getsourceaddr(xfr);
|
|
|
|
isc_sockaddr_format(addrp, addr_buf, sizeof(addr_buf));
|
|
|
|
json_object_object_add(xfrinobj, "localaddr",
|
|
|
|
json_object_new_string(addr_buf));
|
2023-09-15 10:47:17 +00:00
|
|
|
} else if (is_presoa) {
|
2024-09-12 12:54:25 +10:00
|
|
|
dns_zone_getsourceaddr(zone, &addr);
|
2023-09-15 10:47:17 +00:00
|
|
|
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
|
|
|
|
json_object_object_add(xfrinobj, "localaddr",
|
|
|
|
json_object_new_string(addr_buf));
|
2023-05-30 14:58:29 +00:00
|
|
|
} else {
|
|
|
|
json_object_object_add(xfrinobj, "localaddr",
|
|
|
|
json_object_new_string("-"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_running) {
|
|
|
|
addrp = dns_xfrin_getprimaryaddr(xfr);
|
|
|
|
isc_sockaddr_format(addrp, addr_buf, sizeof(addr_buf));
|
|
|
|
json_object_object_add(xfrinobj, "remoteaddr",
|
|
|
|
json_object_new_string(addr_buf));
|
2023-09-15 10:47:17 +00:00
|
|
|
} else if (is_presoa) {
|
2025-02-27 11:52:30 +00:00
|
|
|
if (dns_zone_getprimaryaddr(zone, &addr) == ISC_R_SUCCESS) {
|
|
|
|
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
|
|
|
|
json_object_object_add(
|
|
|
|
xfrinobj, "remoteaddr",
|
|
|
|
json_object_new_string(addr_buf));
|
|
|
|
} else {
|
|
|
|
json_object_object_add(xfrinobj, "remoteaddr",
|
|
|
|
json_object_new_string("-"));
|
|
|
|
}
|
2023-05-30 14:58:29 +00:00
|
|
|
} else {
|
|
|
|
json_object_object_add(xfrinobj, "remoteaddr",
|
|
|
|
json_object_new_string("-"));
|
|
|
|
}
|
|
|
|
|
2023-09-15 08:57:21 +00:00
|
|
|
if (is_running || is_presoa) {
|
|
|
|
if (is_running) {
|
|
|
|
transport_type = dns_xfrin_getsoatransporttype(xfr);
|
|
|
|
} else {
|
|
|
|
transport_type = dns_zone_getrequesttransporttype(zone);
|
|
|
|
}
|
|
|
|
|
2023-08-23 10:46:44 +00:00
|
|
|
if (transport_type == DNS_TRANSPORT_UDP) {
|
|
|
|
json_object_object_add(xfrinobj, "soatransport",
|
|
|
|
json_object_new_string("UDP"));
|
|
|
|
} else if (transport_type == DNS_TRANSPORT_TCP) {
|
|
|
|
json_object_object_add(xfrinobj, "soatransport",
|
|
|
|
json_object_new_string("TCP"));
|
|
|
|
} else if (transport_type == DNS_TRANSPORT_TLS) {
|
|
|
|
json_object_object_add(xfrinobj, "soatransport",
|
|
|
|
json_object_new_string("TLS"));
|
|
|
|
} else if (transport_type == DNS_TRANSPORT_NONE) {
|
|
|
|
json_object_object_add(xfrinobj, "soatransport",
|
|
|
|
json_object_new_string("None"));
|
|
|
|
} else {
|
|
|
|
/* We don't expect any other SOA transport type. */
|
|
|
|
json_object_object_add(xfrinobj, "soatransport",
|
|
|
|
json_object_new_string("-"));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
json_object_object_add(xfrinobj, "soatransport",
|
|
|
|
json_object_new_string("-"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_running) {
|
|
|
|
transport_type = dns_xfrin_gettransporttype(xfr);
|
|
|
|
if (transport_type == DNS_TRANSPORT_TCP) {
|
2023-05-30 14:58:29 +00:00
|
|
|
json_object_object_add(xfrinobj, "transport",
|
|
|
|
json_object_new_string("TCP"));
|
2023-08-23 10:46:44 +00:00
|
|
|
} else if (transport_type == DNS_TRANSPORT_TLS) {
|
2023-05-30 14:58:29 +00:00
|
|
|
json_object_object_add(xfrinobj, "transport",
|
|
|
|
json_object_new_string("TLS"));
|
|
|
|
} else {
|
2023-08-23 10:46:44 +00:00
|
|
|
/* We don't expect any other transport type. */
|
2023-05-30 14:58:29 +00:00
|
|
|
json_object_object_add(xfrinobj, "transport",
|
|
|
|
json_object_new_string("-"));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
json_object_object_add(xfrinobj, "transport",
|
|
|
|
json_object_new_string("-"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_running) {
|
|
|
|
const dns_name_t *tsigkeyname = dns_xfrin_gettsigkeyname(xfr);
|
|
|
|
char tsigkeyname_buf[DNS_NAME_FORMATSIZE];
|
|
|
|
|
|
|
|
if (tsigkeyname != NULL) {
|
|
|
|
dns_name_format(tsigkeyname, tsigkeyname_buf,
|
|
|
|
sizeof(tsigkeyname_buf));
|
|
|
|
json_object_object_add(
|
|
|
|
xfrinobj, "tsigkeyname",
|
|
|
|
json_object_new_string(tsigkeyname_buf));
|
|
|
|
} else {
|
|
|
|
json_object_object_add(xfrinobj, "tsigkeyname", NULL);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
json_object_object_add(xfrinobj, "tsigkeyname", NULL);
|
|
|
|
}
|
|
|
|
|
2023-09-15 10:03:29 +00:00
|
|
|
if (is_running || is_deferred || is_presoa || is_pending) {
|
|
|
|
isc_time_t start = is_running ? dns_xfrin_getstarttime(xfr)
|
|
|
|
: dns_zone_getxfrintime(zone);
|
2023-05-30 14:58:29 +00:00
|
|
|
isc_time_t now = isc_time_now();
|
|
|
|
isc_time_t diff;
|
|
|
|
uint32_t sec;
|
|
|
|
|
|
|
|
isc_time_subtract(&now, &start, &diff);
|
|
|
|
sec = isc_time_seconds(&diff);
|
|
|
|
json_object_object_add(xfrinobj, "duration",
|
|
|
|
json_object_new_int64((int64_t)sec));
|
|
|
|
} else {
|
|
|
|
json_object_object_add(xfrinobj, "duration",
|
|
|
|
json_object_new_int64(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_running) {
|
2024-11-27 10:34:40 +00:00
|
|
|
dns_xfrin_getstats(xfr, &nmsg, &nrecs, &nbytes, &rate);
|
2023-05-30 14:58:29 +00:00
|
|
|
}
|
|
|
|
json_object_object_add(xfrinobj, "nmsg",
|
|
|
|
json_object_new_int64((int64_t)nmsg));
|
|
|
|
json_object_object_add(xfrinobj, "nrecs",
|
|
|
|
json_object_new_int64((int64_t)nrecs));
|
|
|
|
json_object_object_add(
|
|
|
|
xfrinobj, "nbytes",
|
|
|
|
json_object_new_int64(nbytes > INT64_MAX ? INT64_MAX
|
|
|
|
: (int64_t)nbytes));
|
2024-11-27 10:34:40 +00:00
|
|
|
json_object_object_add(xfrinobj, "rate",
|
|
|
|
json_object_new_int64(rate > INT64_MAX
|
|
|
|
? INT64_MAX
|
|
|
|
: (int64_t)rate));
|
2023-05-30 14:58:29 +00:00
|
|
|
|
|
|
|
if (is_running && is_first_data_received) {
|
|
|
|
json_object_object_add(
|
|
|
|
xfrinobj, "ixfr",
|
|
|
|
json_object_new_string(is_ixfr ? "Yes" : "No"));
|
|
|
|
} else {
|
|
|
|
json_object_object_add(xfrinobj, "ixfr",
|
|
|
|
json_object_new_string(""));
|
|
|
|
}
|
|
|
|
|
|
|
|
json_object_array_add(xfrinarray, xfrinobj);
|
|
|
|
xfrinobj = NULL;
|
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (xfr != NULL) {
|
|
|
|
dns_xfrin_detach(&xfr);
|
|
|
|
}
|
|
|
|
if (xfrinobj != NULL) {
|
|
|
|
json_object_put(xfrinobj);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2013-03-13 14:24:50 -07:00
|
|
|
static isc_result_t
|
2017-09-08 13:39:09 -07:00
|
|
|
generatejson(named_server_t *server, size_t *msglen, const char **msg,
|
2018-03-28 14:19:37 +02:00
|
|
|
json_object **rootp, uint32_t flags) {
|
2013-03-13 14:24:50 -07:00
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
|
|
|
json_object *bindstats, *viewlist, *counters, *obj;
|
2016-06-23 08:44:54 +10:00
|
|
|
json_object *traffic = NULL;
|
|
|
|
json_object *udpreq4 = NULL, *udpresp4 = NULL;
|
|
|
|
json_object *tcpreq4 = NULL, *tcpresp4 = NULL;
|
|
|
|
json_object *udpreq6 = NULL, *udpresp6 = NULL;
|
|
|
|
json_object *tcpreq6 = NULL, *tcpresp6 = NULL;
|
2018-03-28 14:19:37 +02:00
|
|
|
uint64_t nsstat_values[ns_statscounter_max];
|
|
|
|
uint64_t resstat_values[dns_resstatscounter_max];
|
|
|
|
uint64_t adbstat_values[dns_adbstats_max];
|
|
|
|
uint64_t zonestat_values[dns_zonestatscounter_max];
|
|
|
|
uint64_t sockstat_values[isc_sockstatscounter_max];
|
|
|
|
uint64_t udpinsizestat_values[dns_sizecounter_in_max];
|
|
|
|
uint64_t udpoutsizestat_values[dns_sizecounter_out_max];
|
|
|
|
uint64_t tcpinsizestat_values[dns_sizecounter_in_max];
|
|
|
|
uint64_t tcpoutsizestat_values[dns_sizecounter_out_max];
|
2018-02-24 17:55:24 -08:00
|
|
|
#ifdef HAVE_DNSTAP
|
2018-03-28 14:19:37 +02:00
|
|
|
uint64_t dnstapstat_values[dns_dnstapcounter_max];
|
2016-08-18 11:16:06 +10:00
|
|
|
#endif /* ifdef HAVE_DNSTAP */
|
2013-03-13 14:24:50 -07:00
|
|
|
stats_dumparg_t dumparg;
|
2016-01-07 15:34:14 -08:00
|
|
|
char boottime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
|
|
|
|
char configtime[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
|
|
|
|
char nowstr[sizeof "yyyy-mm-ddThh:mm:ss.sssZ"];
|
2013-03-13 14:24:50 -07:00
|
|
|
isc_time_t now;
|
|
|
|
|
|
|
|
REQUIRE(msglen != NULL);
|
|
|
|
REQUIRE(msg != NULL && *msg == NULL);
|
|
|
|
REQUIRE(rootp == NULL || *rootp == NULL);
|
|
|
|
|
|
|
|
bindstats = json_object_new_object();
|
|
|
|
if (bindstats == NULL) {
|
|
|
|
return ISC_R_NOMEMORY;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* These statistics are included no matter which URL we use.
|
|
|
|
*/
|
2021-11-03 14:50:08 +01:00
|
|
|
obj = json_object_new_string(STATS_JSON_VERSION);
|
2013-03-13 14:24:50 -07:00
|
|
|
CHECKMEM(obj);
|
|
|
|
json_object_object_add(bindstats, "json-stats-version", obj);
|
|
|
|
|
2023-03-31 00:12:33 +02:00
|
|
|
now = isc_time_now();
|
2017-09-08 13:39:09 -07:00
|
|
|
isc_time_formatISO8601ms(&named_g_boottime, boottime, sizeof(boottime));
|
2025-04-22 13:46:47 +02:00
|
|
|
isc_time_formatISO8601ms(&named_g_defaultconfigtime, configtime,
|
2017-09-08 13:39:09 -07:00
|
|
|
sizeof configtime);
|
2016-01-07 15:34:14 -08:00
|
|
|
isc_time_formatISO8601ms(&now, nowstr, sizeof(nowstr));
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
obj = json_object_new_string(boottime);
|
|
|
|
CHECKMEM(obj);
|
|
|
|
json_object_object_add(bindstats, "boot-time", obj);
|
|
|
|
|
|
|
|
obj = json_object_new_string(configtime);
|
|
|
|
CHECKMEM(obj);
|
|
|
|
json_object_object_add(bindstats, "config-time", obj);
|
|
|
|
|
|
|
|
obj = json_object_new_string(nowstr);
|
|
|
|
CHECKMEM(obj);
|
|
|
|
json_object_object_add(bindstats, "current-time", obj);
|
2018-08-07 16:46:53 +02:00
|
|
|
obj = json_object_new_string(PACKAGE_VERSION);
|
2015-10-28 09:45:46 +11:00
|
|
|
CHECKMEM(obj);
|
|
|
|
json_object_object_add(bindstats, "version", obj);
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
if ((flags & STATS_JSON_SERVER) != 0) {
|
|
|
|
/* OPCODE counters */
|
|
|
|
counters = json_object_new_object();
|
|
|
|
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
dumparg.type = isc_statsformat_json;
|
|
|
|
dumparg.arg = counters;
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_opcodestats_dump(server->sctx->opcodestats, opcodestat_dump,
|
2014-01-09 15:14:57 -08:00
|
|
|
&dumparg, ISC_STATSDUMP_VERBOSE);
|
2013-03-13 14:24:50 -07:00
|
|
|
if (dumparg.result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_get_object(counters)->count != 0) {
|
|
|
|
json_object_object_add(bindstats, "opcodes", counters);
|
|
|
|
} else {
|
|
|
|
json_object_put(counters);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
2016-06-23 08:44:54 +10:00
|
|
|
/* OPCODE counters */
|
|
|
|
counters = json_object_new_object();
|
|
|
|
|
|
|
|
dumparg.type = isc_statsformat_json;
|
|
|
|
dumparg.arg = counters;
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_rcodestats_dump(server->sctx->rcodestats, rcodestat_dump,
|
2016-06-23 08:44:54 +10:00
|
|
|
&dumparg, ISC_STATSDUMP_VERBOSE);
|
|
|
|
if (dumparg.result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2016-06-23 08:44:54 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_get_object(counters)->count != 0) {
|
|
|
|
json_object_object_add(bindstats, "rcodes", counters);
|
|
|
|
} else {
|
|
|
|
json_object_put(counters);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-06-23 08:44:54 +10:00
|
|
|
|
2013-03-13 14:24:50 -07:00
|
|
|
/* QTYPE counters */
|
|
|
|
counters = json_object_new_object();
|
|
|
|
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
dumparg.arg = counters;
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_rdatatypestats_dump(server->sctx->rcvquerystats,
|
2013-03-13 14:24:50 -07:00
|
|
|
rdtypestat_dump, &dumparg, 0);
|
|
|
|
if (dumparg.result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_get_object(counters)->count != 0) {
|
|
|
|
json_object_object_add(bindstats, "qtypes", counters);
|
|
|
|
} else {
|
|
|
|
json_object_put(counters);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
/* server stat counters */
|
|
|
|
counters = json_object_new_object();
|
|
|
|
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
dumparg.arg = counters;
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
result = dump_stats(ns_stats_get(server->sctx->nsstats),
|
|
|
|
isc_statsformat_json, counters, NULL,
|
|
|
|
nsstats_xmldesc, ns_statscounter_max,
|
|
|
|
nsstats_index, nsstat_values, 0);
|
2013-03-13 14:24:50 -07:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_get_object(counters)->count != 0) {
|
|
|
|
json_object_object_add(bindstats, "nsstats", counters);
|
|
|
|
} else {
|
|
|
|
json_object_put(counters);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
/* zone stat counters */
|
|
|
|
counters = json_object_new_object();
|
|
|
|
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
dumparg.arg = counters;
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
result = dump_stats(server->zonestats, isc_statsformat_json,
|
|
|
|
counters, NULL, zonestats_xmldesc,
|
|
|
|
dns_zonestatscounter_max, zonestats_index,
|
|
|
|
zonestat_values, 0);
|
2013-03-13 14:24:50 -07:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_get_object(counters)->count != 0) {
|
|
|
|
json_object_object_add(bindstats, "zonestats",
|
|
|
|
counters);
|
|
|
|
} else {
|
|
|
|
json_object_put(counters);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
/* resolver stat counters */
|
|
|
|
counters = json_object_new_object();
|
|
|
|
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
dumparg.arg = counters;
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
result = dump_stats(server->resolverstats, isc_statsformat_json,
|
|
|
|
counters, NULL, resstats_xmldesc,
|
|
|
|
dns_resstatscounter_max, resstats_index,
|
|
|
|
resstat_values, 0);
|
2013-03-13 14:24:50 -07:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_get_object(counters)->count != 0) {
|
|
|
|
json_object_object_add(bindstats, "resstats", counters);
|
|
|
|
} else {
|
|
|
|
json_object_put(counters);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-08-18 11:16:06 +10:00
|
|
|
|
2018-02-24 17:55:24 -08:00
|
|
|
#ifdef HAVE_DNSTAP
|
2016-08-18 11:16:06 +10:00
|
|
|
/* dnstap stat counters */
|
2017-09-08 13:39:09 -07:00
|
|
|
if (named_g_server->dtenv != NULL) {
|
2016-08-18 11:16:06 +10:00
|
|
|
isc_stats_t *dnstapstats = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_dt_getstats(named_g_server->dtenv, &dnstapstats);
|
2016-08-18 11:16:06 +10:00
|
|
|
counters = json_object_new_object();
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
dumparg.arg = counters;
|
2023-03-16 14:31:46 +00:00
|
|
|
result = dump_stats(dnstapstats, isc_statsformat_json,
|
|
|
|
counters, NULL, dnstapstats_xmldesc,
|
|
|
|
dns_dnstapcounter_max,
|
|
|
|
dnstapstats_index,
|
|
|
|
dnstapstat_values, 0);
|
2016-08-18 11:16:06 +10:00
|
|
|
isc_stats_detach(&dnstapstats);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2016-08-18 11:16:06 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_get_object(counters)->count != 0) {
|
|
|
|
json_object_object_add(bindstats, "dnstapstats",
|
|
|
|
counters);
|
|
|
|
} else {
|
|
|
|
json_object_put(counters);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-08-18 11:16:06 +10:00
|
|
|
}
|
|
|
|
#endif /* ifdef HAVE_DNSTAP */
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
2023-05-30 14:58:29 +00:00
|
|
|
if ((flags &
|
|
|
|
(STATS_JSON_SERVER | STATS_JSON_ZONES | STATS_JSON_XFRINS)) != 0)
|
|
|
|
{
|
2013-03-13 14:24:50 -07:00
|
|
|
viewlist = json_object_new_object();
|
|
|
|
CHECKMEM(viewlist);
|
|
|
|
|
|
|
|
json_object_object_add(bindstats, "views", viewlist);
|
|
|
|
|
2025-03-22 15:26:16 -07:00
|
|
|
ISC_LIST_FOREACH(server->viewlist, view, link) {
|
2023-05-30 14:58:29 +00:00
|
|
|
json_object *za, *xa, *v = json_object_new_object();
|
2023-06-08 16:58:45 +10:00
|
|
|
dns_adb_t *adb = NULL;
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
CHECKMEM(v);
|
|
|
|
json_object_object_add(viewlist, view->name, v);
|
|
|
|
|
|
|
|
za = json_object_new_array();
|
|
|
|
CHECKMEM(za);
|
|
|
|
|
|
|
|
if ((flags & STATS_JSON_ZONES) != 0) {
|
2023-05-31 15:52:36 +10:00
|
|
|
CHECK(dns_view_apply(view, true, NULL,
|
|
|
|
zone_jsonrender, za));
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_array_length(za) != 0) {
|
|
|
|
json_object_object_add(v, "zones", za);
|
|
|
|
} else {
|
|
|
|
json_object_put(za);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
2023-05-30 14:58:29 +00:00
|
|
|
xa = json_object_new_array();
|
|
|
|
CHECKMEM(xa);
|
|
|
|
|
|
|
|
if ((flags & STATS_JSON_XFRINS) != 0) {
|
|
|
|
CHECK(dns_zt_apply(view->zonetable, true, NULL,
|
|
|
|
xfrin_jsonrender, xa));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_array_length(xa) != 0) {
|
|
|
|
json_object_object_add(v, "xfrins", xa);
|
|
|
|
} else {
|
|
|
|
json_object_put(xa);
|
|
|
|
}
|
|
|
|
|
2013-03-13 14:24:50 -07:00
|
|
|
if ((flags & STATS_JSON_SERVER) != 0) {
|
2022-05-11 15:38:54 -07:00
|
|
|
json_object *res = NULL;
|
|
|
|
dns_stats_t *dstats = NULL;
|
|
|
|
isc_stats_t *istats = NULL;
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
res = json_object_new_object();
|
|
|
|
CHECKMEM(res);
|
|
|
|
json_object_object_add(v, "resolver", res);
|
|
|
|
|
2022-05-11 15:38:54 -07:00
|
|
|
dns_resolver_getstats(view->resolver, &istats);
|
2013-03-13 14:24:50 -07:00
|
|
|
if (istats != NULL) {
|
|
|
|
counters = json_object_new_object();
|
|
|
|
CHECKMEM(counters);
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
result = dump_stats(
|
2013-03-13 14:24:50 -07:00
|
|
|
istats, isc_statsformat_json,
|
|
|
|
counters, NULL,
|
|
|
|
resstats_xmldesc,
|
|
|
|
dns_resstatscounter_max,
|
|
|
|
resstats_index, resstat_values,
|
|
|
|
0);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
|
|
|
result = dumparg.result;
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
json_object_object_add(res, "stats",
|
|
|
|
counters);
|
2022-05-11 15:38:54 -07:00
|
|
|
isc_stats_detach(&istats);
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
2022-05-11 15:38:54 -07:00
|
|
|
dns_resolver_getquerystats(view->resolver,
|
|
|
|
&dstats);
|
2013-03-13 14:24:50 -07:00
|
|
|
if (dstats != NULL) {
|
|
|
|
counters = json_object_new_object();
|
|
|
|
CHECKMEM(counters);
|
|
|
|
|
|
|
|
dumparg.arg = counters;
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
dns_rdatatypestats_dump(dstats,
|
|
|
|
rdtypestat_dump,
|
|
|
|
&dumparg, 0);
|
|
|
|
if (dumparg.result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
|
|
|
result = dumparg.result;
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
json_object_object_add(res, "qtypes",
|
|
|
|
counters);
|
2022-05-11 15:38:54 -07:00
|
|
|
dns_stats_detach(&dstats);
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
dstats = dns_db_getrrsetstats(view->cachedb);
|
|
|
|
if (dstats != NULL) {
|
|
|
|
counters = json_object_new_object();
|
|
|
|
CHECKMEM(counters);
|
|
|
|
|
|
|
|
dumparg.arg = counters;
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
dns_rdatasetstats_dump(
|
|
|
|
dstats, rdatasetstats_dump,
|
|
|
|
&dumparg, 0);
|
|
|
|
if (dumparg.result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
|
|
|
result = dumparg.result;
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
json_object_object_add(res, "cache",
|
|
|
|
counters);
|
|
|
|
}
|
|
|
|
|
|
|
|
counters = json_object_new_object();
|
|
|
|
CHECKMEM(counters);
|
|
|
|
|
|
|
|
result = dns_cache_renderjson(view->cache,
|
|
|
|
counters);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
json_object_object_add(res, "cachestats",
|
|
|
|
counters);
|
|
|
|
|
2023-06-08 16:58:45 +10:00
|
|
|
dns_view_getadb(view, &adb);
|
|
|
|
if (adb != NULL) {
|
|
|
|
istats = dns_adb_getstats(adb);
|
|
|
|
dns_adb_detach(&adb);
|
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
if (istats != NULL) {
|
|
|
|
counters = json_object_new_object();
|
|
|
|
CHECKMEM(counters);
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
result = dump_stats(
|
2013-03-13 14:24:50 -07:00
|
|
|
istats, isc_statsformat_json,
|
|
|
|
counters, NULL,
|
|
|
|
adbstats_xmldesc,
|
|
|
|
dns_adbstats_max,
|
|
|
|
adbstats_index, adbstat_values,
|
|
|
|
0);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
|
|
|
result = dumparg.result;
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
json_object_object_add(res, "adb",
|
|
|
|
counters);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & STATS_JSON_NET) != 0) {
|
|
|
|
/* socket stat counters */
|
|
|
|
counters = json_object_new_object();
|
|
|
|
|
|
|
|
dumparg.result = ISC_R_SUCCESS;
|
|
|
|
dumparg.arg = counters;
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
result = dump_stats(server->sockstats, isc_statsformat_json,
|
|
|
|
counters, NULL, sockstats_xmldesc,
|
|
|
|
isc_sockstatscounter_max, sockstats_index,
|
|
|
|
sockstat_values, 0);
|
2013-03-13 14:24:50 -07:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(counters);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (json_object_get_object(counters)->count != 0) {
|
|
|
|
json_object_object_add(bindstats, "sockstats",
|
|
|
|
counters);
|
|
|
|
} else {
|
|
|
|
json_object_put(counters);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & STATS_JSON_MEM) != 0) {
|
|
|
|
json_object *memory = json_object_new_object();
|
|
|
|
CHECKMEM(memory);
|
|
|
|
|
|
|
|
result = isc_mem_renderjson(memory);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
json_object_put(memory);
|
2020-07-09 19:36:10 -07:00
|
|
|
goto cleanup;
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
json_object_object_add(bindstats, "memory", memory);
|
|
|
|
}
|
|
|
|
|
2015-07-06 22:20:03 -07:00
|
|
|
if ((flags & STATS_JSON_TRAFFIC) != 0) {
|
|
|
|
traffic = json_object_new_object();
|
|
|
|
CHECKMEM(traffic);
|
|
|
|
|
2016-06-23 08:44:54 +10:00
|
|
|
udpreq4 = json_object_new_object();
|
|
|
|
CHECKMEM(udpreq4);
|
|
|
|
|
|
|
|
udpresp4 = json_object_new_object();
|
|
|
|
CHECKMEM(udpresp4);
|
|
|
|
|
|
|
|
tcpreq4 = json_object_new_object();
|
|
|
|
CHECKMEM(tcpreq4);
|
|
|
|
|
|
|
|
tcpresp4 = json_object_new_object();
|
|
|
|
CHECKMEM(tcpresp4);
|
|
|
|
|
|
|
|
udpreq6 = json_object_new_object();
|
|
|
|
CHECKMEM(udpreq6);
|
|
|
|
|
|
|
|
udpresp6 = json_object_new_object();
|
|
|
|
CHECKMEM(udpresp6);
|
|
|
|
|
|
|
|
tcpreq6 = json_object_new_object();
|
|
|
|
CHECKMEM(tcpreq6);
|
|
|
|
|
|
|
|
tcpresp6 = json_object_new_object();
|
|
|
|
CHECKMEM(tcpresp6);
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
CHECK(dump_histo(server->sctx->udpinstats4,
|
|
|
|
isc_statsformat_json, udpreq4, NULL,
|
|
|
|
udpinsizestats_xmldesc, dns_sizecounter_in_max,
|
|
|
|
udpinsizestats_index, udpinsizestat_values,
|
|
|
|
0));
|
|
|
|
|
|
|
|
CHECK(dump_histo(server->sctx->udpoutstats4,
|
|
|
|
isc_statsformat_json, udpresp4, NULL,
|
|
|
|
udpoutsizestats_xmldesc,
|
|
|
|
dns_sizecounter_out_max, udpoutsizestats_index,
|
|
|
|
udpoutsizestat_values, 0));
|
|
|
|
|
|
|
|
CHECK(dump_histo(server->sctx->tcpinstats4,
|
|
|
|
isc_statsformat_json, tcpreq4, NULL,
|
|
|
|
tcpinsizestats_xmldesc, dns_sizecounter_in_max,
|
|
|
|
tcpinsizestats_index, tcpinsizestat_values,
|
|
|
|
0));
|
|
|
|
|
|
|
|
CHECK(dump_histo(server->sctx->tcpoutstats4,
|
|
|
|
isc_statsformat_json, tcpresp4, NULL,
|
|
|
|
tcpoutsizestats_xmldesc,
|
|
|
|
dns_sizecounter_out_max, tcpoutsizestats_index,
|
|
|
|
tcpoutsizestat_values, 0));
|
|
|
|
|
|
|
|
CHECK(dump_histo(server->sctx->udpinstats6,
|
|
|
|
isc_statsformat_json, udpreq6, NULL,
|
|
|
|
udpinsizestats_xmldesc, dns_sizecounter_in_max,
|
|
|
|
udpinsizestats_index, udpinsizestat_values,
|
|
|
|
0));
|
|
|
|
|
|
|
|
CHECK(dump_histo(server->sctx->udpoutstats6,
|
|
|
|
isc_statsformat_json, udpresp6, NULL,
|
|
|
|
udpoutsizestats_xmldesc,
|
|
|
|
dns_sizecounter_out_max, udpoutsizestats_index,
|
|
|
|
udpoutsizestat_values, 0));
|
|
|
|
|
|
|
|
CHECK(dump_histo(server->sctx->tcpinstats6,
|
|
|
|
isc_statsformat_json, tcpreq6, NULL,
|
|
|
|
tcpinsizestats_xmldesc, dns_sizecounter_in_max,
|
|
|
|
tcpinsizestats_index, tcpinsizestat_values,
|
|
|
|
0));
|
|
|
|
|
|
|
|
CHECK(dump_histo(server->sctx->tcpoutstats6,
|
|
|
|
isc_statsformat_json, tcpresp6, NULL,
|
|
|
|
tcpoutsizestats_xmldesc,
|
|
|
|
dns_sizecounter_out_max, tcpoutsizestats_index,
|
|
|
|
tcpoutsizestat_values, 0));
|
2015-07-06 22:20:03 -07:00
|
|
|
|
|
|
|
json_object_object_add(traffic,
|
2016-06-23 08:44:54 +10:00
|
|
|
"dns-udp-requests-sizes-received-ipv4",
|
|
|
|
udpreq4);
|
2015-07-06 22:20:03 -07:00
|
|
|
json_object_object_add(
|
2016-06-23 08:44:54 +10:00
|
|
|
traffic, "dns-udp-responses-sizes-sent-ipv4", udpresp4);
|
2015-07-06 22:20:03 -07:00
|
|
|
json_object_object_add(traffic,
|
2016-06-23 08:44:54 +10:00
|
|
|
"dns-tcp-requests-sizes-received-ipv4",
|
|
|
|
tcpreq4);
|
2015-07-06 22:20:03 -07:00
|
|
|
json_object_object_add(
|
2016-06-23 08:44:54 +10:00
|
|
|
traffic, "dns-tcp-responses-sizes-sent-ipv4", tcpresp4);
|
|
|
|
json_object_object_add(traffic,
|
|
|
|
"dns-udp-requests-sizes-received-ipv6",
|
|
|
|
udpreq6);
|
|
|
|
json_object_object_add(
|
|
|
|
traffic, "dns-udp-responses-sizes-sent-ipv6", udpresp6);
|
|
|
|
json_object_object_add(traffic,
|
|
|
|
"dns-tcp-requests-sizes-received-ipv6",
|
|
|
|
tcpreq6);
|
|
|
|
json_object_object_add(
|
|
|
|
traffic, "dns-tcp-responses-sizes-sent-ipv6", tcpresp6);
|
2015-07-06 22:20:03 -07:00
|
|
|
json_object_object_add(bindstats, "traffic", traffic);
|
2016-06-23 08:44:54 +10:00
|
|
|
udpreq4 = NULL;
|
|
|
|
udpresp4 = NULL;
|
|
|
|
tcpreq4 = NULL;
|
|
|
|
tcpresp4 = NULL;
|
|
|
|
udpreq6 = NULL;
|
|
|
|
udpresp6 = NULL;
|
|
|
|
tcpreq6 = NULL;
|
|
|
|
tcpresp6 = NULL;
|
|
|
|
traffic = NULL;
|
2015-07-06 22:20:03 -07:00
|
|
|
}
|
|
|
|
|
2013-03-13 14:24:50 -07:00
|
|
|
*msg = json_object_to_json_string_ext(bindstats,
|
|
|
|
JSON_C_TO_STRING_PRETTY);
|
|
|
|
*msglen = strlen(*msg);
|
|
|
|
|
|
|
|
if (rootp != NULL) {
|
|
|
|
*rootp = bindstats;
|
|
|
|
bindstats = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
|
2020-07-09 19:36:10 -07:00
|
|
|
cleanup:
|
2016-06-23 08:44:54 +10:00
|
|
|
if (udpreq4 != NULL) {
|
|
|
|
json_object_put(udpreq4);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-06-23 08:44:54 +10:00
|
|
|
if (udpresp4 != NULL) {
|
|
|
|
json_object_put(udpresp4);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-06-23 08:44:54 +10:00
|
|
|
if (tcpreq4 != NULL) {
|
|
|
|
json_object_put(tcpreq4);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-06-23 08:44:54 +10:00
|
|
|
if (tcpresp4 != NULL) {
|
|
|
|
json_object_put(tcpresp4);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-06-23 08:44:54 +10:00
|
|
|
if (udpreq6 != NULL) {
|
|
|
|
json_object_put(udpreq6);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-06-23 08:44:54 +10:00
|
|
|
if (udpresp6 != NULL) {
|
|
|
|
json_object_put(udpresp6);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-06-23 08:44:54 +10:00
|
|
|
if (tcpreq6 != NULL) {
|
|
|
|
json_object_put(tcpreq6);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-06-23 08:44:54 +10:00
|
|
|
if (tcpresp6 != NULL) {
|
|
|
|
json_object_put(tcpresp6);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-06-23 08:44:54 +10:00
|
|
|
if (traffic != NULL) {
|
|
|
|
json_object_put(traffic);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
if (bindstats != NULL) {
|
|
|
|
json_object_put(bindstats);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_json(uint32_t flags, void *arg, unsigned int *retcode,
|
|
|
|
const char **retmsg, const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2013-03-13 14:24:50 -07:00
|
|
|
isc_result_t result;
|
|
|
|
json_object *bindstats = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
named_server_t *server = arg;
|
2013-03-13 14:24:50 -07:00
|
|
|
const char *msg = NULL;
|
2015-10-28 09:45:46 +11:00
|
|
|
size_t msglen = 0;
|
2013-03-13 14:24:50 -07:00
|
|
|
char *p;
|
|
|
|
|
|
|
|
result = generatejson(server, &msglen, &msg, &bindstats, flags);
|
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
*retcode = 200;
|
|
|
|
*retmsg = "OK";
|
|
|
|
*mimetype = "application/json";
|
2023-03-30 22:34:12 +02:00
|
|
|
p = UNCONST(msg);
|
2013-03-13 14:24:50 -07:00
|
|
|
isc_buffer_reinit(b, p, msglen);
|
|
|
|
isc_buffer_add(b, msglen);
|
|
|
|
*freecb = wrap_jsonfree;
|
|
|
|
*freecb_args = bindstats;
|
|
|
|
} else {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR, "failed at rendering JSON()");
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-03-13 14:24:50 -07:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_json_all(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2013-03-13 14:24:50 -07:00
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_json(STATS_JSON_ALL, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2014-01-09 15:14:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_json_status(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2014-01-09 15:14:57 -08:00
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_json(STATS_JSON_STATUS, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_json_server(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2013-03-13 14:24:50 -07:00
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_json(STATS_JSON_SERVER, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_json_zones(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2013-03-13 14:24:50 -07:00
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_json(STATS_JSON_ZONES, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
2015-07-06 22:20:03 -07:00
|
|
|
|
2023-05-30 14:58:29 +00:00
|
|
|
static isc_result_t
|
|
|
|
render_json_xfrins(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_json(STATS_JSON_XFRINS, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
|
|
|
}
|
|
|
|
|
2013-03-13 14:24:50 -07:00
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_json_mem(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2013-03-13 14:24:50 -07:00
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_json(STATS_JSON_MEM, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_json_net(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2013-03-13 14:24:50 -07:00
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_json(STATS_JSON_NET, arg, retcode, retmsg, mimetype, b,
|
|
|
|
freecb, freecb_args);
|
2013-03-13 14:24:50 -07:00
|
|
|
}
|
2015-07-06 22:20:03 -07:00
|
|
|
|
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_json_traffic(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo,
|
|
|
|
void *arg, unsigned int *retcode, const char **retmsg,
|
2015-07-06 22:20:03 -07:00
|
|
|
const char **mimetype, isc_buffer_t *b,
|
|
|
|
isc_httpdfree_t **freecb, void **freecb_args) {
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
|
|
|
UNUSED(urlinfo);
|
|
|
|
return render_json(STATS_JSON_TRAFFIC, arg, retcode, retmsg, mimetype,
|
|
|
|
b, freecb, freecb_args);
|
2015-07-06 22:20:03 -07:00
|
|
|
}
|
|
|
|
|
2019-02-06 11:56:42 +01:00
|
|
|
#endif /* HAVE_JSON_C */
|
2013-03-13 14:24:50 -07:00
|
|
|
|
2024-08-27 08:54:54 +10:00
|
|
|
#if HAVE_LIBXML2
|
|
|
|
/*
|
|
|
|
* This is only needed if we have libxml2 and was confusingly returned if
|
|
|
|
* neither of libxml2 or json-c is configured.
|
|
|
|
*/
|
2008-01-17 00:15:14 +00:00
|
|
|
static isc_result_t
|
2022-10-06 12:56:25 +02:00
|
|
|
render_xsl(const isc_httpd_t *httpd, const isc_httpdurl_t *urlinfo, void *args,
|
|
|
|
unsigned int *retcode, const char **retmsg, const char **mimetype,
|
|
|
|
isc_buffer_t *b, isc_httpdfree_t **freecb, void **freecb_args) {
|
2014-01-09 15:14:57 -08:00
|
|
|
isc_result_t result;
|
2022-10-06 12:56:25 +02:00
|
|
|
char *p = NULL;
|
2014-01-09 15:14:57 -08:00
|
|
|
|
2022-10-06 12:56:25 +02:00
|
|
|
UNUSED(httpd);
|
2008-01-17 00:15:14 +00:00
|
|
|
UNUSED(args);
|
|
|
|
|
2014-01-09 15:14:57 -08:00
|
|
|
*freecb = NULL;
|
|
|
|
*freecb_args = NULL;
|
|
|
|
*mimetype = "text/xslt+xml";
|
|
|
|
|
2022-10-06 12:56:25 +02:00
|
|
|
if (isc_httpdurl_isstatic(urlinfo)) {
|
|
|
|
time_t t1, t2;
|
|
|
|
const isc_time_t *when;
|
|
|
|
const isc_time_t *loadtime;
|
|
|
|
|
|
|
|
when = isc_httpd_if_modified_since(httpd);
|
2018-04-09 09:29:02 +02:00
|
|
|
|
2022-10-06 12:56:25 +02:00
|
|
|
if (isc_time_isepoch(when)) {
|
2018-05-01 16:05:01 +10:00
|
|
|
goto send;
|
|
|
|
}
|
|
|
|
|
2022-10-06 12:56:25 +02:00
|
|
|
result = isc_time_secondsastimet(when, &t1);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
goto send;
|
|
|
|
}
|
2014-01-09 15:14:57 -08:00
|
|
|
|
2022-10-06 12:56:25 +02:00
|
|
|
loadtime = isc_httpdurl_loadtime(urlinfo);
|
2014-01-09 15:14:57 -08:00
|
|
|
|
2022-10-06 12:56:25 +02:00
|
|
|
result = isc_time_secondsastimet(loadtime, &t2);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
goto send;
|
|
|
|
}
|
2014-01-09 15:14:57 -08:00
|
|
|
|
2022-10-06 12:56:25 +02:00
|
|
|
if (t1 < t2) {
|
|
|
|
goto send;
|
2014-01-09 15:14:57 -08:00
|
|
|
}
|
2022-10-06 12:56:25 +02:00
|
|
|
|
|
|
|
*retcode = 304;
|
|
|
|
*retmsg = "Not modified";
|
|
|
|
goto end;
|
2014-01-09 15:14:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
send:
|
2008-01-17 00:15:14 +00:00
|
|
|
*retcode = 200;
|
|
|
|
*retmsg = "OK";
|
2023-03-30 22:34:12 +02:00
|
|
|
p = UNCONST(xslmsg);
|
2018-08-07 16:46:53 +02:00
|
|
|
isc_buffer_reinit(b, p, strlen(xslmsg));
|
2008-04-03 05:55:52 +00:00
|
|
|
isc_buffer_add(b, strlen(xslmsg));
|
2018-04-09 09:29:02 +02:00
|
|
|
end:
|
2008-01-17 00:15:14 +00:00
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
2024-08-27 08:54:54 +10:00
|
|
|
#endif
|
2008-01-17 00:15:14 +00:00
|
|
|
|
|
|
|
static void
|
2017-09-08 13:39:09 -07:00
|
|
|
shutdown_listener(named_statschannel_t *listener) {
|
2008-01-17 00:15:14 +00:00
|
|
|
char socktext[ISC_SOCKADDR_FORMATSIZE];
|
|
|
|
isc_sockaddr_format(&listener->address, socktext, sizeof(socktext));
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_NOTICE, "stopping statistics channel on %s",
|
|
|
|
socktext);
|
2008-01-17 00:15:14 +00:00
|
|
|
|
|
|
|
isc_httpdmgr_shutdown(&listener->httpdmgr);
|
|
|
|
}
|
|
|
|
|
2024-08-27 11:22:41 +10:00
|
|
|
#if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C)
|
2018-04-17 08:29:14 -07:00
|
|
|
static bool
|
2008-01-17 00:15:14 +00:00
|
|
|
client_ok(const isc_sockaddr_t *fromaddr, void *arg) {
|
2017-09-08 13:39:09 -07:00
|
|
|
named_statschannel_t *listener = arg;
|
|
|
|
dns_aclenv_t *env =
|
|
|
|
ns_interfacemgr_getaclenv(named_g_server->interfacemgr);
|
2008-01-17 00:15:14 +00:00
|
|
|
isc_netaddr_t netaddr;
|
|
|
|
char socktext[ISC_SOCKADDR_FORMATSIZE];
|
|
|
|
int match;
|
|
|
|
|
|
|
|
REQUIRE(listener != NULL);
|
|
|
|
|
|
|
|
isc_netaddr_fromsockaddr(&netaddr, fromaddr);
|
|
|
|
|
|
|
|
LOCK(&listener->lock);
|
2018-04-26 20:57:41 -07:00
|
|
|
if ((dns_acl_match(&netaddr, NULL, listener->acl, env, &match, NULL) ==
|
|
|
|
ISC_R_SUCCESS) &&
|
|
|
|
match > 0)
|
|
|
|
{
|
2008-01-17 00:15:14 +00:00
|
|
|
UNLOCK(&listener->lock);
|
2018-04-17 08:29:14 -07:00
|
|
|
return true;
|
2008-01-17 00:15:14 +00:00
|
|
|
}
|
|
|
|
UNLOCK(&listener->lock);
|
2008-01-18 23:46:58 +00:00
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
isc_sockaddr_format(fromaddr, socktext, sizeof(socktext));
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_WARNING, "rejected statistics connection from %s",
|
|
|
|
socktext);
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return false;
|
2008-01-17 00:15:14 +00:00
|
|
|
}
|
2024-08-27 11:22:41 +10:00
|
|
|
#endif
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2024-08-27 11:22:41 +10:00
|
|
|
#if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C)
|
2008-01-17 00:15:14 +00:00
|
|
|
static void
|
|
|
|
destroy_listener(void *arg) {
|
2020-07-09 19:36:10 -07:00
|
|
|
named_statschannel_t *listener = (named_statschannel_t *)arg;
|
2008-01-17 00:15:14 +00:00
|
|
|
|
|
|
|
REQUIRE(listener != NULL);
|
|
|
|
REQUIRE(!ISC_LINK_LINKED(listener, link));
|
|
|
|
|
2008-04-09 22:48:17 +00:00
|
|
|
/* We don't have to acquire the lock here since it's already unlinked */
|
2008-01-17 00:15:14 +00:00
|
|
|
dns_acl_detach(&listener->acl);
|
|
|
|
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&listener->lock);
|
2008-01-17 00:15:14 +00:00
|
|
|
isc_mem_putanddetach(&listener->mctx, listener, sizeof(*listener));
|
|
|
|
}
|
2024-08-27 11:22:41 +10:00
|
|
|
#endif
|
2008-01-17 00:15:14 +00:00
|
|
|
|
|
|
|
static isc_result_t
|
2017-09-08 13:39:09 -07:00
|
|
|
add_listener(named_server_t *server, named_statschannel_t **listenerp,
|
2008-01-17 00:15:14 +00:00
|
|
|
const cfg_obj_t *listen_params, const cfg_obj_t *config,
|
|
|
|
isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx,
|
|
|
|
const char *socktext) {
|
2024-08-27 11:22:41 +10:00
|
|
|
#if !defined(HAVE_LIBXML2) && !defined(HAVE_JSON_C)
|
|
|
|
UNUSED(server);
|
|
|
|
UNUSED(listenerp);
|
|
|
|
UNUSED(listen_params);
|
|
|
|
UNUSED(config);
|
|
|
|
UNUSED(addr);
|
|
|
|
UNUSED(aclconfctx);
|
|
|
|
UNUSED(socktext);
|
|
|
|
|
|
|
|
return ISC_R_NOTIMPLEMENTED;
|
|
|
|
#else
|
2008-01-17 00:15:14 +00:00
|
|
|
isc_result_t result;
|
2020-07-09 19:36:10 -07:00
|
|
|
named_statschannel_t *listener = NULL;
|
|
|
|
const cfg_obj_t *allow = NULL;
|
2008-01-17 00:15:14 +00:00
|
|
|
dns_acl_t *new_acl = NULL;
|
2020-07-09 19:36:10 -07:00
|
|
|
int pf;
|
2008-01-17 00:15:14 +00:00
|
|
|
|
|
|
|
listener = isc_mem_get(server->mctx, sizeof(*listener));
|
2020-07-09 19:36:10 -07:00
|
|
|
*listener = (named_statschannel_t){ .address = *addr };
|
2008-01-17 00:15:14 +00:00
|
|
|
ISC_LINK_INIT(listener, link);
|
2018-11-16 15:33:22 +01:00
|
|
|
isc_mutex_init(&listener->lock);
|
2008-01-17 00:15:14 +00:00
|
|
|
isc_mem_attach(server->mctx, &listener->mctx);
|
|
|
|
|
|
|
|
allow = cfg_tuple_get(listen_params, "allow");
|
|
|
|
if (allow != NULL && cfg_obj_islist(allow)) {
|
2024-08-13 18:20:26 +02:00
|
|
|
result = cfg_acl_fromconfig(allow, config, aclconfctx,
|
|
|
|
listener->mctx, 0, &new_acl);
|
2008-01-17 00:15:14 +00:00
|
|
|
} else {
|
|
|
|
result = dns_acl_any(listener->mctx, &new_acl);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-07-09 19:36:10 -07:00
|
|
|
CHECK(result);
|
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
dns_acl_attach(new_acl, &listener->acl);
|
|
|
|
dns_acl_detach(&new_acl);
|
|
|
|
|
2020-07-09 19:36:10 -07:00
|
|
|
pf = isc_sockaddr_pf(&listener->address);
|
|
|
|
if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) ||
|
|
|
|
(pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS))
|
|
|
|
{
|
|
|
|
CHECK(ISC_R_FAMILYNOSUPPORT);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2025-07-14 17:12:35 +02:00
|
|
|
CHECK(isc_httpdmgr_create(server->mctx, addr, client_ok,
|
2020-07-09 19:36:10 -07:00
|
|
|
destroy_listener, listener,
|
|
|
|
&listener->httpdmgr));
|
2008-01-17 00:15:14 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_LIBXML2
|
2020-07-09 19:36:10 -07:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr, "/", false, render_xml_all,
|
|
|
|
server);
|
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr, "/xml", false, render_xml_all,
|
2014-01-09 15:14:57 -08:00
|
|
|
server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/xml/v" STATS_XML_VERSION_MAJOR, false,
|
2020-07-09 19:36:10 -07:00
|
|
|
render_xml_all, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/xml/v" STATS_XML_VERSION_MAJOR "/status", false,
|
2014-01-09 15:14:57 -08:00
|
|
|
render_xml_status, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/xml/v" STATS_XML_VERSION_MAJOR "/server", false,
|
2014-01-09 15:14:57 -08:00
|
|
|
render_xml_server, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/xml/v" STATS_XML_VERSION_MAJOR "/zones", false,
|
2014-01-09 15:14:57 -08:00
|
|
|
render_xml_zones, server);
|
2023-05-30 14:58:29 +00:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/xml/v" STATS_XML_VERSION_MAJOR "/xfrins", false,
|
|
|
|
render_xml_xfrins, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/xml/v" STATS_XML_VERSION_MAJOR "/net", false,
|
2020-07-09 19:36:10 -07:00
|
|
|
render_xml_net, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/xml/v" STATS_XML_VERSION_MAJOR "/mem", false,
|
2020-07-09 19:36:10 -07:00
|
|
|
render_xml_mem, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/xml/v" STATS_XML_VERSION_MAJOR "/traffic", false,
|
2015-07-06 22:20:03 -07:00
|
|
|
render_xml_traffic, server);
|
2024-08-27 08:54:54 +10:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr, "/bind9.xsl", true, render_xsl,
|
|
|
|
server);
|
2013-03-13 14:24:50 -07:00
|
|
|
#endif /* ifdef HAVE_LIBXML2 */
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifdef HAVE_JSON_C
|
2020-07-09 19:36:10 -07:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr, "/json", false, render_json_all,
|
2013-03-13 14:24:50 -07:00
|
|
|
server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/json/v" STATS_JSON_VERSION_MAJOR, false,
|
2020-07-09 19:36:10 -07:00
|
|
|
render_json_all, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/json/v" STATS_JSON_VERSION_MAJOR "/status", false,
|
2014-01-09 15:14:57 -08:00
|
|
|
render_json_status, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/json/v" STATS_JSON_VERSION_MAJOR "/server", false,
|
2013-03-13 14:24:50 -07:00
|
|
|
render_json_server, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/json/v" STATS_JSON_VERSION_MAJOR "/zones", false,
|
2013-03-13 14:24:50 -07:00
|
|
|
render_json_zones, server);
|
2023-05-30 14:58:29 +00:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/json/v" STATS_JSON_VERSION_MAJOR "/xfrins", false,
|
|
|
|
render_json_xfrins, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/json/v" STATS_JSON_VERSION_MAJOR "/net", false,
|
2020-07-09 19:36:10 -07:00
|
|
|
render_json_net, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/json/v" STATS_JSON_VERSION_MAJOR "/mem", false,
|
2020-07-09 19:36:10 -07:00
|
|
|
render_json_mem, server);
|
2021-11-03 14:50:08 +01:00
|
|
|
isc_httpdmgr_addurl(listener->httpdmgr,
|
|
|
|
"/json/v" STATS_JSON_VERSION_MAJOR "/traffic",
|
|
|
|
false, render_json_traffic, server);
|
2008-01-17 00:15:14 +00:00
|
|
|
#endif /* ifdef HAVE_JSON_C */
|
|
|
|
|
|
|
|
*listenerp = listener;
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_NOTICE, "statistics channel listening on %s",
|
|
|
|
socktext);
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2020-07-09 19:36:10 -07:00
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
cleanup:
|
2020-07-09 19:36:10 -07:00
|
|
|
if (listener->acl != NULL) {
|
|
|
|
dns_acl_detach(&listener->acl);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-07-09 19:36:10 -07:00
|
|
|
isc_mutex_destroy(&listener->lock);
|
|
|
|
isc_mem_putanddetach(&listener->mctx, listener, sizeof(*listener));
|
2008-01-17 00:15:14 +00:00
|
|
|
|
|
|
|
return result;
|
2024-08-27 11:22:41 +10:00
|
|
|
#endif
|
2008-01-17 00:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-09-08 13:39:09 -07:00
|
|
|
update_listener(named_server_t *server, named_statschannel_t **listenerp,
|
2008-01-17 00:15:14 +00:00
|
|
|
const cfg_obj_t *listen_params, const cfg_obj_t *config,
|
|
|
|
isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx,
|
|
|
|
const char *socktext) {
|
2025-03-20 22:25:56 -07:00
|
|
|
named_statschannel_t *listener = NULL;
|
2008-01-17 00:15:14 +00:00
|
|
|
const cfg_obj_t *allow = NULL;
|
|
|
|
dns_acl_t *new_acl = NULL;
|
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
|
|
|
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH(server->statschannels, l, link) {
|
|
|
|
if (isc_sockaddr_equal(addr, &l->address)) {
|
|
|
|
listener = l;
|
2008-01-17 00:15:14 +00:00
|
|
|
break;
|
2020-02-13 18:16:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
if (listener == NULL) {
|
|
|
|
*listenerp = NULL;
|
|
|
|
return;
|
|
|
|
}
|
2008-01-18 23:46:58 +00:00
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
/*
|
|
|
|
* Now, keep the old access list unless a new one can be made.
|
|
|
|
*/
|
|
|
|
allow = cfg_tuple_get(listen_params, "allow");
|
2008-01-17 03:01:25 +00:00
|
|
|
if (allow != NULL && cfg_obj_islist(allow)) {
|
2024-08-13 18:20:26 +02:00
|
|
|
result = cfg_acl_fromconfig(allow, config, aclconfctx,
|
|
|
|
listener->mctx, 0, &new_acl);
|
2008-01-17 00:15:14 +00:00
|
|
|
} else {
|
|
|
|
result = dns_acl_any(listener->mctx, &new_acl);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-01-17 00:15:14 +00:00
|
|
|
|
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
LOCK(&listener->lock);
|
|
|
|
|
|
|
|
dns_acl_detach(&listener->acl);
|
|
|
|
dns_acl_attach(new_acl, &listener->acl);
|
|
|
|
dns_acl_detach(&new_acl);
|
|
|
|
|
|
|
|
UNLOCK(&listener->lock);
|
|
|
|
} else {
|
2024-08-13 18:20:26 +02:00
|
|
|
cfg_obj_log(listen_params, ISC_LOG_WARNING,
|
2008-01-17 00:15:14 +00:00
|
|
|
"couldn't install new acl for "
|
|
|
|
"statistics channel %s: %s",
|
|
|
|
socktext, isc_result_totext(result));
|
|
|
|
}
|
|
|
|
|
|
|
|
*listenerp = listener;
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2017-09-08 13:39:09 -07:00
|
|
|
named_statschannels_configure(named_server_t *server, const cfg_obj_t *config,
|
|
|
|
cfg_aclconfctx_t *aclconfctx) {
|
|
|
|
named_statschannellist_t new_listeners;
|
2008-01-17 00:15:14 +00:00
|
|
|
const cfg_obj_t *statschannellist = NULL;
|
|
|
|
char socktext[ISC_SOCKADDR_FORMATSIZE];
|
|
|
|
|
2022-10-14 16:10:41 +02:00
|
|
|
isc_once_do(&once, init_desc);
|
2008-07-17 23:43:26 +00:00
|
|
|
|
2008-01-17 00:15:14 +00:00
|
|
|
ISC_LIST_INIT(new_listeners);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the list of named.conf 'statistics-channels' statements.
|
|
|
|
*/
|
|
|
|
(void)cfg_map_get(config, "statistics-channels", &statschannellist);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Run through the new address/port list, noting sockets that are
|
|
|
|
* already being listened on and moving them to the new list.
|
|
|
|
*
|
|
|
|
* Identifying duplicate addr/port combinations is left to either
|
|
|
|
* the underlying config code, or to the bind attempt getting an
|
|
|
|
* address-in-use error.
|
|
|
|
*/
|
|
|
|
if (statschannellist != NULL) {
|
2014-05-21 12:06:00 +10:00
|
|
|
#ifndef EXTENDED_STATS
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_WARNING,
|
2008-01-17 00:15:14 +00:00
|
|
|
"statistics-channels specified but not effective "
|
2014-05-15 11:12:05 +10:00
|
|
|
"due to missing XML and/or JSON library");
|
2015-08-12 21:58:04 -07:00
|
|
|
#else /* EXTENDED_STATS */
|
|
|
|
#ifndef HAVE_LIBXML2
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_WARNING,
|
2015-08-12 21:58:04 -07:00
|
|
|
"statistics-channels: XML library missing, "
|
|
|
|
"only JSON stats will be available");
|
|
|
|
#endif /* !HAVE_LIBXML2 */
|
2019-02-06 11:56:42 +01:00
|
|
|
#ifndef HAVE_JSON_C
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_WARNING,
|
2015-08-12 21:58:04 -07:00
|
|
|
"statistics-channels: JSON library missing, "
|
|
|
|
"only XML stats will be available");
|
2019-02-06 11:56:42 +01:00
|
|
|
#endif /* !HAVE_JSON_C */
|
2015-08-12 21:58:04 -07:00
|
|
|
#endif /* EXTENDED_STATS */
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2025-03-26 18:54:05 -07:00
|
|
|
CFG_LIST_FOREACH(statschannellist, element) {
|
|
|
|
const cfg_obj_t *statschannel = NULL;
|
2008-01-17 00:15:14 +00:00
|
|
|
const cfg_obj_t *listenercfg = NULL;
|
|
|
|
|
|
|
|
statschannel = cfg_listelt_value(element);
|
|
|
|
(void)cfg_map_get(statschannel, "inet", &listenercfg);
|
|
|
|
if (listenercfg == NULL) {
|
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-01-17 00:15:14 +00:00
|
|
|
|
2025-03-26 18:54:05 -07:00
|
|
|
CFG_LIST_FOREACH(listenercfg, element2) {
|
2025-03-20 22:25:56 -07:00
|
|
|
named_statschannel_t *listener = NULL;
|
|
|
|
const cfg_obj_t *listen_params = NULL;
|
|
|
|
const cfg_obj_t *obj = NULL;
|
2008-01-17 00:15:14 +00:00
|
|
|
isc_sockaddr_t addr;
|
|
|
|
|
|
|
|
listen_params = cfg_listelt_value(element2);
|
|
|
|
|
|
|
|
obj = cfg_tuple_get(listen_params, "address");
|
|
|
|
addr = *cfg_obj_assockaddr(obj);
|
|
|
|
if (isc_sockaddr_getport(&addr) == 0) {
|
2012-11-14 12:44:15 -06:00
|
|
|
isc_sockaddr_setport(
|
|
|
|
&addr,
|
2017-09-08 13:39:09 -07:00
|
|
|
NAMED_STATSCHANNEL_HTTPPORT);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-01-17 00:15:14 +00:00
|
|
|
|
|
|
|
isc_sockaddr_format(&addr, socktext,
|
|
|
|
sizeof(socktext));
|
|
|
|
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
|
2017-09-08 13:39:09 -07:00
|
|
|
NAMED_LOGMODULE_SERVER,
|
2008-01-17 00:15:14 +00:00
|
|
|
ISC_LOG_DEBUG(9),
|
|
|
|
"processing statistics "
|
|
|
|
"channel %s",
|
|
|
|
socktext);
|
|
|
|
|
|
|
|
update_listener(server, &listener,
|
|
|
|
listen_params, config, &addr,
|
|
|
|
aclconfctx, socktext);
|
|
|
|
|
|
|
|
if (listener != NULL) {
|
|
|
|
/*
|
|
|
|
* Remove the listener from the old
|
|
|
|
* list, so it won't be shut down.
|
|
|
|
*/
|
|
|
|
ISC_LIST_UNLINK(server->statschannels,
|
|
|
|
listener, link);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* This is a new listener.
|
|
|
|
*/
|
|
|
|
isc_result_t r;
|
|
|
|
|
|
|
|
r = add_listener(server, &listener,
|
|
|
|
listen_params, config,
|
|
|
|
&addr, aclconfctx,
|
|
|
|
socktext);
|
|
|
|
if (r != ISC_R_SUCCESS) {
|
|
|
|
cfg_obj_log(
|
|
|
|
listen_params,
|
2017-09-08 13:39:09 -07:00
|
|
|
ISC_LOG_WARNING,
|
|
|
|
"couldn't allocate "
|
|
|
|
"statistics channel"
|
|
|
|
" %s: %s",
|
|
|
|
socktext,
|
|
|
|
isc_result_totext(r));
|
2008-01-17 00:15:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (listener != NULL) {
|
|
|
|
ISC_LIST_APPEND(new_listeners, listener,
|
|
|
|
link);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-01-17 00:15:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-05-23 13:02:22 -07:00
|
|
|
ISC_LIST_FOREACH(server->statschannels, listener, link) {
|
2008-01-17 00:15:14 +00:00
|
|
|
ISC_LIST_UNLINK(server->statschannels, listener, link);
|
|
|
|
shutdown_listener(listener);
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LIST_APPENDLIST(server->statschannels, new_listeners, link);
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-09-08 13:39:09 -07:00
|
|
|
named_statschannels_shutdown(named_server_t *server) {
|
2025-05-23 13:02:22 -07:00
|
|
|
ISC_LIST_FOREACH(server->statschannels, listener, link) {
|
2008-01-17 00:15:14 +00:00
|
|
|
ISC_LIST_UNLINK(server->statschannels, listener, link);
|
|
|
|
shutdown_listener(listener);
|
|
|
|
}
|
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
|
|
|
|
isc_result_t
|
2017-09-08 13:39:09 -07:00
|
|
|
named_stats_dump(named_server_t *server, FILE *fp) {
|
2008-04-03 05:55:52 +00:00
|
|
|
isc_result_t result;
|
|
|
|
dns_zone_t *zone, *next;
|
|
|
|
stats_dumparg_t dumparg;
|
2018-03-28 14:19:37 +02:00
|
|
|
uint64_t nsstat_values[ns_statscounter_max];
|
|
|
|
uint64_t resstat_values[dns_resstatscounter_max];
|
|
|
|
uint64_t adbstat_values[dns_adbstats_max];
|
|
|
|
uint64_t zonestat_values[dns_zonestatscounter_max];
|
|
|
|
uint64_t sockstat_values[isc_sockstatscounter_max];
|
|
|
|
uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
|
2023-03-30 21:13:41 +02:00
|
|
|
isc_stdtime_t now = isc_stdtime_now();
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2022-10-14 16:10:41 +02:00
|
|
|
isc_once_do(&once, init_desc);
|
2008-04-09 22:48:17 +00:00
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
/* Set common fields */
|
2012-05-14 10:06:05 -07:00
|
|
|
dumparg.type = isc_statsformat_file;
|
2008-04-03 05:55:52 +00:00
|
|
|
dumparg.arg = fp;
|
|
|
|
|
|
|
|
fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now);
|
|
|
|
|
|
|
|
fprintf(fp, "++ Incoming Requests ++\n");
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_opcodestats_dump(server->sctx->opcodestats, opcodestat_dump,
|
|
|
|
&dumparg, 0);
|
2008-04-03 05:55:52 +00:00
|
|
|
|
|
|
|
fprintf(fp, "++ Incoming Queries ++\n");
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_rdatatypestats_dump(server->sctx->rcvquerystats, rdtypestat_dump,
|
|
|
|
&dumparg, 0);
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2016-06-23 08:44:54 +10:00
|
|
|
fprintf(fp, "++ Outgoing Rcodes ++\n");
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_rcodestats_dump(server->sctx->rcodestats, rcodestat_dump, &dumparg,
|
|
|
|
0);
|
2016-06-23 08:44:54 +10:00
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
fprintf(fp, "++ Outgoing Queries ++\n");
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH(server->viewlist, view, link) {
|
2022-05-11 15:38:54 -07:00
|
|
|
dns_stats_t *dstats = NULL;
|
|
|
|
dns_resolver_getquerystats(view->resolver, &dstats);
|
|
|
|
if (dstats == NULL) {
|
2008-04-03 05:55:52 +00:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
if (strcmp(view->name, "_default") == 0) {
|
|
|
|
fprintf(fp, "[View: default]\n");
|
|
|
|
} else {
|
|
|
|
fprintf(fp, "[View: %s]\n", view->name);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2022-05-11 15:38:54 -07:00
|
|
|
dns_rdatatypestats_dump(dstats, rdtypestat_dump, &dumparg, 0);
|
|
|
|
dns_stats_detach(&dstats);
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(fp, "++ Name Server Statistics ++\n");
|
2023-03-16 14:31:46 +00:00
|
|
|
(void)dump_stats(ns_stats_get(server->sctx->nsstats),
|
|
|
|
isc_statsformat_file, fp, NULL, nsstats_desc,
|
|
|
|
ns_statscounter_max, nsstats_index, nsstat_values, 0);
|
2009-01-27 23:47:54 +00:00
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
fprintf(fp, "++ Zone Maintenance Statistics ++\n");
|
2023-03-16 14:31:46 +00:00
|
|
|
(void)dump_stats(server->zonestats, isc_statsformat_file, fp, NULL,
|
|
|
|
zonestats_desc, dns_zonestatscounter_max,
|
|
|
|
zonestats_index, zonestat_values, 0);
|
2008-04-03 05:55:52 +00:00
|
|
|
|
|
|
|
fprintf(fp, "++ Resolver Statistics ++\n");
|
|
|
|
fprintf(fp, "[Common]\n");
|
2023-03-16 14:31:46 +00:00
|
|
|
(void)dump_stats(server->resolverstats, isc_statsformat_file, fp, NULL,
|
|
|
|
resstats_desc, dns_resstatscounter_max, resstats_index,
|
|
|
|
resstat_values, 0);
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH(server->viewlist, view, link) {
|
2022-05-11 15:38:54 -07:00
|
|
|
isc_stats_t *istats = NULL;
|
|
|
|
dns_resolver_getstats(view->resolver, &istats);
|
|
|
|
if (istats == NULL) {
|
2008-04-03 05:55:52 +00:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
if (strcmp(view->name, "_default") == 0) {
|
|
|
|
fprintf(fp, "[View: default]\n");
|
|
|
|
} else {
|
|
|
|
fprintf(fp, "[View: %s]\n", view->name);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2023-03-16 14:31:46 +00:00
|
|
|
(void)dump_stats(istats, isc_statsformat_file, fp, NULL,
|
|
|
|
resstats_desc, dns_resstatscounter_max,
|
|
|
|
resstats_index, resstat_values, 0);
|
2022-05-11 15:38:54 -07:00
|
|
|
isc_stats_detach(&istats);
|
2012-05-14 10:06:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(fp, "++ Cache Statistics ++\n");
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH(server->viewlist, view, link) {
|
2012-05-14 10:06:05 -07:00
|
|
|
if (strcmp(view->name, "_default") == 0) {
|
|
|
|
fprintf(fp, "[View: default]\n");
|
|
|
|
} else {
|
|
|
|
fprintf(fp, "[View: %s (Cache: %s)]\n", view->name,
|
|
|
|
dns_cache_getname(view->cache));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-14 10:06:05 -07:00
|
|
|
/*
|
|
|
|
* Avoid dumping redundant statistics when the cache is shared.
|
|
|
|
*/
|
|
|
|
if (dns_view_iscacheshared(view)) {
|
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-14 10:06:05 -07:00
|
|
|
dns_cache_dumpstats(view->cache, fp);
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(fp, "++ Cache DB RRsets ++\n");
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH(server->viewlist, view, link) {
|
2012-05-14 10:06:05 -07:00
|
|
|
dns_stats_t *cacherrstats;
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2012-05-14 10:06:05 -07:00
|
|
|
cacherrstats = dns_db_getrrsetstats(view->cachedb);
|
|
|
|
if (cacherrstats == NULL) {
|
2008-04-03 05:55:52 +00:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
if (strcmp(view->name, "_default") == 0) {
|
|
|
|
fprintf(fp, "[View: default]\n");
|
|
|
|
} else {
|
2009-01-09 22:24:37 +00:00
|
|
|
fprintf(fp, "[View: %s (Cache: %s)]\n", view->name,
|
|
|
|
dns_cache_getname(view->cache));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2009-01-09 22:24:37 +00:00
|
|
|
if (dns_view_iscacheshared(view)) {
|
|
|
|
/*
|
|
|
|
* Avoid dumping redundant statistics when the cache is
|
|
|
|
* shared.
|
|
|
|
*/
|
|
|
|
continue;
|
|
|
|
}
|
2012-05-14 10:06:05 -07:00
|
|
|
dns_rdatasetstats_dump(cacherrstats, rdatasetstats_dump,
|
|
|
|
&dumparg, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(fp, "++ ADB stats ++\n");
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH(server->viewlist, view, link) {
|
2023-06-08 16:58:45 +10:00
|
|
|
dns_adb_t *adb = NULL;
|
|
|
|
isc_stats_t *adbstats = NULL;
|
2022-05-11 15:38:54 -07:00
|
|
|
|
2023-06-08 16:58:45 +10:00
|
|
|
dns_view_getadb(view, &adb);
|
|
|
|
if (adb != NULL) {
|
|
|
|
adbstats = dns_adb_getstats(adb);
|
|
|
|
dns_adb_detach(&adb);
|
|
|
|
}
|
2022-05-11 15:38:54 -07:00
|
|
|
if (adbstats == NULL) {
|
2012-05-14 10:06:05 -07:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-05-14 10:06:05 -07:00
|
|
|
if (strcmp(view->name, "_default") == 0) {
|
|
|
|
fprintf(fp, "[View: default]\n");
|
|
|
|
} else {
|
|
|
|
fprintf(fp, "[View: %s]\n", view->name);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2023-03-16 14:31:46 +00:00
|
|
|
(void)dump_stats(adbstats, isc_statsformat_file, fp, NULL,
|
|
|
|
adbstats_desc, dns_adbstats_max,
|
|
|
|
adbstats_index, adbstat_values, 0);
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
|
2009-01-27 22:30:00 +00:00
|
|
|
fprintf(fp, "++ Socket I/O Statistics ++\n");
|
2023-03-16 14:31:46 +00:00
|
|
|
(void)dump_stats(server->sockstats, isc_statsformat_file, fp, NULL,
|
|
|
|
sockstats_desc, isc_sockstatscounter_max,
|
|
|
|
sockstats_index, sockstat_values, 0);
|
2009-01-27 22:30:00 +00:00
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
fprintf(fp, "++ Per Zone Query Statistics ++\n");
|
|
|
|
zone = NULL;
|
|
|
|
for (result = dns_zone_first(server->zonemgr, &zone);
|
|
|
|
result == ISC_R_SUCCESS;
|
|
|
|
next = NULL, result = dns_zone_next(zone, &next), zone = next)
|
|
|
|
{
|
2024-12-06 19:46:39 +01:00
|
|
|
isc_stats_t *zonestats = dns_zone_getrequeststats(zone);
|
2008-04-03 05:55:52 +00:00
|
|
|
if (zonestats != NULL) {
|
|
|
|
char zonename[DNS_NAME_FORMATSIZE];
|
2025-03-20 22:25:56 -07:00
|
|
|
dns_view_t *view = dns_zone_getview(zone);
|
2016-03-21 12:02:00 +11:00
|
|
|
if (view == NULL) {
|
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
|
2016-03-21 12:02:00 +11:00
|
|
|
dns_name_format(dns_zone_getorigin(zone), zonename,
|
|
|
|
sizeof(zonename));
|
2008-04-03 05:55:52 +00:00
|
|
|
fprintf(fp, "[%s", zonename);
|
|
|
|
if (strcmp(view->name, "_default") != 0) {
|
|
|
|
fprintf(fp, " (view: %s)", view->name);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-04-03 05:55:52 +00:00
|
|
|
fprintf(fp, "]\n");
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
(void)dump_stats(zonestats, isc_statsformat_file, fp,
|
|
|
|
NULL, nsstats_desc,
|
|
|
|
ns_statscounter_max, nsstats_index,
|
|
|
|
nsstat_values, 0);
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-06 15:24:16 +05:30
|
|
|
fprintf(fp, "++ Per Zone Glue Cache Statistics ++\n");
|
|
|
|
zone = NULL;
|
|
|
|
for (result = dns_zone_first(server->zonemgr, &zone);
|
|
|
|
result == ISC_R_SUCCESS;
|
|
|
|
next = NULL, result = dns_zone_next(zone, &next), zone = next)
|
|
|
|
{
|
|
|
|
isc_stats_t *gluecachestats = dns_zone_getgluecachestats(zone);
|
|
|
|
if (gluecachestats != NULL) {
|
|
|
|
char zonename[DNS_NAME_FORMATSIZE];
|
2025-03-20 22:25:56 -07:00
|
|
|
dns_view_t *view = dns_zone_getview(zone);
|
2017-10-06 15:24:16 +05:30
|
|
|
if (view == NULL) {
|
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-10-06 15:24:16 +05:30
|
|
|
|
|
|
|
dns_name_format(dns_zone_getorigin(zone), zonename,
|
|
|
|
sizeof(zonename));
|
|
|
|
fprintf(fp, "[%s", zonename);
|
|
|
|
if (strcmp(view->name, "_default") != 0) {
|
|
|
|
fprintf(fp, " (view: %s)", view->name);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-10-06 15:24:16 +05:30
|
|
|
fprintf(fp, "]\n");
|
|
|
|
|
2023-03-16 14:31:46 +00:00
|
|
|
(void)dump_stats(gluecachestats, isc_statsformat_file,
|
|
|
|
fp, NULL, gluecachestats_desc,
|
|
|
|
dns_gluecachestatscounter_max,
|
|
|
|
gluecachestats_index,
|
|
|
|
gluecachestats_values, 0);
|
2017-10-06 15:24:16 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now);
|
|
|
|
|
|
|
|
return ISC_R_SUCCESS; /* this function currently always succeeds */
|
|
|
|
}
|