]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/iterate: QUERY_PERMISSIVE mode
authorMarek Vavrusa <marek@vavrusa.com>
Fri, 15 Apr 2016 07:03:13 +0000 (00:03 -0700)
committerMarek Vavrusa <marek@vavrusa.com>
Fri, 15 Apr 2016 07:03:13 +0000 (00:03 -0700)
in permissive mode, resolver is free to use
(but not cache) non-mandatory glue records even
if they're not resolvable. this is great as a
workaround for broken child-side zones, but
not great for security of, well, insecure
delegations. it's off by default.

lib/layer/iterate.c
lib/layer/pktcache.c
lib/layer/rrcache.c
lib/rplan.h
tests/deckard

index 773e418c8f4e5f894d1b4932b5bfb22b99961a8e..6a039326481e39ab554eb3cfd75aee5980ce2e93 100644 (file)
@@ -224,6 +224,8 @@ static int update_cut(knot_pkt_t *pkt, const knot_rrset_t *rr, struct kr_request
 #endif
        }
 
+       /* Remember current bailiwick for NS processing. */
+       const knot_dname_t *current_cut = cut->name;
        /* Update zone cut name */
        if (!knot_dname_is_equal(rr->owner, cut->name)) {
                /* Remember parent cut and descend to new (keep keys and TA). */
@@ -250,7 +252,10 @@ static int update_cut(knot_pkt_t *pkt, const knot_rrset_t *rr, struct kr_request
                        continue;
                }
                kr_zonecut_add(cut, ns_name, NULL);
-               fetch_glue(pkt, ns_name, qry);
+               /* Use glue only in permissive mode or when in bailiwick. */
+               if ((qry->flags & QUERY_PERMISSIVE) || knot_dname_in(current_cut, ns_name)) {
+                       fetch_glue(pkt, ns_name, qry);
+               }
        }
 
        return state;
index e80b5e128a2021a53d09ae915efda7ac848ba64a..205653ce76065816ee7e952474222736e6d1e733 100644 (file)
@@ -181,10 +181,9 @@ static int pktcache_stash(knot_layer_t *ctx, knot_pkt_t *pkt)
                return ctx->state;
        }
        /* Cache only NODATA/NXDOMAIN or metatype/RRSIG or
-         * wildcard expanded answers. */
+        * wildcard expanded answers. */
        const uint16_t qtype = knot_pkt_qtype(pkt);
-       const bool is_eligible = (knot_rrtype_is_metatype(qtype) ||
-                                 qtype == KNOT_RRTYPE_RRSIG);
+       const bool is_eligible = (knot_rrtype_is_metatype(qtype) || qtype == KNOT_RRTYPE_RRSIG);
        int pkt_class = kr_response_classify(pkt);
        if (!(is_eligible || (pkt_class & (PKT_NODATA|PKT_NXDOMAIN)) ||
            (qry->flags & QUERY_DNSSEC_WEXPAND))) {
index cd0e75475b85a1331c1aad734702a7b4d4ab7bc6..1e8d72233f4c89f88ac4205fcea3c439794f1408 100644 (file)
@@ -268,7 +268,10 @@ static int stash_authority(struct kr_query *qry, knot_pkt_t *pkt, map_t *stash,
                }
                /* Look up glue records for NS */
                if (rr->type == KNOT_RRTYPE_NS) {
-                       stash_glue(stash, pkt, knot_ns_name(&rr->rrs, 0), pool);
+                       const knot_dname_t *ns_name = knot_ns_name(&rr->rrs, 0);
+                       if (qry->flags & QUERY_PERMISSIVE || knot_dname_in(qry->zone_cut.name, ns_name)) {
+                               stash_glue(stash, pkt, ns_name, pool);
+                       }
                }
                /* Stash record */
                kr_rrmap_add(stash, rr, KR_RANK_NONAUTH, pool);
@@ -334,9 +337,11 @@ static int rrcache_stash(knot_layer_t *ctx, knot_pkt_t *pkt)
        bool is_auth = knot_wire_get_aa(pkt->wire);
        if (is_auth) {
                ret = stash_answer(qry, pkt, &stash, &req->pool);
-       }
+               if (ret == 0) {
+                       ret = stash_authority(qry, pkt, &stash, &req->pool);
+               }
        /* Cache authority only if chasing referral/cname chain */
-       if (!is_auth || qry != array_tail(req->rplan.pending)) {
+       } else if (!is_auth || qry != array_tail(req->rplan.pending)) {
                ret = stash_authority(qry, pkt, &stash, &req->pool);
        }
        /* Cache DS records in referrals */
index 17df1475cfe382797ce366f6d1335fe002db86c7..69a58fa3b75a453ec48f693cf1a4a558656ea92d 100644 (file)
@@ -44,7 +44,8 @@
        X(DNSSEC_INSECURE, 1 << 16) /**< Query response is DNSSEC insecure. */ \
        X(STUB,            1 << 17) /**< Stub resolution, accept received answer as solved. */ \
        X(ALWAYS_CUT,      1 << 18) /**< Always recover zone cut (even if cached). */ \
-       X(DNSSEC_WEXPAND,  1 << 19) /**< Query response has wildcard expansion. */
+       X(DNSSEC_WEXPAND,  1 << 19) /**< Query response has wildcard expansion. */ \
+       X(PERMISSIVE,      1 << 20) /**< Permissive referral path resolution. */
 
 /** Query flags */
 enum kr_query_flag {
index 8bdd07d0a238b861b399ac2158978aa0066063da..93766685eb05898b5591e2b243906af9f9fc75b9 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 8bdd07d0a238b861b399ac2158978aa0066063da
+Subproject commit 93766685eb05898b5591e2b243906af9f9fc75b9