Commit 53a3ed96 authored by Karel Slaný's avatar Karel Slaný

layer/validate: resolver queries for missing DNSKEYS

parent cd8ed460
......@@ -733,6 +733,12 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt)
#warning TODO: set QUERY_AWAIT_CUT for next query in plan ?
}
}
if ((qtype == KNOT_RRTYPE_DNSKEY) && (qry->parent != NULL) && (qry->parent->zone_cut.key == NULL)) {
qry->parent->zone_cut.key = knot_rrset_copy(qry->zone_cut.key, qry->parent->zone_cut.pool);
if (!qry->parent->zone_cut.key) {
return KNOT_STATE_FAIL;
}
}
DEBUG_MSG("<= answer valid, OK\n");
return ctx->state;
......
......@@ -489,8 +489,8 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t
/* The query wasn't resolved from cache,
* now it's the time to look up closest zone cut from cache.
*/
bool want_secured = (request->options & QUERY_DNSSEC_WANT);
if (qry->flags & QUERY_AWAIT_CUT) {
bool want_secured = (request->options & QUERY_DNSSEC_WANT);
int ret = ns_fetch_cut(qry, request, want_secured);
if (ret != 0) {
return KNOT_STATE_FAIL;
......@@ -513,6 +513,17 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t
qry->flags &= ~QUERY_AWAIT_CUT;
}
if (want_secured && !qry->zone_cut.key && qry->stype != KNOT_RRTYPE_DNSKEY) {
struct kr_query *next = kr_rplan_push(rplan, qry, qry->zone_cut.name, KNOT_CLASS_IN, KNOT_RRTYPE_DNSKEY);
if (!next) {
return kr_error(ENOMEM);
}
int ret = kr_zonecut_copy_whole(&next->zone_cut, &qry->zone_cut);
if (ret != 0) {
return ret;
}
return KNOT_STATE_PRODUCE;
}
ns_election:
/* If the query has already selected a NS and is waiting for IPv4/IPv6 record,
......
......@@ -153,6 +153,57 @@ int kr_zonecut_copy(struct kr_zonecut *dst, const struct kr_zonecut *src)
return map_walk((map_t *)&src->nsset, copy_addr_set, dst);
}
int kr_zonecut_copy_whole(struct kr_zonecut *dst, const struct kr_zonecut *src)
{
if (!dst || !src) {
return kr_error(EINVAL);
}
kr_zonecut_deinit(dst);
memset(dst, 0, sizeof(*dst));
int ret;
dst->pool = src->pool;
dst->nsset = map_make();
dst->nsset.malloc = (map_alloc_f) mm_alloc;
dst->nsset.free = (map_free_f) mm_free;
dst->nsset.baton = dst->pool;
dst->name = knot_dname_copy(src->name, dst->pool);
if (!dst->name) {
ret = kr_error(ENOMEM);
goto fail;
}
ret = map_walk((map_t *)&src->nsset, copy_addr_set, dst);
if (ret != 0) {
goto fail;
}
if (src->key) {
dst->key = knot_rrset_copy(src->key, dst->pool);
if (!dst->key) {
ret = kr_error(ENOMEM);
goto fail;
}
}
if (src->trust_anchor) {
dst->trust_anchor = knot_rrset_copy(src->trust_anchor, dst->pool);
if (!dst->trust_anchor) {
ret = kr_error(ENOMEM);
goto fail;
}
}
return kr_ok();
fail:
kr_zonecut_deinit(dst);
memset(dst, 0, sizeof(*dst));
return ret;
}
/** @internal Filter ANY or loopback addresses. */
static bool is_valid_addr(uint8_t *addr, size_t len)
{
......
......@@ -65,6 +65,14 @@ void kr_zonecut_set(struct kr_zonecut *cut, const knot_dname_t *name);
*/
int kr_zonecut_copy(struct kr_zonecut *dst, const struct kr_zonecut *src);
/**
* Copy zone cut, including all data, really.
* @param dst destination zone cut
* @param src source zone cut
* @return 0 or an error code
*/
int kr_zonecut_copy_whole(struct kr_zonecut *dst, const struct kr_zonecut *src);
/**
* Add address record to the zone cut.
*
......
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