From: Štěpán Balážik Date: Sat, 29 Aug 2020 12:30:06 +0000 (+0200) Subject: selection: exponential back off after timeout X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c2603ac6ab451ddabbcc1828069edbc111c20970;p=thirdparty%2Fknot-resolver.git selection: exponential back off after timeout --- diff --git a/lib/selection.c b/lib/selection.c index d8a0ac00a..638fc5035 100644 --- a/lib/selection.c +++ b/lib/selection.c @@ -122,6 +122,10 @@ struct rtt_state calc_rtt_state(struct rtt_state old, unsigned new_rtt) { return ret; } +bool no_rtt_info(struct rtt_state s) { + return s.srtt == -1 && s.variance == -1; +} + void check_tls_capable(struct address_state *address_state, struct kr_request *req, struct sockaddr *address) { address_state->tls_capable = req->selection_context.is_tls_capable ? req->selection_context.is_tls_capable(address) : false; } @@ -161,6 +165,7 @@ struct kr_transport *choose_transport(struct choice choices[], int choices_len, knot_dname_t **unresolved, int unresolved_len, + int timeouts, struct knot_mm *mempool, bool tcp, size_t *out_forward_index) { @@ -192,6 +197,12 @@ 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; + } + *transport = (struct kr_transport) { .name = choices[choice].address_state->name, .protocol = tcp ? KR_TRANSPORT_TCP : KR_TRANSPORT_UDP, diff --git a/lib/selection.h b/lib/selection.h index 3edeab33c..2e91436b6 100644 --- a/lib/selection.h +++ b/lib/selection.h @@ -93,6 +93,7 @@ struct kr_transport *choose_transport(struct choice choices[], int choices_len, knot_dname_t **unresolved, int unresolved_len, + int timeouts, struct knot_mm *mempool, bool tcp, size_t *out_forward_index); diff --git a/lib/selection_forward.c b/lib/selection_forward.c index b80489395..a68d65d3e 100644 --- a/lib/selection_forward.c +++ b/lib/selection_forward.c @@ -70,7 +70,7 @@ void forward_choose_transport(struct kr_query *qry, struct kr_transport **transp }; } - *transport = choose_transport(choices, valid, NULL, 0, &qry->request->pool, qry->flags.TCP, &local_state->last_choice_index); + *transport = choose_transport(choices, valid, NULL, 0, qry->server_selection.timeouts, &qry->request->pool, qry->flags.TCP, &local_state->last_choice_index); } void forward_success(struct kr_query *qry, const struct kr_transport *transport) { diff --git a/lib/selection_iter.c b/lib/selection_iter.c index 07ab52478..620a16add 100644 --- a/lib/selection_iter.c +++ b/lib/selection_iter.c @@ -171,7 +171,7 @@ void iter_choose_transport(struct kr_query *qry, struct kr_transport **transport trie_it_free(it); if (valid_addresses || to_resolve) { - *transport = choose_transport(choices, valid_addresses, unresolved_names, to_resolve, mempool, qry->flags.TCP, NULL); + *transport = choose_transport(choices, valid_addresses, unresolved_names, to_resolve, qry->server_selection.timeouts, mempool, qry->flags.TCP, NULL); } else { *transport = NULL; }