From: Grigorii Demidov Date: Mon, 15 May 2017 11:54:29 +0000 (+0200) Subject: lib/resolve: use TA with longest eligible name in forwarding mode X-Git-Tag: 1.3.0-rc1~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cca9e25729cab7764b0258c404d788e8eb181cdc;p=thirdparty%2Fknot-resolver.git lib/resolve: use TA with longest eligible name in forwarding mode --- diff --git a/lib/dnssec/ta.c b/lib/dnssec/ta.c index 2cc503c73..740444eeb 100644 --- a/lib/dnssec/ta.c +++ b/lib/dnssec/ta.c @@ -31,6 +31,20 @@ knot_rrset_t *kr_ta_get(map_t *trust_anchors, const knot_dname_t *name) return map_get(trust_anchors, (const char *)name); } +const knot_dname_t *kr_ta_get_longest_name(map_t *trust_anchors, const knot_dname_t *name) +{ + while(name) { + if (kr_ta_get(trust_anchors, name)) { + return name; + } + if (name[0] == '\0') { + break; + } + name = knot_wire_next_label(name, NULL); + } + return NULL; +} + /* @internal Create DS from DNSKEY, caller MUST free dst if successful. */ static int dnskey2ds(dnssec_binary_t *dst, const knot_dname_t *owner, const uint8_t *rdata, uint16_t rdlen) { diff --git a/lib/dnssec/ta.h b/lib/dnssec/ta.h index 9a8c498fb..dcc55e78c 100644 --- a/lib/dnssec/ta.h +++ b/lib/dnssec/ta.h @@ -75,3 +75,13 @@ int kr_ta_del(map_t *trust_anchors, const knot_dname_t *name); */ KR_EXPORT void kr_ta_clear(map_t *trust_anchors); + +/** + * Return TA with the longest name that covers given name. + * @param trust_anchors trust store + * @param name name of the TA + * @return pointer to name or NULL. + if not NULL, points inside the name parameter. + */ +KR_EXPORT +const knot_dname_t *kr_ta_get_longest_name(map_t *trust_anchors, const knot_dname_t *name); diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index d3c79ae66..4d6477ab6 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -661,7 +661,7 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req) return KR_STATE_FAIL; } if (query->flags & QUERY_FORWARD) { - next->flags |= QUERY_FORWARD; + next->flags |= (QUERY_FORWARD | QUERY_AWAIT_CUT); state = kr_nsrep_copy_set(&next->ns, &query->ns); if (state != kr_ok()) { return KR_STATE_FAIL; diff --git a/lib/resolve.c b/lib/resolve.c index efae9b739..1a659781a 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -930,18 +930,34 @@ static int forward_trust_chain_check(struct kr_request *request, struct kr_query assert(qry->flags & QUERY_FORWARD); + if (!trust_anchors) { + qry->flags &= ~QUERY_AWAIT_CUT; + return KR_STATE_PRODUCE; + } + if (qry->flags & QUERY_DNSSEC_INSECURE) { + qry->flags &= ~QUERY_AWAIT_CUT; return KR_STATE_PRODUCE; } + const knot_dname_t *wanted_name = NULL; + const knot_dname_t *start_name = qry->sname; + if (qry->flags & QUERY_AWAIT_CUT) { + const knot_dname_t *longest_ta = kr_ta_get_longest_name(trust_anchors, qry->sname); + if (longest_ta) { + start_name = longest_ta; + qry->zone_cut.name = knot_dname_copy(start_name, qry->zone_cut.pool); + } + qry->flags &= ~QUERY_AWAIT_CUT; + } + bool nods = false; bool ds_req = false; bool ns_req = false; bool minimized = false; - const knot_dname_t* wanted_name = NULL; int name_offset = 1; do { - wanted_name = qry->sname; + wanted_name = start_name; nods = false; ds_req = false; ns_req = false; @@ -1031,7 +1047,9 @@ static int forward_trust_chain_check(struct kr_request *request, struct kr_query char name[] = "\0"; ta_rr = kr_ta_get(trust_anchors, (knot_dname_t*)name); } - qry->zone_cut.trust_anchor = knot_rrset_copy(ta_rr, qry->zone_cut.pool); + if (ta_rr) { + qry->zone_cut.trust_anchor = knot_rrset_copy(ta_rr, qry->zone_cut.pool); + } } const bool has_ta = (qry->zone_cut.trust_anchor != NULL); diff --git a/modules/policy/policy.lua b/modules/policy/policy.lua index 2c19ed854..dafbdf3ea 100644 --- a/modules/policy/policy.lua +++ b/modules/policy/policy.lua @@ -99,6 +99,7 @@ local function forward(target) req.options = bit.bor(bit.bor(req.options, kres.query.FORWARD), kres.query.NO_MINIMIZE) qry.flags = bit.band(bit.bor(qry.flags, kres.query.FORWARD), bit.bnot(kres.query.ALWAYS_CUT)) qry.flags = bit.bor(qry.flags, kres.query.NO_MINIMIZE) + qry.flags = bit.bor(qry.flags, kres.query.AWAIT_CUT) qry:nslist(list) return state end