]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/nsrep: use other NS addresses as alternative
authorMarek Vavruša <marek.vavrusa@nic.cz>
Sun, 15 Nov 2015 11:51:14 +0000 (12:51 +0100)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Sun, 15 Nov 2015 11:51:14 +0000 (12:51 +0100)
this allows daemon to try other NSs for fast retransmit if the best chosen NS doesn’t respond within time limit

lib/nsrep.c
lib/nsrep.h

index 9ba7a3a38a65097bba9abcffad5379c84b368660..c0d6fa064a4ffd259d362aeaf1f79615e5fb0ed3 100644 (file)
@@ -44,6 +44,9 @@ static void update_nsrep(struct kr_nsrep *ns, size_t pos, uint8_t *addr, size_t
                return;
        }
 
+       /* Rotate previous addresses to the right. */
+       memmove(ns->addr + pos + 1, ns->addr + pos, (KR_NSREP_MAXADDR - pos - 1) * sizeof(ns->addr[0]));
+
        switch(addr_len) {
        case sizeof(struct in_addr):
                ADDR_SET(ns->addr[pos].ip4.sin, AF_INET, addr, addr_len); break;
@@ -63,7 +66,7 @@ static void update_nsrep_set(struct kr_nsrep *ns, const knot_dname_t *name, uint
                        size_t len = pack_obj_len(addr[i]);
                        update_nsrep(ns, i, addr_val, len);
                } else {
-                       update_nsrep(ns, i, NULL, 0);
+                       break;
                }
        }
 }
@@ -91,8 +94,8 @@ static unsigned eval_addr_set(pack_t *addr_set, kr_nsrep_lru_t *rttcache, unsign
                        unsigned *cached = rttcache ? lru_get(rttcache, val, len) : NULL;
                        unsigned addr_score = (cached) ? *cached : KR_NS_GLUED;
                        if (addr_score < score + favour) {
-                               /* Shake down previous contenders, last one is always unused */
-                               for (size_t i = KR_NSREP_MAXADDR - 2; i > 0; --i)
+                               /* Shake down previous contenders */
+                               for (size_t i = KR_NSREP_MAXADDR - 1; i > 0; --i)
                                        addr[i] = addr[i - 1];
                                addr[0] = it;
                                score = addr_score;
@@ -142,7 +145,7 @@ 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 & QUERY_NO_THROTTLE || score < KR_NS_TIMEOUT)) {
+       if (score <= ns->score && (qry->flags & QUERY_NO_THROTTLE || score < KR_NS_TIMEOUT)) {
                update_nsrep_set(ns, (const knot_dname_t *)k, addr_choice, score);
                ns->reputation = reputation;
        } else {
index f733074852d06aeb26726b647133c8f354bd6c7b..dbeca487645af7be80d99bbcf28e1dda30473f61 100644 (file)
@@ -53,7 +53,7 @@ enum kr_ns_rep {
 typedef lru_hash(unsigned) kr_nsrep_lru_t;
 
 /* Maximum count of addresses probed in one go (last is left empty) */
-#define KR_NSREP_MAXADDR 3
+#define KR_NSREP_MAXADDR 4
 
 /**
  * Name server representation.