* 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>
#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,
}
}
+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;
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;
/*
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
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)) {
*/
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;
}
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
type = qtype;
else {
CTRACE("find_query: REFUSED: qcount != 1");
+ query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_REFUSED);
goto cleanup;
}
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;
}
*/
dbuf = query_getnamebuf(client);
if (dbuf == NULL) {
+ query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
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;
}
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;
}
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.
*/
*/
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);
* 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;
}
/*
* Recurse!
*/
+ query_count(zone, is_zone,
+ dns_zonecount_recurse);
if (type == dns_rdatatype_key)
result = query_recurse(client, qtype,
NULL, NULL);
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;
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
*/
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;
}
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.
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;
}
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.
/*
* Something has gone wrong.
*/
+ query_count(zone, is_zone, dns_zonecount_failure);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
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;
}
/*
* 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;
}
ns_client_attach(client, &qclient);
query_find(qclient, NULL);
}
+
+
* 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>
*/
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)
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 *);
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);
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. */
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);
+}
+