]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/resolve: use TA with longest eligible name in forwarding mode
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Mon, 15 May 2017 11:54:29 +0000 (13:54 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 1 Jun 2017 14:27:16 +0000 (16:27 +0200)
lib/dnssec/ta.c
lib/dnssec/ta.h
lib/layer/iterate.c
lib/resolve.c
modules/policy/policy.lua

index 2cc503c730074e33031fb5b9a4a385ae366e1037..740444eeb22d5f195301bc5baeb0eb12889b020c 100644 (file)
@@ -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)
 {
index 9a8c498fb63a157fce0450c710a8779ea096ace5..dcc55e78c148f210edc531433afa5d5a2c7e4078 100644 (file)
@@ -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);
index d3c79ae66316cb5c0ec0596c3e50e09ea5391f5e..4d6477ab67277577b687c15829029b732dcbc177 100644 (file)
@@ -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;
index efae9b7394efcd25d22285a12fd09356108b7ae6..1a659781a307969a48b63eb48c6a645f63a78d44 100644 (file)
@@ -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);
index 2c19ed85415ac12658e468cb7bf28b39c7ef01a0..dafbdf3ea8abee8e1b121007a4d891cd22919be3 100644 (file)
@@ -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