From: Štěpán Balážik Date: Tue, 8 Sep 2020 09:51:25 +0000 (+0200) Subject: selection: limit backing of the timeout X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8f51f4979b23905e1a587ae8d49de74cfa105d23;p=thirdparty%2Fknot-resolver.git selection: limit backing of the timeout --- diff --git a/lib/selection.c b/lib/selection.c index fe4322339..8fe967e4b 100644 --- a/lib/selection.c +++ b/lib/selection.c @@ -38,6 +38,7 @@ void *prefix_key(const uint8_t *ip, size_t len) { #define DEFAULT_TIMEOUT 400 #define MAX_TIMEOUT 10000 +#define MAX_BACKOFF 5 const struct rtt_state default_rtt_state = {0, DEFAULT_TIMEOUT/4, 0}; @@ -108,14 +109,21 @@ bool no_rtt_info(struct rtt_state s) { #define MINIMAL_TIMEOUT_ADDITION 20 -// This is verbatim (minus the default timeout value and minimal variance) RFC2988, sec. 2 -int32_t calc_timeout(struct rtt_state state) { - int32_t timeout = state.srtt + MAX(4 * state.variance, MINIMAL_TIMEOUT_ADDITION); - timeout = timeout * (1 << state.consecutive_timeouts); - if (timeout > MAX_TIMEOUT) { +unsigned back_off_timeout(uint32_t to, int pow) { + if (pow > MAX_BACKOFF) { + return to *= 1 << MAX_BACKOFF; + } else { + return to * (1 << pow); + } + if (to > MAX_TIMEOUT) { return MAX_TIMEOUT; } - return timeout; +} + +// This is verbatim (minus the default timeout value and minimal variance) RFC2988, sec. 2 +unsigned calc_timeout(struct rtt_state state) { + int32_t timeout = state.srtt + MAX(4 * state.variance, MINIMAL_TIMEOUT_ADDITION); + return back_off_timeout(timeout, state.consecutive_timeouts); } // This is verbatim RFC2988, sec. 2 @@ -219,7 +227,7 @@ struct kr_transport *choose_transport(struct choice choices[], unsigned timeout = calc_timeout(choices[choice].address_state->rtt_state); if (no_rtt_info(choices[choice].address_state->rtt_state)) { // Exponential back-off when retrying after timeout and choosing an unknown server - timeout *= 1 << timeouts; + timeout = back_off_timeout(timeout, timeouts); } enum kr_transport_protocol protocol; diff --git a/lib/selection_iter.c b/lib/selection_iter.c index f54c333ab..5b2cb3c94 100644 --- a/lib/selection_iter.c +++ b/lib/selection_iter.c @@ -202,7 +202,7 @@ void iter_choose_transport(struct kr_query *qry, struct kr_transport **transport const char *ns_str = kr_straddr(&(*transport)->address.ip); if ((*transport)->protocol) { VERBOSE_MSG(qry, - "=> id: '%05u' choosing: '%s'@'%s' with timeout %d ms zone cut: '%s'\n", + "=> id: '%05u' choosing: '%s'@'%s' with timeout %u ms zone cut: '%s'\n", qry->id, ns_name, ns_str ? ns_str : "", (*transport)->timeout, zonecut_str); } else { VERBOSE_MSG(qry,