From: Marek Vavruša Date: Thu, 4 Jun 2015 00:33:11 +0000 (+0200) Subject: lib/nsrep: lower bound on rtt, optional throttling X-Git-Tag: v1.0.0-beta1~124^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8068d1178bf0dd51ecbf7c150d0bbc4d00d7fe34;p=thirdparty%2Fknot-resolver.git lib/nsrep: lower bound on rtt, optional throttling when a NS is in the TIMEOUT, it can’t be autoselected by default but only probed after a successful dice roll - however in some scenarios we’d like to probe timeouting servers more thoroughly --- diff --git a/lib/nsrep.c b/lib/nsrep.c index 9e7e99090..967c5c89b 100644 --- a/lib/nsrep.c +++ b/lib/nsrep.c @@ -21,6 +21,7 @@ #include #include "lib/nsrep.h" +#include "lib/rplan.h" #include "lib/defines.h" #include "lib/generic/pack.h" @@ -97,7 +98,7 @@ static int eval_nsrep(const char *k, void *v, void *baton) * The fastest NS is preferred by workers until it is depleted (timeouts or degrades), * at the same time long distance scouts probe other sources (low probability). * Servers on TIMEOUT (depleted) can be probed by the dice roll only */ - if (score < ns->score && score < KR_NS_TIMEOUT) { + if (score < ns->score && (ns->flags & QUERY_NO_THROTTLE || score < KR_NS_TIMEOUT)) { update_nsrep(ns, (const knot_dname_t *)k, addr, score); } else { /* With 5% chance, probe server with a probability given by its RTT / MAX_RTT */ @@ -135,6 +136,9 @@ int kr_nsrep_update(struct kr_nsrep *ns, unsigned score, kr_nsrep_lru_t *repcach if (score > KR_NS_MAX_SCORE) { score = KR_NS_MAX_SCORE; } + if (score <= KR_NS_UNKNOWN) { + score = KR_NS_UNKNOWN + 1; + } /* Set initial value or smooth over last two measurements */ if (*cur != 0) { *cur = (*cur + score) / 2; diff --git a/lib/nsrep.h b/lib/nsrep.h index 4d2ad8a4b..7df5493d0 100644 --- a/lib/nsrep.h +++ b/lib/nsrep.h @@ -46,6 +46,7 @@ typedef lru_hash(unsigned) kr_nsrep_lru_t; struct kr_nsrep { unsigned score; /**< Server score */ + unsigned flags; /**< Server flags */ const knot_dname_t *name; /**< Server name */ kr_nsrep_lru_t *repcache; /**< Reputation cache pointer */ union { diff --git a/lib/resolve.c b/lib/resolve.c index 9adb019ff..e447b9a5d 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -431,6 +431,11 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t ns_election: /* Elect best nameserver candidate */ assert(++ns_election_iter < KR_ITER_LIMIT); + /* Set slow NS throttling mode */ + qry->ns.flags = 0; + if (qry->flags & QUERY_NO_THROTTLE) { + qry->ns.flags = QUERY_NO_THROTTLE; + } kr_nsrep_elect(&qry->ns, &qry->zone_cut.nsset, request->ctx->nsrep); if (qry->ns.score > KR_NS_MAX_SCORE) { DEBUG_MSG("=> no valid NS left\n"); diff --git a/lib/rplan.h b/lib/rplan.h index e5afd9bba..f47bd28ce 100644 --- a/lib/rplan.h +++ b/lib/rplan.h @@ -29,13 +29,14 @@ /** Query flags */ enum kr_query_flag { QUERY_NO_MINIMIZE = 1 << 0, /**< Don't minimize QNAME. */ - QUERY_TCP = 1 << 1, /**< Use TCP for this query. */ - QUERY_RESOLVED = 1 << 2, /**< Query is resolved. */ - QUERY_AWAIT_IPV4 = 1 << 3, /**< Query is waiting for A address. */ - QUERY_AWAIT_IPV6 = 1 << 4, /**< Query is waiting for AAAA address. */ - QUERY_AWAIT_CUT = 1 << 5, /**< Query is waiting for zone cut lookup */ - QUERY_SAFEMODE = 1 << 6, /**< Don't use fancy stuff (EDNS...) */ - QUERY_CACHED = 1 << 7 /**< Query response is cached. */ + QUERY_NO_THROTTLE = 1 << 1, /**< No query/slow NS throttling. */ + QUERY_TCP = 1 << 2, /**< Use TCP for this query. */ + QUERY_RESOLVED = 1 << 3, /**< Query is resolved. */ + QUERY_AWAIT_IPV4 = 1 << 4, /**< Query is waiting for A address. */ + QUERY_AWAIT_IPV6 = 1 << 5, /**< Query is waiting for AAAA address. */ + QUERY_AWAIT_CUT = 1 << 6, /**< Query is waiting for zone cut lookup */ + QUERY_SAFEMODE = 1 << 7, /**< Don't use fancy stuff (EDNS...) */ + QUERY_CACHED = 1 << 8 /**< Query response is cached. */ }; /**