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
#include <libknot/internal/sockaddr.h>
#include "lib/nsrep.h"
+#include "lib/rplan.h"
#include "lib/defines.h"
#include "lib/generic/pack.h"
* 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 */
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;
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 {
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");
/** 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. */
};
/**