]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/nsrep: some changes in NS selection algorythm
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Wed, 7 Mar 2018 16:21:07 +0000 (17:21 +0100)
committerPetr Špaček <petr.spacek@nic.cz>
Wed, 28 Mar 2018 09:15:18 +0000 (11:15 +0200)
daemon/lua/kres-gen.lua
daemon/worker.c
lib/nsrep.c
lib/resolve.c
lib/rplan.h
modules/serve_stale/serve_stale.lua

index a0210962e43cc3bcd00131422e1f15286f08eeff..c2d1bce1748e2accbcce99a9d60df046bd7efa30 100644 (file)
@@ -96,6 +96,7 @@ struct kr_qflags {
        _Bool FORWARD : 1;
        _Bool DNS64_MARK : 1;
        _Bool CACHE_TRIED : 1;
+       _Bool NO_NS_FOUND : 1;
 };
 typedef struct {
        knot_rrset_t **at;
index 62b87ee26f78e6b85651853afce0966620ad9820..95ce4078ba45dc38c86d906ef30079204ade7e13 100644 (file)
@@ -1329,7 +1329,7 @@ static void on_udp_timeout(uv_timer_t *timer)
                                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_UPDATE);
+                                           worker->engine->resolver.cache_rtt, KR_NS_RESET);
                }
        }
        task->timeouts += 1;
index b25453b4916035bf7a14c7be1cf3d03c48533a36..30101a3db61234fb9baaf4df92060336558609a4 100644 (file)
@@ -162,10 +162,10 @@ static int eval_nsrep(const char *k, void *v, void *baton)
         * The fastest NS is preferred by workers until it is depleted (timeouts or degrades),
         * at the same time long distance scouts probe other sources (low probability).
         * Servers on TIMEOUT (depleted) can be probed by the dice roll only */
-       if (score <= ns->score && (qry->flags.NO_THROTTLE || score < KR_NS_TIMEOUT)) {
+       if (score <= ns->score && (score < KR_NS_LONG  || (qry->flags.NO_THROTTLE && (score < KR_NS_TIMEOUT)))) {
                update_nsrep_set(ns, (const knot_dname_t *)k, addr_choice, score);
                ns->reputation = reputation;
-       } else {
+       } else if (score < KR_NS_TIMEOUT) {
                /* With 10% chance, probe server with a probability given by its RTT / MAX_RTT */
                if ((kr_rand_uint(100) < 10) && (kr_rand_uint(KR_NS_MAX_SCORE) >= score)) {
                        /* If this is a low-reliability probe, go with TCP to get ICMP reachability check. */
index c0836201c615658a988670d5680d73f7a99a616c..759cb86ee6881699d6a2a443317c9737954190a3 100644 (file)
@@ -863,7 +863,7 @@ static void update_nslist_score(struct kr_request *request, struct kr_query *qry
                }
        /* Penalise resolution failures except validation failures. */
        } else if (!(qry->flags.DNSSEC_BOGUS)) {
-               kr_nsrep_update_rtt(&qry->ns, src, KR_NS_TIMEOUT, ctx->cache_rtt, KR_NS_RESET);
+               kr_nsrep_update_rtt(&qry->ns, src, KR_NS_TIMEOUT, ctx->cache_rtt, KR_NS_UPDATE);
                WITH_VERBOSE(qry) {
                        char addr_str[INET6_ADDRSTRLEN];
                        inet_ntop(src->sa_family, kr_inaddr(src), addr_str, sizeof(addr_str));
@@ -1433,8 +1433,12 @@ ns_election:
                        } else {
                                VERBOSE_MSG(qry, "=> no valid NS left\n");
                        }
-                       ITERATE_LAYERS(request, qry, reset);
-                       kr_rplan_pop(rplan, qry);
+                       if (!qry->flags.NO_NS_FOUND) {
+                               qry->flags.NO_NS_FOUND = true;
+                       } else {
+                               ITERATE_LAYERS(request, qry, reset);
+                               kr_rplan_pop(rplan, qry);
+                       }
                        return KR_STATE_PRODUCE;
                }
        }
index 0600b3c89d12ac8bc4fad50a681039d53ea0cba6..adb67eaeb9983436776c26682d673daba0343d41 100644 (file)
@@ -62,6 +62,7 @@ struct kr_qflags {
        bool FORWARD : 1;        /**< Forward all queries to upstream; validate answers. */
        bool DNS64_MARK : 1;     /**< Internal mark for dns64 module. */
        bool CACHE_TRIED : 1;    /**< Internal to cache module. */
+       bool NO_NS_FOUND : 1;    /**< No valid NS found during last PRODUCE stage. */
 };
 
 /** Combine flags together.  This means set union for simple flags. */
index c8677ba1eab2b09d59ccad19e21f633d5fbd00b4..2c3971a8d630307d613b3cdda3cc91f6894180f8 100644 (file)
@@ -26,8 +26,8 @@ M.layer = {
 
                local now = ffi.C.kr_now()
                local deadline = qry.creation_time_mono + M.timeout
-               if now > deadline then
-                       --log('[     ][stal]   => deadline has passed')
+               if now > deadline or qry.flags.NO_NS_FOUND then
+                       log('[     ][stal]   => deadline has passed')
                        qry.stale_cb = M.callback
                        -- TODO: probably start the same request that doesn't stale-serve,
                        -- but first we need some detection of non-interactive / internal requests.