statschannel.c revision 1bb2f53b9f74a8ca9812cbe9243ef41190b4da14
/*
* Copyright (C) 2008-2013 Internet Systems Consortium, Inc. ("ISC")
*
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: statschannel.c,v 1.28.224.1 2011/12/22 07:48:27 marka Exp $ */
/*! \file */
#include <config.h>
#include <dns/resolver.h>
#include <dns/rdataclass.h>
#include <dns/rdatatype.h>
#include <named/statschannel.h>
#ifdef HAVE_JSON_H
#endif
#include "bind9.xsl.h"
struct ns_statschannel {
/* Unlocked */
/*
* Locked by channel lock: can be referenced and modified by both
* the server task and the channel task.
*/
/* Locked by server task */
};
typedef struct
void *arg; /* type dependent argument */
int ncounters; /* for general statistics */
int *counterindices; /* for general statistics */
/*%
* 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.
*/
static const char *nsstats_desc[dns_nsstatscounter_max];
static const char *resstats_desc[dns_resstatscounter_max];
static const char *adbstats_desc[dns_adbstats_max];
static const char *zonestats_desc[dns_zonestatscounter_max];
static const char *sockstats_desc[isc_sockstatscounter_max];
static const char *dnssecstats_desc[dns_dnssecstats_max];
#ifdef HAVE_LIBXML2
static const char *nsstats_xmldesc[dns_nsstatscounter_max];
static const char *resstats_xmldesc[dns_resstatscounter_max];
static const char *adbstats_xmldesc[dns_adbstats_max];
static const char *zonestats_xmldesc[dns_zonestatscounter_max];
static const char *sockstats_xmldesc[isc_sockstatscounter_max];
static const char *dnssecstats_xmldesc[dns_dnssecstats_max];
#else
#define nsstats_xmldesc NULL
#define resstats_xmldesc NULL
#define adbstats_xmldesc NULL
#define zonestats_xmldesc NULL
#define sockstats_xmldesc NULL
#define dnssecstats_xmldesc NULL
#endif /* HAVE_LIBXML2 */
/*%
* 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.
*/
static int nsstats_index[dns_nsstatscounter_max];
static int resstats_index[dns_resstatscounter_max];
static int adbstats_index[dns_adbstats_max];
static int zonestats_index[dns_zonestatscounter_max];
static int sockstats_index[isc_sockstatscounter_max];
static int dnssecstats_index[dns_dnssecstats_max];
static inline void
{
#ifdef HAVE_LIBXML2
#endif
#ifdef HAVE_LIBXML2
#else
#endif
}
static void
init_desc(void) {
int i;
/* Initialize name server statistics */
for (i = 0; i < dns_nsstatscounter_max; i++)
nsstats_desc[i] = NULL;
#ifdef HAVE_LIBXML2
for (i = 0; i < dns_nsstatscounter_max; i++)
nsstats_xmldesc[i] = NULL;
#endif
do { \
} while (0)
i = 0;
"requests with unsupported EDNS version received",
"ReqBadEDNSVer");
"ReqBadSIG");
"TruncatedResp");
"QrySuccess");
"QryAuthAns");
"queries resulted in non authoritative answer",
"QryNoauthAns");
"QryReferral");
"UpdateReqFwd");
"UpdateRespFwd");
"updates rejected due to prerequisite failure",
"UpdateBadPrereq");
"RecursClients");
"RateDropped");
"RateSlipped");
"RPZRewrites");
INSIST(i == dns_nsstatscounter_max);
/* Initialize resolver statistics */
for (i = 0; i < dns_resstatscounter_max; i++)
resstats_desc[i] = NULL;
#ifdef HAVE_LIBXML2
for (i = 0; i < dns_resstatscounter_max; i++)
resstats_xmldesc[i] = NULL;
#endif
do { \
} while (0)
i = 0;
"QueryAbort");
"QuerySockFail");
"GlueFetchv4Fail");
"GlueFetchv6Fail");
"ValNegOk");
"QryRTT" DNS_RESOLVER_QRYRTTCLASS0STR);
"QryRTT" DNS_RESOLVER_QRYRTTCLASS1STR);
"QryRTT" DNS_RESOLVER_QRYRTTCLASS2STR);
"QryRTT" DNS_RESOLVER_QRYRTTCLASS3STR);
"QryRTT" DNS_RESOLVER_QRYRTTCLASS4STR);
INSIST(i == dns_resstatscounter_max);
/* Initialize adb statistics */
for (i = 0; i < dns_adbstats_max; i++)
adbstats_desc[i] = NULL;
#ifdef HAVE_LIBXML2
for (i = 0; i < dns_adbstats_max; i++)
adbstats_xmldesc[i] = NULL;
#endif
do { \
} while (0)
i = 0;
INSIST(i == dns_adbstats_max);
/* Initialize zone statistics */
for (i = 0; i < dns_zonestatscounter_max; i++)
zonestats_desc[i] = NULL;
#ifdef HAVE_LIBXML2
for (i = 0; i < dns_zonestatscounter_max; i++)
zonestats_xmldesc[i] = NULL;
#endif
do { \
} while (0)
i = 0;
"XfrSuccess");
INSIST(i == dns_zonestatscounter_max);
/* Initialize socket statistics */
for (i = 0; i < isc_sockstatscounter_max; i++)
sockstats_desc[i] = NULL;
#ifdef HAVE_LIBXML2
for (i = 0; i < isc_sockstatscounter_max; i++)
sockstats_xmldesc[i] = NULL;
#endif
do { \
} while (0)
i = 0;
"UDP4OpenFail");
"UDP6OpenFail");
"TCP4OpenFail");
"TCP6OpenFail");
"UnixOpenFail");
"FDWatchClose");
"UDP4BindFail");
"UDP6BindFail");
"TCP4BindFail");
"TCP6BindFail");
"UnixBindFail");
"FdwatchBindFail");
"UDP4ConnFail");
"UDP6ConnFail");
"TCP4ConnFail");
"TCP6ConnFail");
"UnixConnFail");
"FDwatchConnFail");
"UDP4Conn");
"UDP6Conn");
"TCP4Conn");
"TCP6Conn");
"UnixConn");
"FDwatch domain connections established",
"FDwatchConn");
"TCP4AcceptFail");
"TCP6AcceptFail");
"Unix domain connection accept failures",
"UnixAcceptFail");
"TCP4Accept");
"TCP6Accept");
"UnixAccept");
"UnixSendErr");
"FDwatchSendErr");
"UnixRecvErr");
"FDwatchRecvErr");
"UnixActive");
INSIST(i == isc_sockstatscounter_max);
/* Initialize DNSSEC statistics */
for (i = 0; i < dns_dnssecstats_max; i++)
dnssecstats_desc[i] = NULL;
#ifdef HAVE_LIBXML2
for (i = 0; i < dns_dnssecstats_max; i++)
dnssecstats_xmldesc[i] = NULL;
#endif
do { \
desc, dnssecstats_desc, \
} while (0)
i = 0;
"\"as is\"", "DNSSECasis");
"lower cased", "DNSSECdowncase");
"DNSSECwild");
INSIST(i == dns_dnssecstats_max);
/* Sanity check */
for (i = 0; i < dns_nsstatscounter_max; i++)
for (i = 0; i < dns_resstatscounter_max; i++)
for (i = 0; i < dns_adbstats_max; i++)
for (i = 0; i < dns_zonestatscounter_max; i++)
for (i = 0; i < isc_sockstatscounter_max; i++)
for (i = 0; i < dns_dnssecstats_max; i++)
#ifdef HAVE_LIBXML2
for (i = 0; i < dns_nsstatscounter_max; i++)
for (i = 0; i < dns_resstatscounter_max; i++)
for (i = 0; i < dns_adbstats_max; i++)
for (i = 0; i < dns_zonestatscounter_max; i++)
for (i = 0; i < isc_sockstatscounter_max; i++)
for (i = 0; i < dns_dnssecstats_max; i++)
#endif
}
/*%
* Dump callback functions.
*/
static void
}
static isc_result_t
{
int i, index;
#ifdef HAVE_LIBXML2
int xmlrc;
#endif
#ifdef HAVE_JSON
#endif
#if !defined(HAVE_LIBXML2) && !defined(HAVE_JSON)
#endif
#ifdef HAVE_JSON
return (ISC_R_NOMEMORY);
}
}
#endif
for (i = 0; i < ncounters; i++) {
continue;
case isc_statsformat_file:
break;
case isc_statsformat_xml:
#ifdef HAVE_LIBXML2
/* <NameOfCategory> */
category));
/* <name> inside category */
"name"));
/* </name> */
/* <counter> */
"counter"));
/* </counter> */
/* </NameOfCategory> */
} else {
"counter"));
"name",
/* counter */
}
#endif
break;
case isc_statsformat_json:
#ifdef HAVE_JSON
return (ISC_R_NOMEMORY);
#endif
break;
}
}
return (ISC_R_SUCCESS);
#ifdef HAVE_LIBXML2
ISC_LOG_ERROR, "failed at dump_counters()");
return (ISC_R_FAILURE);
#endif
}
static void
char typebuf[64];
const char *typestr;
#ifdef HAVE_LIBXML2
int xmlrc;
#endif
#ifdef HAVE_JSON
#endif
== 0) {
sizeof(typebuf));
} else
typestr = "Others";
case isc_statsformat_file:
break;
case isc_statsformat_xml:
#ifdef HAVE_LIBXML2
val));
#endif
break;
case isc_statsformat_json:
#ifdef HAVE_JSON
return;
#endif
break;
}
return;
#ifdef HAVE_LIBXML2
ISC_LOG_ERROR, "failed at rdtypestat_dump()");
return;
#endif
}
static void
char typebuf[64];
const char *typestr;
#ifdef HAVE_LIBXML2
int xmlrc;
#endif
#ifdef HAVE_JSON
char buf[1024];
#endif
!= 0) {
typestr = "NXDOMAIN";
} else if ((DNS_RDATASTATSTYPE_ATTR(type) &
DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) != 0) {
typestr = "Others";
} else {
sizeof(typebuf));
}
!= 0)
!= 0)
case isc_statsformat_file:
break;
case isc_statsformat_xml:
#ifdef HAVE_LIBXML2
val));
#endif
break;
case isc_statsformat_json:
#ifdef HAVE_JSON
return;
#endif
break;
}
return;
#ifdef HAVE_LIBXML2
ISC_LOG_ERROR, "failed at rdatasetstats_dump()");
#endif
}
static void
isc_buffer_t b;
char codebuf[64];
#ifdef HAVE_LIBXML2
int xmlrc;
#endif
#ifdef HAVE_JSON
#endif
dns_opcode_totext(code, &b);
case isc_statsformat_file:
break;
case isc_statsformat_xml:
#ifdef HAVE_LIBXML2
ISC_XMLCHAR codebuf ));
val));
#endif
break;
case isc_statsformat_json:
#ifdef HAVE_JSON
return;
#endif
break;
}
return;
#ifdef HAVE_LIBXML2
ISC_LOG_ERROR, "failed at opcodestat_dump()");
return;
#endif
}
#ifdef HAVE_LIBXML2
/*
* Which statistics to include when rendering to XML
*/
#define STATS_XML_SERVER 0x01
#define STATS_XML_ZONES 0x02
#define STATS_XML_TASKS 0x04
#define STATS_XML_NET 0x08
#define STATS_XML_MEM 0x10
#define STATS_XML_ALL 0xff
static isc_result_t
char *zone_name_only = NULL;
int xmlrc;
if (statlevel == dns_zonestat_none)
return (ISC_R_SUCCESS);
if(zone_name_only == NULL)
ISC_XMLCHAR buf));
else
ISC_XMLCHAR "rcode"));
if (result != ISC_R_SUCCESS)
goto error;
/* counters type="rcode"*/
}
ISC_XMLCHAR "qtype"));
&dumparg, 0);
goto error;
/* counters type="qtype"*/
}
return (ISC_R_SUCCESS);
ISC_LOG_ERROR, "Failed at zone_xmlrender()");
return (ISC_R_FAILURE);
}
static isc_result_t
{
char boottime[sizeof "yyyy-mm-ddThh:mm:ssZ"];
char configtime[sizeof "yyyy-mm-ddThh:mm:ssZ"];
char nowstr[sizeof "yyyy-mm-ddThh:mm:ssZ"];
int xmlrc;
isc_time_now(&now);
goto error;
ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.xsl\""));
ISC_XMLCHAR "3.4"));
/* Set common fields for statistics dump */
/* Render server information */
if ((flags & STATS_XML_SERVER) != 0) {
ISC_XMLCHAR "opcode"));
goto error;
ISC_XMLCHAR "qtype"));
&dumparg, 0);
goto error;
ISC_XMLCHAR "nsstat"));
if (result != ISC_R_SUCCESS)
goto error;
ISC_XMLCHAR "zonestat"));
if (result != ISC_R_SUCCESS)
goto error;
/*
* Most of the common resolver statistics entries are 0, so
* we don't use the verbose dump here.
*/
ISC_XMLCHAR "resstat"));
resstats_index, resstat_values, 0);
if (result != ISC_R_SUCCESS)
goto error;
}
if ((flags & STATS_XML_NET) != 0) {
ISC_XMLCHAR "sockstat"));
if (result != ISC_R_SUCCESS)
goto error;
}
/*
* Render views. For each view we know of, call its
* rendering function.
*/
{
if ((flags & STATS_XML_ZONES) != 0) {
ISC_XMLCHAR "zones"));
if (result != ISC_R_SUCCESS)
goto error;
}
if ((flags & STATS_XML_SERVER) == 0) {
continue;
}
ISC_XMLCHAR "counters"));
ISC_XMLCHAR "resqtype"));
rdtypestat_dump, &dumparg, 0);
goto error;
}
/* <resstats> */
ISC_XMLCHAR "resstats"));
if (result != ISC_R_SUCCESS)
goto error;
}
if (cacherrstats != NULL) {
ISC_XMLCHAR "cache"));
ISC_XMLCHAR "name",
&dumparg, 0);
goto error;
}
/* <adbstats> */
ISC_XMLCHAR "adbstat"));
if (result != ISC_R_SUCCESS)
goto error;
}
/* <cachestats> */
ISC_XMLCHAR "cachestats"));
}
if ((flags & STATS_XML_NET) != 0) {
ISC_XMLCHAR "socketmgr"));
}
if ((flags & STATS_XML_TASKS) != 0) {
}
if ((flags & STATS_XML_MEM) != 0) {
}
goto error;
return (ISC_R_SUCCESS);
ISC_LOG_ERROR, "failed generating XML response");
return (ISC_R_FAILURE);
}
static void
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
int msglen;
if (result == ISC_R_SUCCESS) {
*retcode = 200;
*retmsg = "OK";
isc_buffer_add(b, msglen);
*freecb = wrap_xmlfree;
*freecb_args = NULL;
} else
"failed at rendering XML()");
return (result);
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
#endif /* HAVE_LIBXML2 */
#ifdef HAVE_JSON
/*
* Which statistics to include when rendering to JSON
*/
#define STATS_JSON_SERVER 0x01
#define STATS_JSON_ZONES 0x02
#define STATS_JSON_TASKS 0x04
#define STATS_JSON_NET 0x08
#define STATS_JSON_MEM 0x10
#define STATS_JSON_ALL 0xff
#define CHECKMEM(m) do { \
if (m == NULL) { \
result = ISC_R_NOMEMORY;\
goto error;\
} \
} while(0)
static void
}
static json_object *
return (NULL);
return (node);
}
static isc_result_t
char *zone_name_only = NULL;
char *class_only = NULL;
if (statlevel == dns_zonestat_none)
return (ISC_R_SUCCESS);
if(zone_name_only == NULL)
class_only = class;
serial = -1;
return (ISC_R_NOMEMORY);
goto error;
}
nsstat_values, 0);
if (result != ISC_R_SUCCESS) {
goto error;
}
else
}
&dumparg, 0);
goto error;
}
else
}
return (result);
}
static isc_result_t
{
char boottime[sizeof "yyyy-mm-ddThh:mm:ssZ"];
char configtime[sizeof "yyyy-mm-ddThh:mm:ssZ"];
char nowstr[sizeof "yyyy-mm-ddThh:mm:ssZ"];
return (ISC_R_NOMEMORY);
/*
* These statistics are included no matter which URL we use.
*/
isc_time_now(&now);
configtime, sizeof configtime);
if ((flags & STATS_JSON_SERVER) != 0) {
/* OPCODE counters */
goto error;
}
else
/* QTYPE counters */
rdtypestat_dump, &dumparg, 0);
goto error;
}
else
/* server stat counters */
nsstats_index, nsstat_values, 0);
if (result != ISC_R_SUCCESS) {
goto error;
}
else
/* zone stat counters */
if (result != ISC_R_SUCCESS) {
goto error;
}
counters);
else
/* resolver stat counters */
resstats_index, resstat_values, 0);
if (result != ISC_R_SUCCESS) {
goto error;
}
else
}
CHECKMEM(v);
za = json_object_new_array();
if ((flags & STATS_JSON_ZONES) != 0) {
if (result != ISC_R_SUCCESS) {
goto error;
}
}
if (json_object_array_length(za) != 0)
else
if ((flags & STATS_JSON_SERVER) != 0) {
resstat_values, 0);
if (result != ISC_R_SUCCESS) {
goto error;
}
counters);
}
&dumparg, 0);
goto error;
}
counters);
}
&dumparg, 0);
goto error;
}
"cache",
counters);
}
counters);
if (result != ISC_R_SUCCESS) {
goto error;
}
counters);
adbstat_values, 0);
if (result != ISC_R_SUCCESS) {
goto error;
}
counters);
}
}
}
}
if ((flags & STATS_JSON_NET) != 0) {
/* socket stat counters */
if (result != ISC_R_SUCCESS) {
goto error;
}
counters);
else
if (result != ISC_R_SUCCESS) {
goto error;
}
}
if ((flags & STATS_JSON_TASKS) != 0) {
if (result != ISC_R_SUCCESS) {
goto error;
}
}
if ((flags & STATS_JSON_MEM) != 0) {
if (result != ISC_R_SUCCESS) {
goto error;
}
}
}
return (result);
}
static isc_result_t
const char *querystring, const char *headers,
const char **mimetype, isc_buffer_t *b,
{
char *p;
if (result == ISC_R_SUCCESS) {
*retcode = 200;
*retmsg = "OK";
*mimetype = "application/json";
isc_buffer_reinit(b, p, msglen);
isc_buffer_add(b, msglen);
*freecb = wrap_jsonfree;
*freecb_args = bindstats;
} else
"failed at rendering JSON()");
return (result);
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
static isc_result_t
const char **mimetype, isc_buffer_t *b,
{
freecb, freecb_args));
}
#endif /* HAVE_JSON */
static isc_result_t
const char *querystring, const char *headers,
const char **mimetype, isc_buffer_t *b,
{
*freecb_args = NULL;
if (p != NULL) {
p += strlen("If-Modified-Since: ");
if (result != ISC_R_SUCCESS)
goto send;
if (result != ISC_R_SUCCESS)
goto send;
&t2);
if (result != ISC_R_SUCCESS)
goto send;
goto send;
*retcode = 304;
*retmsg = "Not modified";
return (ISC_R_SUCCESS);
}
}
send:
*retcode = 200;
*retmsg = "OK";
return (ISC_R_SUCCESS);
}
static void
char socktext[ISC_SOCKADDR_FORMATSIZE];
ISC_LOG_NOTICE, "stopping statistics channel on %s",
socktext);
}
static isc_boolean_t
char socktext[ISC_SOCKADDR_FORMATSIZE];
int match;
return (ISC_TRUE);
}
"rejected statistics connection from %s", socktext);
return (ISC_FALSE);
}
static void
destroy_listener(void *arg) {
/* We don't have to acquire the lock here since it's already unlinked */
}
static isc_result_t
const char *socktext)
{
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS) {
return (ISC_R_FAILURE);
}
&new_acl);
} else
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
#ifndef ISC_ALLOW_MAPPED
#endif
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
#ifdef HAVE_LIBXML2
#endif
#ifdef HAVE_JSON
#endif
render_xsl, server);
"statistics channel listening on %s", socktext);
if (result != ISC_R_SUCCESS) {
sizeof(*listener));
}
return (result);
}
static void
const char *socktext)
{
break;
return;
}
/*
* Now, keep the old access list unless a new one can be made.
*/
&new_acl);
} else
if (result == ISC_R_SUCCESS) {
} else {
"couldn't install new acl for "
"statistics channel %s: %s",
}
}
{
char socktext[ISC_SOCKADDR_FORMATSIZE];
/*
* Get the list of named.conf 'statistics-channels' statements.
*/
/*
* already being listened on and moving them to the new list.
*
* the underlying config code, or to the bind attempt getting an
* address-in-use error.
*/
if (statschannellist != NULL) {
#ifndef HAVE_LIBXML2
"statistics-channels specified but not effective "
"due to missing XML library");
#endif
const cfg_obj_t *statschannel;
&listenercfg);
if (listenercfg == NULL)
continue;
const cfg_obj_t *listen_params;
if (isc_sockaddr_getport(&addr) == 0)
sizeof(socktext));
ISC_LOG_DEBUG(9),
"processing statistics "
"channel %s",
socktext);
/*
* Remove the listener from the old
* list, so it won't be shut down.
*/
} else {
/*
* This is a new listener.
*/
isc_result_t r;
&addr, aclconfctx,
socktext);
if (r != ISC_R_SUCCESS) {
"couldn't allocate "
"statistics channel"
" %s: %s",
isc_result_totext(r));
}
}
link);
}
}
}
listener = listener_next) {
}
return (ISC_R_SUCCESS);
}
void
}
}
/* Set common fields */
&dumparg, 0);
continue;
else
&dumparg, 0);
}
nsstats_index, nsstat_values, 0);
resstats_index, resstat_values, 0);
continue;
else
resstat_values, 0);
}
else
/*
* Avoid dumping redundant statistics when the cache is shared.
*/
if (dns_view_iscacheshared(view))
continue;
}
if (cacherrstats == NULL)
continue;
else
if (dns_view_iscacheshared(view)) {
/*
* Avoid dumping redundant statistics when the cache is
* shared.
*/
continue;
}
&dumparg, 0);
}
continue;
else
adbstats_index, adbstat_values, 0);
}
result == ISC_R_SUCCESS;
{
char zonename[DNS_NAME_FORMATSIZE];
nsstats_index, nsstat_values, 0);
}
}
return (ISC_R_SUCCESS); /* this function currently always succeeds */
}