]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
selection: exponential back off after timeout
authorŠtěpán Balážik <stepan.balazik@nic.cz>
Sat, 29 Aug 2020 12:30:06 +0000 (14:30 +0200)
committerŠtěpán Balážik <stepan.balazik@nic.cz>
Thu, 15 Oct 2020 11:22:21 +0000 (13:22 +0200)
lib/selection.c
lib/selection.h
lib/selection_forward.c
lib/selection_iter.c

index d8a0ac00ad2561fff888effcbe6c33c115dd6435..638fc5035785b5be648b039fe5f2c21ab17f8660 100644 (file)
@@ -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,
index 3edeab33cbbfc629474cfb25c88289ba7bbb3def..2e91436b6ed408470f656a03b7ea160eafa27493 100644 (file)
@@ -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);
index b804893957a5c133aacdae7b5e4bb7742d861c33..a68d65d3e57c5880f7d3b0a1c6e719de4c34dcf5 100644 (file)
@@ -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) {
index 07ab52478265813fdb4bc7d8239db519525a53ca..620a16adda7283a6ed0437b6e5182f33adddd25a 100644 (file)
@@ -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;
     }