]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/nsrep: don't mark NS as 'timeouted' immediately, but after two retries
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Fri, 9 Mar 2018 15:18:21 +0000 (16:18 +0100)
committerPetr Špaček <petr.spacek@nic.cz>
Wed, 28 Mar 2018 09:15:23 +0000 (11:15 +0200)
daemon/worker.c
lib/nsrep.c
lib/nsrep.h

index d7c627fab5f3e843cb3130c7a9bdc671ee583905..df97b39cc2c32f50fd057b20742a5fbb58f494f4 100644 (file)
@@ -1077,8 +1077,8 @@ static int session_tls_hs_cb(struct session *session, int status)
        int deletion_res = worker_del_tcp_waiting(worker, &peer->ip);
 
        if (status) {
-               kr_nsrep_update_rtt(NULL, &peer->ip, KR_NS_TIMEOUT,
-                                   worker->engine->resolver.cache_rtt, KR_NS_RESET);
+               kr_nsrep_update_rtt(NULL, &peer->ip, KR_NS_DEAD,
+                                   worker->engine->resolver.cache_rtt, KR_NS_UPDATE);
        } else {
                if (deletion_res != 0) {
                        /* session isn't in list of waiting queries, *
@@ -1244,8 +1244,8 @@ static void on_tcp_connect_timeout(uv_timer_t *timer)
                VERBOSE_MSG(qry, "=> connection to '%s' failed\n", addr_str);
        }
 
-       kr_nsrep_update_rtt(NULL, &peer->ip, KR_NS_TIMEOUT,
-                           worker->engine->resolver.cache_rtt, KR_NS_RESET);
+       kr_nsrep_update_rtt(NULL, &peer->ip, KR_NS_DEAD,
+                           worker->engine->resolver.cache_rtt, KR_NS_UPDATE);
 
        while (session->waiting.len > 0) {
                struct qr_task *task = session->waiting.at[0];
@@ -1327,8 +1327,8 @@ static void on_udp_timeout(uv_timer_t *timer)
                                inet_ntop(choice->sa_family, kr_inaddr(choice), addr_str, sizeof(addr_str));
                                VERBOSE_MSG(qry, "=> server: '%s' flagged as 'bad'\n", addr_str);
                        }
-                       kr_nsrep_update_rtt(&qry->ns, choice, KR_NS_TIMEOUT,
-                                           worker->engine->resolver.cache_rtt, KR_NS_RESET);
+                       kr_nsrep_update_rtt(&qry->ns, choice, KR_NS_DEAD,
+                                           worker->engine->resolver.cache_rtt, KR_NS_UPDATE);
                }
        }
        task->timeouts += 1;
index c098f52152ac2592b3370ad9b4f5cfa05f3d2bfe..7bdabbbd0461efc203ae035802130ac6ac534d4c 100644 (file)
@@ -280,7 +280,7 @@ int kr_nsrep_elect_addr(struct kr_query *qry, struct kr_context *ctx)
 int kr_nsrep_update_rtt(struct kr_nsrep *ns, const struct sockaddr *addr,
                        unsigned score, kr_nsrep_lru_t *cache, int umode)
 {
-       if (!cache) {
+       if (!cache || umode > KR_NS_MAX) {
                return kr_error(EINVAL);
        }
 
@@ -309,10 +309,6 @@ int kr_nsrep_update_rtt(struct kr_nsrep *ns, const struct sockaddr *addr,
        if (!cur) {
                return kr_ok();
        }
-       /* Score limits */
-       if (score > KR_NS_MAX_SCORE) {
-               score = KR_NS_MAX_SCORE;
-       }
        if (score <= KR_NS_GLUED) {
                score = KR_NS_GLUED + 1;
        }
@@ -320,14 +316,20 @@ int kr_nsrep_update_rtt(struct kr_nsrep *ns, const struct sockaddr *addr,
        if (*cur == 0) {
                umode = KR_NS_RESET;
        }
+       unsigned new_score = 0;
        /* Update score, by default smooth over last two measurements. */
        switch (umode) {
-       case KR_NS_UPDATE: *cur = (*cur + score) / 2; break;
-       case KR_NS_RESET:  *cur = score; break;
-       case KR_NS_ADD:    *cur = MIN(KR_NS_MAX_SCORE - 1, *cur + score); break;
-       case KR_NS_MAX:    *cur = MAX(*cur, score); break;
+       case KR_NS_UPDATE: new_score = (*cur + score) / 2; break;
+       case KR_NS_RESET:  new_score = score; break;
+       case KR_NS_ADD:    new_score = MIN(KR_NS_MAX_SCORE - 1, *cur + score); break;
+       case KR_NS_MAX:    new_score = MAX(*cur, score); break;
        default: break;
        }
+       /* Score limits */
+       if (new_score > KR_NS_MAX_SCORE) {
+               new_score = KR_NS_MAX_SCORE;
+       }
+       *cur = new_score;
        return kr_ok();
 }
 
index b0cdd3fcc266fcc862d3d97c1cace2057dee45a4..26d9fdf894ce94f4a2c33674c25ca509ed27a0ea 100644 (file)
@@ -40,6 +40,11 @@ enum kr_ns_score {
        KR_NS_GLUED     = 10
 };
 
+/**
+ *  See kr_nsrep_update_rtt()
+ */
+#define KR_NS_DEAD ((KR_NS_TIMEOUT * 4) / 3)
+
 /**
  * NS QoS flags.
  */
@@ -117,6 +122,8 @@ int kr_nsrep_elect_addr(struct kr_query *qry, struct kr_context *ctx);
  * @param  ns           updated NS representation
  * @param  addr         chosen address (NULL for first)
  * @param  score        new score (i.e. RTT), see enum kr_ns_score
+ *                      after two calls with score = KR_NS_DEAD and umode = KR_NS_UPDATE
+ *                      server will be guaranteed to have KR_NS_TIMEOUTED score
  * @param  cache        LRU cache
  * @param  umode        update mode (KR_NS_UPDATE or KR_NS_RESET or KR_NS_ADD)
  * @return              0 on success, error code on failure