--------
- policy.rpz: improve logs, fix origin detection in files without $ORIGIN
- lua: log() works again; broken in 5.4.2 (!1223)
+- policy: correctly include EDNS0 previously omitted by some actions (!1230)
Knot Resolver 5.4.2 (2021-10-13)
knot_pkt_t *knot_pkt_new(void *, uint16_t, knot_mm_t *);
void knot_pkt_free(knot_pkt_t *);
int knot_pkt_parse(knot_pkt_t *, unsigned int);
+knot_rrset_t *kr_request_ensure_edns(struct kr_request *);
knot_pkt_t *kr_request_ensure_answer(struct kr_request *);
struct kr_rplan *kr_resolve_plan(struct kr_request *);
knot_mm_t *kr_resolve_pool(struct kr_request *);
knot_pkt_t *knot_pkt_new(void *, uint16_t, knot_mm_t *);
void knot_pkt_free(knot_pkt_t *);
int knot_pkt_parse(knot_pkt_t *, unsigned int);
+knot_rrset_t *kr_request_ensure_edns(struct kr_request *);
knot_pkt_t *kr_request_ensure_answer(struct kr_request *);
struct kr_rplan *kr_resolve_plan(struct kr_request *);
knot_mm_t *kr_resolve_pool(struct kr_request *);
## libkres API
${CDEFS} ${LIBKRES} functions <<-EOF
# Resolution request
+ kr_request_ensure_edns
kr_request_ensure_answer
kr_resolve_plan
kr_resolve_pool
req.vars_ref = ref
return var
end,
+ -- Ensure that answer has EDNS if needed; can't fail.
+ ensure_edns = function (req)
+ assert(ffi.istype(kr_request_t, req))
+ return C.kr_request_ensure_edns(req)
+ end,
-- Ensure that answer exists and return it; can't fail.
ensure_answer = function (req)
assert(ffi.istype(kr_request_t, req))
return request->state;
}
+knot_rrset_t* kr_request_ensure_edns(struct kr_request *request)
+{
+ kr_require(request && request->answer && request->qsource.packet && request->ctx);
+ knot_pkt_t* answer = request->answer;
+ bool want_edns = knot_pkt_has_edns(request->qsource.packet);
+ if (!want_edns) {
+ kr_assert(!answer->opt_rr);
+ return answer->opt_rr;
+ } else if (answer->opt_rr) {
+ return answer->opt_rr;
+ }
+
+ kr_assert(request->ctx->downstream_opt_rr);
+ answer->opt_rr = knot_rrset_copy(request->ctx->downstream_opt_rr, &answer->mm);
+ if (!answer->opt_rr)
+ return NULL;
+ if (knot_pkt_has_dnssec(request->qsource.packet))
+ knot_edns_set_do(answer->opt_rr);
+ return answer->opt_rr;
+}
+
knot_pkt_t *kr_request_ensure_answer(struct kr_request *request)
{
if (request->answer)
}
// Prepare EDNS if required.
- if (knot_pkt_has_edns(qs_pkt)) {
- answer->opt_rr = knot_rrset_copy(request->ctx->downstream_opt_rr,
- &answer->mm);
- if (!answer->opt_rr)
- goto enomem; // answer is on mempool, so "leak" is OK
- if (knot_pkt_has_dnssec(qs_pkt))
- knot_edns_set_do(answer->opt_rr);
- }
+ if (knot_pkt_has_edns(qs_pkt) && kr_fails_assert(kr_request_ensure_edns(request)))
+ goto enomem; // answer is on mempool, so "leak" is OK
return request->answer;
enomem:
KR_EXPORT
int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx);
+/**
+ * Ensure that request->answer->opt_rr is present if query has EDNS.
+ *
+ * This function should be used after clearing a response packet to ensure its
+ * opt_rr is properly set. Returns the opt_rr (for convenience) or NULL.
+ */
+KR_EXPORT
+knot_rrset_t * kr_request_ensure_edns(struct kr_request *request);
+
/**
* Ensure that request->answer is usable, and return it (for convenience).
*
local pkt = req:ensure_answer()
if pkt == nil then return nil end
pkt:clear_payload()
+ req:ensure_edns()
return pkt
end