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;
}
int choices_len,
knot_dname_t **unresolved,
int unresolved_len,
+ int timeouts,
struct knot_mm *mempool,
bool tcp,
size_t *out_forward_index) {
}
}
+ 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,
int choices_len,
knot_dname_t **unresolved,
int unresolved_len,
+ int timeouts,
struct knot_mm *mempool,
bool tcp,
size_t *out_forward_index);
};
}
- *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) {
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;
}