]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
resolve, iterate: fix fallback when upstream SERVFAILs
authorVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 7 Mar 2019 14:39:11 +0000 (15:39 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 8 Mar 2019 10:04:15 +0000 (11:04 +0100)
or REFUSEs.  We typically ended up retrying with the same server,
which is almost never good.  Now we remove the server from the set.

Nitpick: a couple kr_query fields are reordered for better packing.

NEWS
daemon/lua/kres-gen.lua
lib/layer/iterate.c
lib/resolve.c
lib/rplan.h
tests/deckard

diff --git a/NEWS b/NEWS
index 3d69602298630955a302c9ac59c641a8eed2acca..ac2229ff9c7a20ddb61401d2596c6bdbc4e4fd45 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ Bugfixes
 - fix startup on macOS+BSD when </dev/null and cqueues installed
 - policy.RPZ: log problems from zone-file level of parser as well (#453)
 - fix flushing of messages to logs in some cases (!781)
+- fix fallback when SERVFAIL or REFUSED is received from upstream (!784)
 
 Improvements
 ------------
index 727d624612515c5c7b132ea9351f28a415d6bcd5..0651f07d37c0d8650620de2e5de2e0f26e55af94 100644 (file)
@@ -244,17 +244,16 @@ struct kr_query {
        uint16_t stype;
        uint16_t sclass;
        uint16_t id;
+       uint16_t reorder;
        struct kr_qflags flags;
        struct kr_qflags forward_flags;
        uint32_t secret;
-       uint16_t fails;
-       uint16_t reorder;
+       uint32_t uid;
        uint64_t creation_time_mono;
        uint64_t timestamp_mono;
        struct timeval timestamp;
        struct kr_zonecut zone_cut;
        struct kr_layer_pickle *deferred;
-       uint32_t uid;
        struct kr_query *cname_parent;
        struct kr_request *request;
        kr_stale_cb stale_cb;
index cf57cc54c0e266d62abb560efd479466654616e4..d5448af03e8a0ff32637e4bbcd1f13d0dc810fee 100644 (file)
@@ -1073,16 +1073,7 @@ static int resolve(kr_layer_t *ctx, knot_pkt_t *pkt)
                        break;
                }
                VERBOSE_MSG("<= rcode: %s\n", rcode ? rcode->name : "??");
-               query->fails += 1;
-               if (query->fails >= KR_QUERY_NSRETRY_LIMIT) {
-                       query->fails = 0; /* Reset per-query counter. */
-                       return resolve_error(pkt, req);
-               } else {
-                       if (!query->flags.FORWARD) {
-                               query->flags.NO_MINIMIZE = true; /* Drop minimisation as a safe-guard. */
-                       }
-                       return KR_STATE_CONSUME;
-               }
+               return KR_STATE_FAIL;
        }
        case KNOT_RCODE_FORMERR:
                VERBOSE_MSG("<= rcode: %s\n", rcode ? rcode->name : "??");
index ce21edf9941261d9c4f488bd1e992ebed6894254..a83de468eaac83a314827dcd2c38ba442816627a 100644 (file)
@@ -162,7 +162,12 @@ static int invalidate_ns(struct kr_rplan *rplan, struct kr_query *qry)
        if (qry->ns.addr[0].ip.sa_family != AF_UNSPEC) {
                const char *addr = kr_inaddr(&qry->ns.addr[0].ip);
                int addr_len = kr_inaddr_len(&qry->ns.addr[0].ip);
-               return kr_zonecut_del(&qry->zone_cut, qry->ns.name, addr, addr_len);
+               int ret = kr_zonecut_del(&qry->zone_cut, qry->ns.name, addr, addr_len);
+               /* Also remove it from the qry->ns.addr array.
+                * That's useful at least for STUB and FORWARD modes. */
+               memmove(qry->ns.addr, qry->ns.addr + 1,
+                       sizeof(qry->ns.addr[0]) * (KR_NSREP_MAXADDR - 1));
+               return ret;
        } else {
                return kr_zonecut_del_all(&qry->zone_cut, qry->ns.name);
        }
index b5ac1f91c171784ff9749b968f4596e0e2b73202..6e93afc71b003c9db84e3017784f0393c24b39cf 100644 (file)
@@ -90,10 +90,10 @@ struct kr_query {
        uint16_t stype;
        uint16_t sclass;
        uint16_t id;
+       uint16_t reorder; /**< Seed to reorder (cached) RRs in answer or zero. */
        struct kr_qflags flags, forward_flags;
        uint32_t secret;
-       uint16_t fails;
-       uint16_t reorder; /**< Seed to reorder (cached) RRs in answer or zero. */
+       uint32_t uid; /**< Query iteration number, unique within the kr_rplan. */
        uint64_t creation_time_mono; /* The time of query's creation (milliseconds).
                                 * Or time of creation of an oldest
                                 * ancestor if it is a subquery. */
@@ -102,7 +102,6 @@ struct kr_query {
        struct timeval timestamp; /**< Real time for TTL+DNSSEC checks (.tv_sec only). */
        struct kr_zonecut zone_cut;
        struct kr_layer_pickle *deferred;
-       uint32_t uid; /**< Query iteration number, unique within the kr_rplan. */
        /** Pointer to the query that originated this one because of following a CNAME (or NULL). */
        struct kr_query *cname_parent;
        struct kr_request *request; /**< Parent resolution request. */
index 7ec9d93e05cf40fdeee58bc6f8bbdd3ddb216115..2a9c7de5377ed62f2569dcdb250fee44035776f4 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 7ec9d93e05cf40fdeee58bc6f8bbdd3ddb216115
+Subproject commit 2a9c7de5377ed62f2569dcdb250fee44035776f4