]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
iterate: fix minimisation downgrade when encountering authoritative referrals
authorMarek Vavruša <mvavrusa@cloudflare.com>
Thu, 12 Apr 2018 17:35:57 +0000 (10:35 -0700)
committerMarek Vavruša <mvavrusa@cloudflare.com>
Fri, 7 Sep 2018 17:45:21 +0000 (10:45 -0700)
This fixes turning off minimisation when there's an authoritative referral
answer on the resolution path. This happens when there's a nameserver,
which is authoritative for both parent and child side of the delegation,
so it answers from the child side with AA=1. Such answer will be mistakenly
processed as authoritative, and QNAME minimisation will be turned off
(assuming this is the final zone cut).

lib/layer/iterate.c
lib/utils.c

index 32aa0e1728c6f796c88fc8455f612e2530f66a01..70e45f26aa78d10395ff4994326a2fc28b908fb1 100644 (file)
@@ -457,6 +457,9 @@ static int process_authority(knot_pkt_t *pkt, struct kr_request *req)
                                /* NS below cut in authority indicates different authority,
                                 * but same NS set. */
                                qry->zone_cut.name = knot_dname_copy(rr->owner, &req->pool);
+                               /* Process as referral unless the NS is actually the target of the current query. */
+                               if (!knot_dname_is_equal(rr->owner, qry->sname))
+                                       result = KR_STATE_DONE;
                        }
                }
        }
@@ -1091,6 +1094,7 @@ static int resolve(kr_layer_t *ctx, knot_pkt_t *pkt)
        }
 
        /* Resolve authority to see if it's referral or authoritative. */
+       bool is_referral_and_auth = knot_wire_get_aa(pkt->wire);
        int state = process_authority(pkt, req);
        switch(state) {
        case KR_STATE_CONSUME: /* Not referral, process answer. */
@@ -1099,6 +1103,11 @@ static int resolve(kr_layer_t *ctx, knot_pkt_t *pkt)
                break;
        case KR_STATE_DONE: /* Referral */
                state = process_referral_answer(pkt,req);
+               /* Continue with the server when switching from parent to child zone
+                * side of the delegation on the same nameserver. */
+               if (state == KR_STATE_DONE && is_referral_and_auth) {
+                       state = KR_STATE_CONSUME;
+               }
                VERBOSE_MSG("<= referral response, follow\n");
                break;
        default:
index 38ba39d55ab7dce00974e498f8d9a7817c3b3060..dac35b548febd67dfecc8be3eac87ef58ed8238f 100644 (file)
@@ -720,7 +720,6 @@ int kr_ranked_rrarray_add(ranked_rr_array_t *array, const knot_rrset_t *rr,
                /* Found the entry to merge with.  Check consistency and merge. */
                bool ok = stashed->rank == rank && !stashed->cached;
                if (!ok) {
-                       assert(false);
                        return kr_error(EEXIST);
                }
                /* It may happen that an RRset is first considered useful