From 849fe8d24160244aa8c2e11f4ba948a8166df1f9 Mon Sep 17 00:00:00 2001 From: Pieter Lexis Date: Thu, 30 Jun 2016 16:55:48 +0200 Subject: [PATCH] Recursor: Add DNSSEC validation statistics Closes #3916 --- docs/markdown/recursor/stats.md | 7 +++++++ pdns/rec_channel_rec.cc | 7 +++++++ pdns/syncres.hh | 3 +++ pdns/validate-recursor.cc | 32 ++++++++++++++++++++------------ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/docs/markdown/recursor/stats.md b/docs/markdown/recursor/stats.md index cef77567bc..7030bf0432 100644 --- a/docs/markdown/recursor/stats.md +++ b/docs/markdown/recursor/stats.md @@ -26,6 +26,13 @@ The `rec_control get` command can be used to query the following statistics, eit * `client-parse-errors`: counts number of client packets that could not be parsed * `concurrent-queries`: shows the number of MThreads currently running * `dlg-only-drops`: number of records dropped because of delegation only setting +* `dnssec-queries`: number of queries received with the DO and/or AD bit set +* `dnssec-result-bogus`: number of DNSSEC validations that had the Bogus state +* `dnssec-result-indeterminate`: number of DNSSEC validations that had the Indeterminate state +* `dnssec-result-insecure`: number of DNSSEC validations that had the Insecure state +* `dnssec-result-nta`: number of DNSSEC validations that had the NTA (negative trust anchor) state +* `dnssec-result-secure`: number of DNSSEC validations that had the Secure state +* `dnssec-validations`: number of DNSSEC validations performed * `dont-outqueries`: number of outgoing queries dropped because of 'dont-query' setting (since 3.3) * `edns-ping-matches`: number of servers that sent a valid EDNS PING response * `edns-ping-mismatches`: number of servers that sent an invalid EDNS PING response diff --git a/pdns/rec_channel_rec.cc b/pdns/rec_channel_rec.cc index 3e0b7c40e2..caeb01ade2 100644 --- a/pdns/rec_channel_rec.cc +++ b/pdns/rec_channel_rec.cc @@ -846,6 +846,13 @@ RecursorControlParser::RecursorControlParser() addGetStat("memory-alloc-flux", boost::bind(&MallocTracer::getAllocFlux, g_mtracer, string())); addGetStat("memory-allocated", boost::bind(&MallocTracer::getTotAllocated, g_mtracer, string())); #endif + + addGetStat("dnssec-validations", &g_stats.dnssecValidations); + addGetStat("dnssec-result-insecure", &g_stats.dnssecResults[Insecure]); + addGetStat("dnssec-result-secure", &g_stats.dnssecResults[Secure]); + addGetStat("dnssec-result-bogus", &g_stats.dnssecResults[Bogus]); + addGetStat("dnssec-result-indeterminate", &g_stats.dnssecResults[Indeterminate]); + addGetStat("dnssec-result-nta", &g_stats.dnssecResults[NTA]); } static void doExitGeneric(bool nicely) diff --git a/pdns/syncres.hh b/pdns/syncres.hh index 564af638c3..3287bb7acf 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -23,6 +23,7 @@ #include #include "mtasker.hh" #include "iputils.hh" +#include "validate.hh" #include "filterpo.hh" @@ -606,6 +607,8 @@ struct RecursorStats time_t startupTime; std::atomic dnssecQueries; unsigned int maxMThreadStackUsage; + std::atomic dnssecValidations; // should be the sum of all dnssecResult* stats + std::map > dnssecResults; }; //! represents a running TCP/IP client session diff --git a/pdns/validate-recursor.cc b/pdns/validate-recursor.cc index eae00a61d4..94f3a8b51e 100644 --- a/pdns/validate-recursor.cc +++ b/pdns/validate-recursor.cc @@ -25,12 +25,19 @@ public: int d_queries{0}; }; +inline vState increaseDNSSECStateCounter(const vState& state) +{ + g_stats.dnssecResults[state]++; + return state; +} vState validateRecords(const vector& recs) { if(recs.empty()) return Insecure; // can't secure nothing + g_stats.dnssecValidations++; + cspmap_t cspmap=harvestCSPFromRecs(recs); LOG("Got "<& recs) for(const auto& csp : cspmap) { for(const auto& sig : csp.second.signatures) { state = getKeysFor(sro, sig->d_signer, keys); // XXX check validity here - if(state == NTA) + if(state == NTA) { + increaseDNSSECStateCounter(state); return Insecure; + } LOG("! state = "<& recs) // maybe not the right idea } } - if(state == Bogus) { - return state; - } + if(state == Bogus) + return increaseDNSSECStateCounter(state); validateWithKeySet(cspmap, validrrsets, keys); } else { @@ -69,16 +77,16 @@ vState validateRecords(const vector& recs) state = getKeysFor(sro, recs.begin()->d_name, keys); // um WHAT DOES THIS MEAN - try first qname?? LOG("! state = "<& recs) LOG(csp.first.first<<"|"<