]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/resolve: penalize failing NSs
authorMarek Vavruša <marek.vavrusa@nic.cz>
Thu, 3 Dec 2015 13:54:30 +0000 (14:54 +0100)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Thu, 3 Dec 2015 14:13:54 +0000 (15:13 +0100)
any answer that is considered as malformed/servfail/otherwise bad
penalizes the NS for the next time like timeout, this doesn't apply for
DNSSEC validation failures as it still may be okay for insecure
resolution. EDNS failures are okay because the server is requeried in
the most simple RFC1035 mode before flagging it as failed

this avoids instant requeries for SERVFAILing resolutions

lib/nsrep.c
lib/resolve.c

index 2dfd05d2cf2d80a37730badb5ece81a304c6c44f..b872c33e8bece03be4477f999e0cb69532db7efb 100644 (file)
@@ -154,8 +154,8 @@ static int eval_nsrep(const char *k, void *v, void *baton)
                update_nsrep_set(ns, (const knot_dname_t *)k, addr_choice, score);
                ns->reputation = reputation;
        } else {
-               /* With 5% chance, probe server with a probability given by its RTT / MAX_RTT */
-               if ((kr_rand_uint(100) < 5) && (kr_rand_uint(KR_NS_MAX_SCORE) >= score)) {
+               /* 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. */
                        if (score >= KR_NS_LONG) {
                                qry->flags |= QUERY_TCP;
index 97bd81cedfa651cc2bdd47c81727014795dfbd9f..b665345ee082ad0be907ae750f70965619380c74 100644 (file)
@@ -437,13 +437,30 @@ int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, k
        }
 
        /* Track RTT for iterative answers */
-       if (!(qry->flags & QUERY_CACHED)) {
-               struct timeval now;
-               gettimeofday(&now, NULL);
-               kr_nsrep_update_rtt(&qry->ns, src, time_diff(&qry->timestamp, &now), ctx->cache_rtt);
-               /* Sucessful answer, lift any address resolution requests. */
-               if (request->state != KNOT_STATE_FAIL)
+       if (src && !(qry->flags & QUERY_CACHED)) {
+               /* Sucessful answer, track RTT and lift any address resolution requests. */
+               if (request->state != KNOT_STATE_FAIL) {
+                       /* Do not track in safe mode. */
+                       if (!(qry->flags & QUERY_SAFEMODE)) {
+                               struct timeval now;
+                               gettimeofday(&now, NULL);
+                               kr_nsrep_update_rtt(&qry->ns, src, time_diff(&qry->timestamp, &now), ctx->cache_rtt);
+                               WITH_DEBUG {
+                                       char addr_str[SOCKADDR_STRLEN];
+                                       inet_ntop(src->sa_family, kr_inaddr(src), addr_str, sizeof(addr_str));
+                                       DEBUG_MSG(qry, "<= server: '%s' rtt: %ld ms\n", addr_str, time_diff(&qry->timestamp, &now));
+                               }
+                       }
                        qry->flags &= ~(QUERY_AWAIT_IPV6|QUERY_AWAIT_IPV4);
+               /* Do not penalize validation timeouts. */
+               } else if (!(qry->flags & QUERY_DNSSEC_BOGUS)) {
+                       kr_nsrep_update_rtt(&qry->ns, src, KR_NS_TIMEOUT, ctx->cache_rtt);
+                       WITH_DEBUG {
+                               char addr_str[SOCKADDR_STRLEN];
+                               inet_ntop(src->sa_family, kr_inaddr(src), addr_str, sizeof(addr_str));
+                               DEBUG_MSG(qry, "=> server: '%s' flagged as 'bad'\n", addr_str);
+                       }
+               }
        }
        /* Resolution failed, invalidate current NS. */
        if (request->state == KNOT_STATE_FAIL) {