Add counters of incoming queries, server-wide and by zone. There is

currently no way to get these counts back *out* of the server, pending
a command channel.  A temporary channel should be built for these data
soon.
This commit is contained in:
Michael Sawyer 2000-10-17 20:57:26 +00:00
parent 6e90488a8d
commit 55aed608cc
3 changed files with 181 additions and 6 deletions

View file

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: query.c,v 1.137 2000/10/12 21:51:45 mws Exp $ */
/* $Id: query.c,v 1.138 2000/10/17 20:57:22 mws Exp $ */
#include <config.h>
@ -76,6 +76,11 @@
#define DNS_GETDB_NOEXACT 0x01U
#define DNS_GETDB_NOLOG 0x02U
/*
* Server-wide counter of queries
*/
isc_uint64_t globalcount[DNS_ZONE_COUNTSIZE];
static isc_result_t
query_simplefind(void *arg, dns_name_t *name, dns_rdatatype_t type,
@ -102,6 +107,35 @@ query_maybeputqname(ns_client_t *client) {
}
}
static isc_uint64_t
query_getglobals(unsigned int counter) {
REQUIRE(counter < DNS_ZONE_COUNTSIZE);
return(globalcount[counter]);
}
static void
query_count(dns_zone_t *zone, isc_boolean_t is_zone,
dns_zonecount_t counter)
{
REQUIRE(counter < DNS_ZONE_COUNTSIZE);
globalcount[counter]++;
if (!is_zone || zone == NULL) {
isc_log_write(dns_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_QUERY,
1, "global counter %s set to %ld",
dns_zonecount_names[counter],
(long)globalcount[counter]);
return;
}
dns_zone_count(zone, counter);
isc_log_write(dns_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_QUERY,
1, "zone counter %s set to %ld, global %ld",
dns_zonecount_names[counter],
(long)dns_zone_getcounts(zone, counter),
(long)globalcount[counter]);
}
static inline void
query_reset(ns_client_t *client, isc_boolean_t everything) {
isc_buffer_t *dbuf, *dbuf_next;
@ -477,7 +511,7 @@ query_getzonedb(ns_client_t *client, dns_name_t *name, unsigned int options,
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
result = dns_zone_getdb(zone, &db);
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS)
goto fail;
/*
@ -771,6 +805,7 @@ query_simplefind(void *arg, dns_name_t *name, dns_rdatatype_t type,
if (dns_rdataset_isassociated(sigrdataset))
dns_rdataset_disassociate(sigrdataset);
if (is_zone) {
query_count(zone, is_zone, dns_zonecount_delegate);
if (USECACHE(client)) {
/*
* Either the answer is in the cache, or we
@ -829,6 +864,13 @@ query_simplefind(void *arg, dns_name_t *name, dns_rdatatype_t type,
dns_rdataset_disassociate(sigrdataset);
result = ISC_R_NOTFOUND;
}
/*
* If we get here, the result is ISC_R_SUCCESS, and we found the
* answer we were looking for in the zone. Update the zone's
* query counter.
*/
if (result == ISC_R_SUCCESS)
query_count(zone, is_zone, dns_zonecount_success);
cleanup:
if (dns_rdataset_isassociated(&zrdataset)) {
@ -2158,17 +2200,20 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
*/
dbuf = query_getnamebuf(client);
if (dbuf == NULL) {
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
fname = query_newname(client, dbuf, &b);
if (fname == NULL) {
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
tname = dns_fixedname_name(&event->foundname);
result = dns_name_concatenate(tname, NULL, fname, NULL);
if (result != ISC_R_SUCCESS) {
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
@ -2191,6 +2236,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
result = query_getdb(client, client->query.qname, 0, &zone, &db,
&version, &is_zone);
if (result != ISC_R_SUCCESS) {
query_count(NULL, ISC_FALSE, dns_zonecount_failure);
if (result == DNS_R_REFUSED)
QUERY_ERROR(DNS_R_REFUSED);
else
@ -2232,6 +2278,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
type = qtype;
else {
CTRACE("find_query: REFUSED: qcount != 1");
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_REFUSED);
goto cleanup;
}
@ -2242,6 +2289,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
result = query_checktype(qtype);
if (result != ISC_R_SUCCESS) {
CTRACE("find_query: non supported query type");
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(result);
goto cleanup;
}
@ -2259,6 +2307,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
*/
dbuf = query_getnamebuf(client);
if (dbuf == NULL) {
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
@ -2266,6 +2315,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
rdataset = query_newrdataset(client);
sigrdataset = query_newrdataset(client);
if (fname == NULL || rdataset == NULL || sigrdataset == NULL) {
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
@ -2321,6 +2371,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
result = dns_name_concatenate(client->query.qname,
NULL, fname, NULL);
if (result != ISC_R_SUCCESS) {
query_count(zone, is_zone,
dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
@ -2338,6 +2390,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
CTRACE("query_find: resume");
switch (result) {
case ISC_R_SUCCESS:
query_count(zone, is_zone, dns_zonecount_success);
/*
* This case is handled in the main line below.
*/
@ -2369,6 +2422,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
*/
INSIST(!is_zone);
INSIST(client->view->hints != NULL);
query_count(zone, is_zone, dns_zonecount_delegate);
if (db != NULL)
dns_db_detach(&db);
dns_db_attach(client->view->hints, &db);
@ -2380,6 +2434,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
* We can't even find the hints for the root
* nameservers!
*/
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
@ -2479,6 +2534,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
/*
* Recurse!
*/
query_count(zone, is_zone,
dns_zonecount_recurse);
if (type == dns_rdatatype_key)
result = query_recurse(client, qtype,
NULL, NULL);
@ -2488,12 +2545,17 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
if (result == ISC_R_SUCCESS)
client->query.attributes |=
NS_QUERYATTR_RECURSING;
else
else {
query_count(zone, is_zone,
dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
}
} else {
/*
* This is the best answer.
*/
query_count(zone, is_zone,
dns_zonecount_delegate);
client->query.gluedb = zdb;
client->query.attributes |=
NS_QUERYATTR_CACHEGLUEOK;
@ -2508,6 +2570,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
goto cleanup;
case DNS_R_NXRRSET:
INSIST(is_zone);
query_count(zone, is_zone, dns_zonecount_nxrrset);
if (dns_rdataset_isassociated(rdataset)) {
/*
* If we've got a NXT record, we need to save the
@ -2534,6 +2597,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
*/
result = query_addsoa(client, db, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(result);
goto cleanup;
}
@ -2550,6 +2614,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
goto cleanup;
case DNS_R_NXDOMAIN:
INSIST(is_zone);
query_count(zone, is_zone, dns_zonecount_nxdomain);
if (client->query.restarts > 0) {
/*
* We hit a dead end following a CNAME or DNAME.
@ -2588,6 +2653,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
else
result = query_addsoa(client, db, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(result);
goto cleanup;
}
@ -2607,8 +2673,13 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
client->message->rcode = dns_rcode_nxdomain;
goto cleanup;
case DNS_R_NCACHENXDOMAIN:
INSIST(!is_zone);
query_count(NULL, is_zone, dns_zonecount_nxdomain);
goto ncachenxrrset;
case DNS_R_NCACHENXRRSET:
INSIST(!is_zone);
query_count(NULL, is_zone, dns_zonecount_nxrrset);
ncachenxrrset:
authoritative = ISC_FALSE;
/*
* Set message rcode, if required.
@ -2767,6 +2838,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
/*
* Something has gone wrong.
*/
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
@ -2780,6 +2852,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
rdsiter = NULL;
result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
if (result != ISC_R_SUCCESS) {
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
@ -2853,11 +2926,14 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
/*
* Something went wrong.
*/
query_count(zone, is_zone,
dns_zonecount_failure);
result = DNS_R_SERVFAIL;
}
}
dns_rdatasetiter_destroy(&rdsiter);
if (result != ISC_R_NOMORE) {
query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
@ -3139,3 +3215,5 @@ ns_query_start(ns_client_t *client) {
ns_client_attach(client, &qclient);
query_find(qclient, NULL);
}

View file

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zone.h,v 1.80 2000/10/13 13:45:45 marka Exp $ */
/* $Id: zone.h,v 1.81 2000/10/17 20:57:26 mws Exp $ */
#ifndef DNS_ZONE_H
#define DNS_ZONE_H 1
@ -38,6 +38,19 @@ typedef enum {
dns_zone_stub
} dns_zonetype_t;
typedef enum {
dns_zonecount_success = 0, /* Successful lookups */
dns_zonecount_delegate = 1, /* Delegation result */
dns_zonecount_nxrrset = 2, /* NXRRSET result */
dns_zonecount_nxdomain = 3, /* NXDOMAIN result */
dns_zonecount_recurse = 4, /* Recursion was used */
dns_zonecount_failure = 5 /* Some other failure */
} dns_zonecount_t;
extern const char *dns_zonecount_names[];
#define DNS_ZONE_COUNTSIZE 6
#define DNS_ZONEOPT_SERVERS 0x00000001U /* perform server checks */
#define DNS_ZONEOPT_PARENTS 0x00000002U /* perform parent checks */
#define DNS_ZONEOPT_CHILDREN 0x00000004U /* perform child checks */
@ -1174,6 +1187,38 @@ dns_zone_isforced(dns_zone_t *zone);
* 'zone' to be a valid zone.
*/
void
dns_zone_count(dns_zone_t *zone, dns_zonecount_t counter);
/*
* Increment a counter on a zone.
*
* Requires:
* zone be a valid zone.
* counter be a valid counter ID
*/
isc_uint64_t
dns_zone_getcounts(dns_zone_t *zone, dns_zonecount_t counter);
/*
* Return the value of a counter on a zone.
*
* Requires:
* zone be a valid zone.
* counter be a valid counter ID
*/
void
dns_zone_resetcounts(dns_zone_t *zone);
/*
* Reset the counters on a zone.
*
* Requires:
* zone be a valid zone.
*/
extern int dns_zone_countsize;
ISC_LANG_ENDDECLS
#endif /* DNS_ZONE_H */

View file

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zone.c,v 1.236 2000/10/17 07:22:34 marka Exp $ */
/* $Id: zone.c,v 1.237 2000/10/17 20:57:24 mws Exp $ */
#include <config.h>
@ -187,6 +187,12 @@ struct dns_zone {
*/
ISC_LINK(dns_zone_t) statelink;
dns_zonelist_t *statelist;
/*
* Variables stored in the zone object which are used to hold
* statistical information regarding the zone.
*/
isc_uint64_t counters[DNS_ZONE_COUNTSIZE];
isc_uint64_t totals[DNS_ZONE_COUNTSIZE];
};
#define DNS_ZONE_FLAG(z,f) (((z)->flags & (f)) != 0)
@ -319,6 +325,17 @@ struct dns_io {
isc_event_t *event;
};
/*
* Names of the zone counters
*/
const char *dns_zonecount_names[] = {
"SUCCESS",
"DELEGATION",
"NXRRSET",
"NXDOMAIN",
"RECURSION",
"SERVFAIL" };
static isc_result_t zone_settimer(dns_zone_t *, isc_stdtime_t);
static void cancel_refresh(dns_zone_t *);
@ -406,6 +423,7 @@ isc_result_t
dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
isc_result_t result;
dns_zone_t *zone;
int i;
REQUIRE(zonep != NULL && *zonep == NULL);
REQUIRE(mctx != NULL);
@ -492,8 +510,11 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->view = NULL;
ISC_LINK_INIT(zone, statelink);
zone->statelist = NULL;
for (i = 0; i < DNS_ZONE_COUNTSIZE; i++) {
zone->counters[i]=0;
zone->totals[i]=0;
}
zone->magic = ZONE_MAGIC;
/* Must be after magic is set. */
@ -5470,3 +5491,34 @@ dns_zone_isforced(dns_zone_t *zone) {
return (DNS_ZONE_FLAG(zone,DNS_ZONEFLG_FORCELOAD));
}
void
dns_zone_count(dns_zone_t *zone, dns_zonecount_t counter) {
REQUIRE(counter < DNS_ZONE_COUNTSIZE);
RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
zone->totals[counter]++;
zone->counters[counter]++;
RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
}
isc_uint64_t
dns_zone_getcounts(dns_zone_t *zone, dns_zonecount_t counter) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(counter < DNS_ZONE_COUNTSIZE);
return(zone->counters[counter]);
}
void
dns_zone_resetcounts(dns_zone_t *zone) {
int i;
REQUIRE(DNS_ZONE_VALID(zone));
RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
for (i = 0; i < DNS_ZONE_COUNTSIZE; i++)
zone->counters[i]=0;
RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
}