From 7b18274d7e1ed0dda25669048a62ebd55cb9a11d Mon Sep 17 00:00:00 2001 From: Ralph Dolmans Date: Thu, 3 Aug 2017 12:52:33 +0000 Subject: [PATCH] - Added stats for queries that have been ratelimited by domain recursion. git-svn-id: file:///svn/unbound/trunk@4292 be551aaa-1e26-0410-a405-d3ace91eadb9 --- daemon/remote.c | 3 +++ daemon/stats.c | 23 +++++++++++++++++++++++ doc/Changelog | 2 ++ doc/unbound-control.8.in | 4 ++++ iterator/iterator.c | 13 +++++++++++++ iterator/iterator.h | 5 +++++ libunbound/unbound.h | 2 ++ smallapp/unbound-control.c | 2 ++ 8 files changed, 54 insertions(+) diff --git a/daemon/remote.c b/daemon/remote.c index 6ee5d4c0d..60852b03c 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1017,6 +1017,9 @@ print_ext(SSL* ssl, struct ub_stats_info* s) if(!ssl_printf(ssl, "num.answer.rcode.nodata"SQ"%lu\n", (unsigned long)s->svr.ans_rcode_nodata)) return 0; } + /* iteration */ + if(!ssl_printf(ssl, "num.query.ratelimited"SQ"%lu\n", + (unsigned long)s->svr.queries_ratelimited)) return 0; /* validation */ if(!ssl_printf(ssl, "num.answer.secure"SQ"%lu\n", (unsigned long)s->svr.ans_secure)) return 0; diff --git a/daemon/stats.c b/daemon/stats.c index 50233f4ac..666725263 100644 --- a/daemon/stats.c +++ b/daemon/stats.c @@ -56,6 +56,7 @@ #include "util/timehist.h" #include "util/net_help.h" #include "validator/validator.h" +#include "iterator/iterator.h" #include "sldns/sbuffer.h" #include "services/cache/rrset.h" #include "services/cache/infra.h" @@ -139,6 +140,24 @@ get_rrset_bogus(struct worker* worker, int reset) return r; } +/** get number of ratelimited queries from iterator */ +static size_t +get_queries_ratelimit(struct worker* worker, int reset) +{ + int m = modstack_find(&worker->env.mesh->mods, "iterator"); + struct iter_env* ie; + size_t r; + if(m == -1) + return 0; + ie = (struct iter_env*)worker->env.modinfo[m]; + lock_basic_lock(&ie->queries_ratelimit_lock); + r = ie->num_queries_ratelimited; + if(reset && !worker->env.cfg->stat_cumulative) + ie->num_queries_ratelimited = 0; + lock_basic_unlock(&ie->queries_ratelimit_lock); + return r; +} + void server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset) { @@ -171,6 +190,9 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset) /* get and reset validator rrset bogus number */ s->svr.rrset_bogus = (long long)get_rrset_bogus(worker, reset); + /* get and reset iterator query ratelimit number */ + s->svr.queries_ratelimited = (long long)get_queries_ratelimit(worker, reset); + /* get cache sizes */ s->svr.msg_cache_count = (long long)count_slabhash_entries(worker->env.msg_cache); s->svr.rrset_cache_count = (long long)count_slabhash_entries(&worker->env.rrset_cache->table); @@ -267,6 +289,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a) total->svr.ans_secure += a->svr.ans_secure; total->svr.ans_bogus += a->svr.ans_bogus; total->svr.rrset_bogus += a->svr.rrset_bogus; + total->svr.queries_ratelimited += a->svr.queries_ratelimited; total->svr.unwanted_replies += a->svr.unwanted_replies; total->svr.unwanted_queries += a->svr.unwanted_queries; total->svr.tcp_accept_usage += a->svr.tcp_accept_usage; diff --git a/doc/Changelog b/doc/Changelog index cc9e36057..9ad5731a6 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,8 @@ 3 August 2017: Ralph - Remove unused iter_env member (ip6arpa_dname) - Do not reset rrset.bogus stats when called using stats_noreset. + - Added stats for queries that have been ratelimited by domain + recursion. 3 August 2017: Wouter - Fix #1394: mix of serve-expired and response-ip could cause a crash. diff --git a/doc/unbound-control.8.in b/doc/unbound-control.8.in index d275d887b..229106c3e 100644 --- a/doc/unbound-control.8.in +++ b/doc/unbound-control.8.in @@ -493,6 +493,10 @@ number of queries that had an EDNS OPT record present. number of queries that had an EDNS OPT record with the DO (DNSSEC OK) bit set. These queries are also included in the num.query.edns.present number. .TP +.I num.query.ratelimited +The number of queries that are turned away from being send to nameserver due to +ratelimiting. +.TP .I num.answer.rcode.NXDOMAIN The number of answers to queries, from cache or from recursion, that had the return code NXDOMAIN. Also printed for the other return codes. diff --git a/iterator/iterator.c b/iterator/iterator.c index 205ab0d15..2f62915a5 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -78,6 +78,12 @@ iter_init(struct module_env* env, int id) return 0; } env->modinfo[id] = (void*)iter_env; + + lock_basic_init(&iter_env->queries_ratelimit_lock); + lock_protect(&iter_env->queries_ratelimit_lock, + &iter_env->num_queries_ratelimited, + sizeof(iter_env->num_queries_ratelimited)); + if(!iter_apply_cfg(iter_env, env->cfg)) { log_err("iterator: could not apply configuration settings."); return 0; @@ -103,6 +109,7 @@ iter_deinit(struct module_env* env, int id) if(!env || !env->modinfo[id]) return; iter_env = (struct iter_env*)env->modinfo[id]; + lock_basic_destroy(&iter_env->queries_ratelimit_lock); free(iter_env->target_fetch_policy); priv_delete(iter_env->priv); donotq_delete(iter_env->donotq); @@ -1276,6 +1283,9 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, "delegation point", iq->dp->name, LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN); } else { + lock_basic_lock(&ie->queries_ratelimit_lock); + ie->num_queries_ratelimited++; + lock_basic_unlock(&ie->queries_ratelimit_lock); log_nametypeclass(VERB_ALGO, "ratelimit exceeded with " "delegation point", iq->dp->name, LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN); @@ -2064,6 +2074,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok) { if(!infra_ratelimit_inc(qstate->env->infra_cache, iq->dp->name, iq->dp->namelen, *qstate->env->now)) { + lock_basic_lock(&ie->queries_ratelimit_lock); + ie->num_queries_ratelimited++; + lock_basic_unlock(&ie->queries_ratelimit_lock); verbose(VERB_ALGO, "query exceeded ratelimits"); return error_response(qstate, id, LDNS_RCODE_SERVFAIL); } diff --git a/iterator/iterator.h b/iterator/iterator.h index e4ddbecf1..75aafee47 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -129,6 +129,11 @@ struct iter_env { * array of max_dependency_depth+1 size. */ int* target_fetch_policy; + + /** lock on ratelimit counter */ + lock_basic_type queries_ratelimit_lock; + /** number of queries that have been ratelimited */ + size_t num_queries_ratelimited; }; /** diff --git a/libunbound/unbound.h b/libunbound/unbound.h index d7667d104..95d6ee101 100644 --- a/libunbound/unbound.h +++ b/libunbound/unbound.h @@ -704,6 +704,8 @@ struct ub_server_stats { long long ans_bogus; /** rrsets marked bogus by validator */ long long rrset_bogus; + /** number of queries that have been ratelimited by domain recursion. */ + long long queries_ratelimited; /** unwanted traffic received on server-facing ports */ long long unwanted_replies; /** unwanted traffic received on client-facing ports */ diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index ee21e532a..73fe23c10 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -337,6 +337,8 @@ static void print_extended(struct ub_stats_info* s) if(!inhibit_zero || s->svr.ans_rcode_nodata) { PR_UL("num.answer.rcode.nodata", s->svr.ans_rcode_nodata); } + /* iteration */ + PR_UL("num.query.ratelimited", s->svr.queries_ratelimited); /* validation */ PR_UL("num.answer.secure", s->svr.ans_secure); PR_UL("num.answer.bogus", s->svr.ans_bogus); -- 2.47.3