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)
{
*/
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);
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;
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;
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);
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