]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/selection: be more careful around rtt_state.dead_since
authorVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 29 Dec 2020 08:28:16 +0000 (09:28 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 31 Dec 2020 14:36:11 +0000 (15:36 +0100)
It's all because the timestamp that we're using isn't (guaranteed to be)
meaningful across reboots or different machines, whereas our cache even
persists by default.

lib/selection.c

index 6dad1a29697a387d0204f2c476a52a804a6a8958..0f88e15c8e0ade95deb81c28d93aa7da3d49a6f0 100644 (file)
@@ -179,8 +179,20 @@ static struct rtt_state calc_rtt_state(struct rtt_state old, unsigned new_rtt)
 static void invalidate_dead_upstream(struct address_state *state,
                                     unsigned int retry_timeout)
 {
-       if (kr_now() - state->rtt_state.dead_since < retry_timeout) {
-               state->generation = -1;
+       struct rtt_state *rs = &state->rtt_state;
+       if (rs->consecutive_timeouts >= KR_NS_TIMEOUT_ROW_DEAD) {
+               uint64_t now = kr_now();
+               if (now < rs->dead_since) {
+                       // broken continuity of timestamp (reboot, different machine, etc.)
+                       *rs = default_rtt_state;
+               } else if (now < rs->dead_since + retry_timeout) {
+                       // period when we don't want to use the address
+                       state->generation = -1;
+               } else {
+                       assert(now >= rs->dead_since + retry_timeout);
+                       // we allow to retry the server now
+                       // TODO: perhaps tweak *rs?
+               }
        }
 }