2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 10:10:06 +00:00

Add DNSSEC sign operations statistics channel

Add a new statistics structure to record how many sign operations
a key has made within a zone.
This commit is contained in:
Matthijs Mekking 2019-06-19 16:02:50 +02:00 committed by Matthijs Mekking
parent e317a675a1
commit d8cf7aedfa
7 changed files with 247 additions and 12 deletions

View File

@ -1444,6 +1444,60 @@ rcodestat_dump(dns_rcode_t code, uint64_t val, void *arg) {
#endif
}
static void
dnssecsignstat_dump(dns_keytag_t tag, uint64_t val, void *arg) {
FILE *fp;
char tagbuf[64];
stats_dumparg_t *dumparg = arg;
#ifdef HAVE_LIBXML2
xmlTextWriterPtr writer;
int xmlrc;
#endif
#ifdef HAVE_JSON
json_object *zoneobj, *obj;
#endif
snprintf(tagbuf, sizeof(tagbuf), "%u", tag);
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
break;
case isc_statsformat_json:
#ifdef HAVE_JSON
zoneobj = (json_object *) dumparg->arg;
obj = json_object_new_int64(val);
if (obj == NULL) {
return;
}
json_object_object_add(zoneobj, tagbuf, obj);
#endif
break;
}
return;
#ifdef HAVE_LIBXML2
error:
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"failed at dnssecsignstat_dump()");
dumparg->result = ISC_R_FAILURE;
return;
#endif
}
#ifdef HAVE_LIBXML2
/*
* Which statistics to include when rendering to XML
@ -1506,6 +1560,7 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
isc_stats_t *zonestats;
isc_stats_t *gluecachestats;
dns_stats_t *rcvquerystats;
dns_stats_t *dnssecsignstats;
uint64_t nsstat_values[ns_statscounter_max];
uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
@ -1567,6 +1622,26 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
/* counters type="qtype"*/
TRY0(xmlTextWriterEndElement(writer));
}
dnssecsignstats = dns_zone_getdnssecsignstats(zone);
if (dnssecsignstats != NULL) {
TRY0(xmlTextWriterStartElement(writer,
ISC_XMLCHAR "counters"));
TRY0(xmlTextWriterWriteAttribute(writer,
ISC_XMLCHAR "type",
ISC_XMLCHAR "dnssec"));
dumparg.result = ISC_R_SUCCESS;
dns_dnssecsignstats_dump(dnssecsignstats,
dnssecsignstat_dump,
&dumparg, 0);
if(dumparg.result != ISC_R_SUCCESS) {
goto error;
}
/* counters type="dnssec"*/
TRY0(xmlTextWriterEndElement(writer));
}
}
TRY0(xmlTextWriterEndElement(writer)); /* zone */
@ -2287,6 +2362,7 @@ zone_jsonrender(dns_zone_t *zone, void *arg) {
isc_stats_t *zonestats;
isc_stats_t *gluecachestats;
dns_stats_t *rcvquerystats;
dns_stats_t *dnssecsignstats;
uint64_t nsstat_values[ns_statscounter_max];
uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
@ -2364,6 +2440,30 @@ zone_jsonrender(dns_zone_t *zone, void *arg) {
else
json_object_put(counters);
}
dnssecsignstats = dns_zone_getdnssecsignstats(zone);
if (dnssecsignstats != 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_dnssecsignstats_dump(dnssecsignstats,
dnssecsignstat_dump,
&dumparg, 0);
if (dumparg.result != ISC_R_SUCCESS) {
json_object_put(counters);
goto error;
}
if (json_object_get_object(counters)->count != 0)
json_object_object_add(zoneobj,
"dnssec", counters);
else
json_object_put(counters);
}
}
json_object_array_add(zonearray, zoneobj);

View File

@ -904,6 +904,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
const dns_master_style_t *masterstyle = &dns_master_style_default;
isc_stats_t *zoneqrystats;
dns_stats_t *rcvquerystats;
dns_stats_t *dnssecsignstats;
dns_zonestat_level_t statlevel = dns_zonestat_none;
int seconds;
dns_zone_t *mayberaw = (raw != NULL) ? raw : zone;
@ -1188,14 +1189,16 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
zoneqrystats = NULL;
rcvquerystats = NULL;
dnssecsignstats = NULL;
if (statlevel == dns_zonestat_full) {
RETERR(isc_stats_create(mctx, &zoneqrystats,
ns_statscounter_max));
RETERR(dns_rdatatypestats_create(mctx,
&rcvquerystats));
RETERR(dns_rdatatypestats_create(mctx, &rcvquerystats));
RETERR(dns_dnssecsignstats_create(mctx, &dnssecsignstats));
}
dns_zone_setrequeststats(zone, zoneqrystats);
dns_zone_setrcvquerystats(zone, rcvquerystats);
dns_zone_setdnssecsignstats(zone, dnssecsignstats);
if (zoneqrystats != NULL)
isc_stats_detach(&zoneqrystats);
@ -1203,6 +1206,10 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
if(rcvquerystats != NULL)
dns_stats_detach(&rcvquerystats);
if(dnssecsignstats != NULL) {
dns_stats_detach(&dnssecsignstats);
}
/*
* Configure master functionality. This applies
* to primary masters (type "master") and slaves

View File

@ -499,8 +499,8 @@ typedef void (*dns_generalstats_dumper_t)(isc_statscounter_t, uint64_t,
void *);
typedef void (*dns_rdatatypestats_dumper_t)(dns_rdatastatstype_t, uint64_t,
void *);
typedef void (*dns_dnssecsignstats_dumper_t)(dns_keytag_t, uint64_t, void *);
typedef void (*dns_opcodestats_dumper_t)(dns_opcode_t, uint64_t, void *);
typedef void (*dns_rcodestats_dumper_t)(dns_rcode_t, uint64_t, void *);
ISC_LANG_BEGINDECLS
@ -588,6 +588,22 @@ dns_rcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp);
*\li anything else -- failure
*/
isc_result_t
dns_dnssecsignstats_create(isc_mem_t *mctx, dns_stats_t **statsp);
/*%<
* Create a statistics counter structure per assigned DNSKEY id.
*
* Requires:
*\li 'mctx' must be a valid memory context.
*
*\li 'statsp' != NULL && '*statsp' == NULL.
*
* Returns:
*\li ISC_R_SUCCESS -- all ok
*
*\li anything else -- failure
*/
void
dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp);
/*%<
@ -669,6 +685,15 @@ dns_rcodestats_increment(dns_stats_t *stats, dns_opcode_t code);
*\li 'stats' is a valid dns_stats_t created by dns_rcodestats_create().
*/
void
dns_dnssecsignstats_increment(dns_stats_t *stats, dns_keytag_t id);
/*%<
* Increment the statistics counter for the DNSKEY 'id'.
*
* Requires:
*\li 'stats' is a valid dns_stats_t created by dns_dnssecsignstats_create().
*/
void
dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn,
void *arg, unsigned int options);
@ -713,6 +738,21 @@ dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
*\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
*/
void
dns_dnssecsignstats_dump(dns_stats_t *stats,
dns_dnssecsignstats_dumper_t dump_fn,
void *arg, unsigned int options);
/*%<
* Dump the current statistics counters in a specified way. For each counter
* in stats, dump_fn is called with the corresponding type in the form of
* dns_rdatastatstype_t, the current counter value and the given argument
* arg. By default counters that have a value of 0 is skipped; if options has
* the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped.
*
* Requires:
*\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
*/
void
dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn,
void *arg, unsigned int options);

View File

@ -1925,6 +1925,9 @@ dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats);
void
dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats);
void
dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats);
/*%<
* Set additional statistics sets to zone. These are attached to the zone
* but are not counted in the zone module; only the caller updates the
@ -1941,6 +1944,9 @@ dns_zone_getrequeststats(dns_zone_t *zone);
dns_stats_t *
dns_zone_getrcvquerystats(dns_zone_t *zone);
dns_stats_t *
dns_zone_getdnssecsignstats(dns_zone_t *zone);
/*%<
* Get the additional statistics for zone, if one is installed.
*
@ -1952,6 +1958,17 @@ dns_zone_getrcvquerystats(dns_zone_t *zone);
* otherwise NULL.
*/
/*%<
* Set additional statistics sets to zone. These are attached to the zone
* but are not counted in the zone module; only the caller updates the
* counters.
*
* Requires:
* \li 'zone' to be a valid zone.
*
*\li stats is a valid statistics.
*/
void
dns_zone_dialup(dns_zone_t *zone);
/*%<

View File

@ -35,7 +35,8 @@ typedef enum {
dns_statstype_rdtype = 1,
dns_statstype_rdataset = 2,
dns_statstype_opcode = 3,
dns_statstype_rcode = 4
dns_statstype_rcode = 4,
dns_statstype_dnssec = 5
} dns_statstype_t;
/*%
@ -58,7 +59,8 @@ enum {
rdtypecounter_nxdomain = rdtypenxcounter_max,
/* stale counters offset */
rdtypecounter_stale = rdtypecounter_nxdomain + 1,
rdatasettypecounter_max = rdtypecounter_stale * 2
rdatasettypecounter_max = rdtypecounter_stale * 2,
dnssec_keyid_max = 65535
};
struct dns_stats {
@ -84,9 +86,13 @@ typedef struct opcodedumparg {
} opcodedumparg_t;
typedef struct rcodedumparg {
dns_rcodestats_dumper_t fn;
dns_rcodestats_dumper_t fn;
void *arg;
} rcodedumparg_t;
typedef struct dnssecsigndumparg {
dns_dnssecsignstats_dumper_t fn;
void *arg;
} dnssecsigndumparg_t;
void
dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp) {
@ -196,6 +202,14 @@ dns_rcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
dns_rcode_badcookie + 1, statsp));
}
isc_result_t
dns_dnssecsignstats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
REQUIRE(statsp != NULL && *statsp == NULL);
return (create_stats(mctx, dns_statstype_dnssec,
dnssec_keyid_max, statsp));
}
/*%
* Increment/Decrement methods
*/
@ -294,6 +308,13 @@ dns_rcodestats_increment(dns_stats_t *stats, dns_rcode_t code) {
isc_stats_increment(stats->counters, (isc_statscounter_t)code);
}
void
dns_dnssecsignstats_increment(dns_stats_t *stats, dns_keytag_t id) {
REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_dnssec);
isc_stats_increment(stats->counters, (isc_statscounter_t)id);
}
/*%
* Dump methods
*/
@ -395,6 +416,28 @@ dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
isc_stats_dump(stats->counters, rdataset_dumpcb, &arg, options);
}
static void
dnssec_dumpcb(isc_statscounter_t counter, uint64_t value, void *arg) {
dnssecsigndumparg_t *dnssecarg = arg;
dnssecarg->fn((dns_keytag_t)counter, value, dnssecarg->arg);
}
void
dns_dnssecsignstats_dump(dns_stats_t *stats,
dns_dnssecsignstats_dumper_t dump_fn,
void *arg0, unsigned int options)
{
dnssecsigndumparg_t arg;
REQUIRE(DNS_STATS_VALID(stats) &&
stats->type == dns_statstype_dnssec);
arg.fn = dump_fn;
arg.arg = arg0;
isc_stats_dump(stats->counters, dnssec_dumpcb, &arg, options);
}
static void
opcode_dumpcb(isc_statscounter_t counter, uint64_t value, void *arg) {
opcodedumparg_t *opcodearg = arg;

View File

@ -331,6 +331,10 @@ dns_dnssec_verify
dns_dnssec_verifymessage
dns_dnsseckey_create
dns_dnsseckey_destroy
dns_dnssecsignstats_create
dns_dnssecsignstats_decrement
dns_dnssecsignstats_dump
dns_dnssecsignstats_increment
dns_ds_buildrdata
dns_dsdigest_format
dns_dsdigest_fromtext
@ -1137,6 +1141,7 @@ dns_zone_getchecknames
dns_zone_getclass
dns_zone_getdb
dns_zone_getdbtype
dns_zone_getdnssecsignstats
dns_zone_getexpiretime
dns_zone_getfile
dns_zone_getforwardacl
@ -1237,6 +1242,7 @@ dns_zone_setclass
dns_zone_setdb
dns_zone_setdbtype
dns_zone_setdialup
dns_zone_setdnssecsignstats
dns_zone_setfile
dns_zone_setflag
dns_zone_setforwardacl

View File

@ -323,9 +323,10 @@ struct dns_zone {
* module.
*/
dns_zonestat_level_t statlevel;
bool requeststats_on;
bool requeststats_on;
isc_stats_t *requeststats;
dns_stats_t *rcvquerystats;
dns_stats_t *dnssecsignstats;
uint32_t notifydelay;
dns_isselffunc_t isself;
void *isselfarg;
@ -1022,6 +1023,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->statlevel = dns_zonestat_none;
zone->requeststats = NULL;
zone->rcvquerystats = NULL;
zone->dnssecsignstats = NULL;
zone->notifydelay = 5;
zone->isself = NULL;
zone->isselfarg = NULL;
@ -1195,6 +1197,9 @@ zone_free(dns_zone_t *zone) {
if (zone->rcvquerystats != NULL){
dns_stats_detach(&zone->rcvquerystats);
}
if (zone->dnssecsignstats != NULL){
dns_stats_detach(&zone->dnssecsignstats);
}
if (zone->db != NULL) {
zone_detachdb(zone);
}
@ -6623,6 +6628,7 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
/* XXX inefficient - will cause dataset merging */
CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
name, rdataset.ttl, &sig_rdata));
dns_rdata_reset(&sig_rdata);
isc_buffer_init(&buffer, data, sizeof(data));
}
@ -17521,6 +17527,24 @@ dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
UNLOCK_ZONE(zone);
}
void
dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) {
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
if (stats != NULL && zone->dnssecsignstats == NULL) {
dns_stats_attach(stats, &zone->dnssecsignstats);
}
UNLOCK_ZONE(zone);
}
dns_stats_t*
dns_zone_getdnssecsignstats(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return (zone->dnssecsignstats);
}
isc_stats_t *
dns_zone_getrequeststats(dns_zone_t *zone) {
/*
@ -18019,8 +18043,7 @@ rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
*/
static isc_result_t
add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
dns_dbversion_t *ver, dns_diff_t *diff,
bool sign_all)
dns_dbversion_t *ver, dns_diff_t *diff, bool sign_all)
{
dns_difftuple_t *tuple, *newtuple = NULL;
dns_rdata_dnskey_t dnskey;
@ -18486,9 +18509,8 @@ zone_rekey(dns_zone_t *zone) {
{
CHECK(dns_diff_apply(&diff, db, ver));
CHECK(clean_nsec3param(zone, db, ver, &diff));
CHECK(add_signing_records(db, zone->privatetype,
ver, &diff,
(newalg || fullsign)));
CHECK(add_signing_records(db, zone->privatetype, ver,
&diff, (newalg || fullsign)));
CHECK(update_soa_serial(db, ver, &diff, mctx,
zone->updatemethod));
CHECK(add_chains(zone, db, ver, &diff));