Commit dc300136 authored by Marek Vavrusa's avatar Marek Vavrusa
Browse files

lib/iterate: QUERY_PERMISSIVE mode

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.
parent 6e2c36a2
......@@ -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;
......
......@@ -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))) {
......
......@@ -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 */
......
......@@ -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 {
......
deckard @ 93766685
Subproject commit 8bdd07d0a238b861b399ac2158978aa0066063da
Subproject commit 93766685eb05898b5591e2b243906af9f9fc75b9
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment