Commit 78571df0 authored by Marek Vavrusa's avatar Marek Vavrusa

internet/nsec_proofs: small cleanup

parent a3171d63
......@@ -178,7 +178,7 @@ static int put_answer(knot_pkt_t *pkt, uint16_t type, struct query_data *qdata)
return KNOT_ESPACE;
}
for (unsigned i = 0; i < knot_node_rrset_count(qdata->node); ++i) {
ret = ns_put_rr(pkt, rrsets[i], NULL, compr_hint, 0, true, qdata);
ret = ns_put_rr(pkt, rrsets[i], NULL, compr_hint, 0, qdata);
if (ret != KNOT_EOK) {
break;
}
......@@ -188,7 +188,7 @@ static int put_answer(knot_pkt_t *pkt, uint16_t type, struct query_data *qdata)
rrset = knot_node_get_rrset(qdata->node, type);
if (rrset) {
const knot_rrset_t *rrsigs = knot_node_rrset(qdata->node, KNOT_RRTYPE_RRSIG);
ret = ns_put_rr(pkt, rrset, rrsigs, compr_hint, 0, true, qdata);
ret = ns_put_rr(pkt, rrset, rrsigs, compr_hint, 0, qdata);
}
break;
}
......@@ -218,7 +218,7 @@ static int put_authority_ns(knot_pkt_t *pkt, struct query_data *qdata)
if (ns_rrset) {
const knot_rrset_t *rrsigs = knot_node_rrset(zone->apex, KNOT_RRTYPE_RRSIG);
return ns_put_rr(pkt, ns_rrset, rrsigs, COMPR_HINT_NONE,
KNOT_PF_NOTRUNC|KNOT_PF_CHECKDUP, false, qdata);
KNOT_PF_NOTRUNC|KNOT_PF_CHECKDUP, qdata);
} else {
dbg_ns("%s: no NS RRSets in this zone, fishy...\n", __func__);
}
......@@ -249,7 +249,7 @@ static int put_authority_soa(knot_pkt_t *pkt, struct query_data *qdata,
flags |= KNOT_PF_FREE;
}
ret = ns_put_rr(pkt, soa_rrset, rrsigs, COMPR_HINT_NONE, flags, false, qdata);
ret = ns_put_rr(pkt, soa_rrset, rrsigs, COMPR_HINT_NONE, flags, qdata);
if (ret != KNOT_EOK && (flags & KNOT_PF_FREE)) {
knot_rrset_deep_free(&soa_rrset, 1, &pkt->mm);
}
......@@ -268,7 +268,7 @@ static int put_delegation(knot_pkt_t *pkt, struct query_data *qdata)
/* Insert NS record. */
const knot_rrset_t *rrset = knot_node_rrset(qdata->node, KNOT_RRTYPE_NS);
const knot_rrset_t *rrsigs = knot_node_rrset(qdata->node, KNOT_RRTYPE_RRSIG);
return ns_put_rr(pkt, rrset, rrsigs, COMPR_HINT_NONE, 0, false, qdata);
return ns_put_rr(pkt, rrset, rrsigs, COMPR_HINT_NONE, 0, qdata);
}
/*! \brief Put additional records for given RR. */
......@@ -303,7 +303,7 @@ static int put_additional(knot_pkt_t *pkt, const knot_rrset_t *rr,
continue;
}
ret = ns_put_rr(pkt, additional, rrsigs,
hint, flags, false, qdata);
hint, flags, qdata);
if (ret != KNOT_EOK) {
break;
}
......@@ -329,7 +329,7 @@ static int follow_cname(knot_pkt_t *pkt, uint16_t rrtype, struct query_data *qda
/* Now, try to put CNAME to answer. */
uint16_t rr_count_before = pkt->rrset_count;
ret = ns_put_rr(pkt, cname_rr, rrsigs, 0, flags, true, qdata);
ret = ns_put_rr(pkt, cname_rr, rrsigs, 0, flags, qdata);
switch (ret) {
case KNOT_EOK: break;
case KNOT_ESPACE: return TRUNC;
......@@ -351,7 +351,7 @@ static int follow_cname(knot_pkt_t *pkt, uint16_t rrtype, struct query_data *qda
return ERROR;
}
cname_rr = dname_cname_synth(cname_rr, qdata->name, &pkt->mm);
ret = ns_put_rr(pkt, cname_rr, NULL, 0, KNOT_PF_FREE, true, qdata);
ret = ns_put_rr(pkt, cname_rr, NULL, 0, KNOT_PF_FREE, qdata);
switch (ret) {
case KNOT_EOK: break;
case KNOT_ESPACE: return TRUNC;
......@@ -523,7 +523,6 @@ static int solve_answer_dnssec(int state, knot_pkt_t *pkt, struct query_data *qd
/* RFC4035, section 3.1 RRSIGs for RRs in ANSWER are mandatory. */
int ret = nsec_append_rrsigs(pkt, qdata, false);
ns_reset_rrsigs(qdata);
switch(ret) {
case KNOT_ESPACE: return TRUNC;
case KNOT_EOK: return state;
......@@ -603,7 +602,6 @@ static int solve_authority_dnssec(int state, knot_pkt_t *pkt, struct query_data
/* RFC4035, section 3.1 RRSIGs for RRs in AUTHORITY are mandatory. */
if (ret == KNOT_EOK) {
ret = nsec_append_rrsigs(pkt, qdata, false);
ns_reset_rrsigs(qdata);
}
/* Evaluate final state. */
......@@ -648,7 +646,6 @@ static int solve_additional_dnssec(int state, knot_pkt_t *pkt, struct query_data
/* RFC4035, section 3.1 RRSIGs for RRs in ADDITIONAL are optional. */
int ret = nsec_append_rrsigs(pkt, qdata, true);
ns_reset_rrsigs(qdata);
switch(ret) {
case KNOT_ESPACE: return TRUNC;
case KNOT_EOK: return state;
......@@ -656,35 +653,9 @@ static int solve_additional_dnssec(int state, knot_pkt_t *pkt, struct query_data
}
}
/*! \brief Helper for internet_answer repetitive code. */
#define SOLVE_STEP(solver, state) \
state = solver(state, response, qdata); \
if (state == TRUNC) { \
return NS_PROC_DONE; \
} else if (state == ERROR) { \
return NS_PROC_FAIL; \
}
void ns_reset_rrsigs(struct query_data *qdata)
{
if (qdata == NULL) {
return;
}
node_t *n = NULL, *nxt = NULL;
WALK_LIST_DELSAFE(n, nxt, qdata->rrsigs) {
struct rrsig_info *info = (struct rrsig_info *)n;
knot_rrset_t *rrsig = info->synth_rrsig;
rem_node(n);
mm_free(qdata->mm, n);
knot_rrset_deep_free(&rrsig, true, qdata->mm);
};
init_list(&qdata->rrsigs);
}
int ns_put_rr(knot_pkt_t *pkt, const knot_rrset_t *rr,
const knot_rrset_t *rrsigs, uint16_t compr_hint,
uint32_t flags, bool expand, struct query_data *qdata)
uint32_t flags, struct query_data *qdata)
{
/* RFC3123 s.6 - empty APL is valid, ignore other empty RRs. */
if (knot_rrset_rr_count(rr) < 1 &&
......@@ -693,13 +664,18 @@ int ns_put_rr(knot_pkt_t *pkt, const knot_rrset_t *rr,
return KNOT_EMALF;
}
/* Wildcard expansion applies only for answers. */
bool expand = false;
if (pkt->current == KNOT_ANSWER) {
/* Expand if RR is wildcard & we didn't query for wildcard. */
expand = (knot_dname_is_wildcard(rr->owner) && !knot_dname_is_wildcard(qdata->name));
}
/* If we already have compressed name on the wire and compression hint,
* we can just insert RRSet and fake synthesis by using compression
* hint. */
int ret = KNOT_EOK;
bool do_expansion = expand && compr_hint == COMPR_HINT_NONE &&
knot_dname_is_wildcard(rr->owner);
if (do_expansion) {
if (compr_hint == COMPR_HINT_NONE && expand) {
ret = knot_rrset_deep_copy(rr, (knot_rrset_t **)&rr, &pkt->mm);
if (ret != KNOT_EOK) {
return KNOT_ENOMEM;
......@@ -721,17 +697,22 @@ int ns_put_rr(knot_pkt_t *pkt, const knot_rrset_t *rr,
bool inserted = (prev_count != pkt->rrset_count);
if (inserted && rrsigs && rr->type != KNOT_RRTYPE_RRSIG) {
// Get rrinfo of just inserted RR.
knot_rrinfo_t *rrinfo =
&pkt->rr_info[pkt->rrset_count - 1];
int ret = put_rrsig(rr->owner, rr->type, rrsigs, rrinfo, qdata);
if (ret != KNOT_EOK) {
return ret;
}
knot_rrinfo_t *rrinfo = &pkt->rr_info[pkt->rrset_count - 1];
ret = put_rrsig(rr->owner, rr->type, rrsigs, rrinfo, qdata);
}
return KNOT_EOK;
return ret;
}
/*! \brief Helper for internet_answer repetitive code. */
#define SOLVE_STEP(solver, state) \
state = solver(state, response, qdata); \
if (state == TRUNC) { \
return NS_PROC_DONE; \
} else if (state == ERROR) { \
return NS_PROC_FAIL; \
}
int internet_answer(knot_pkt_t *response, struct query_data *qdata)
{
dbg_ns("%s(%p, %p)\n", __func__, response, qdata);
......
......@@ -41,13 +41,6 @@ struct query_data;
*/
int internet_answer(knot_pkt_t *resp, struct query_data *qdata);
/*!
* \brief Resets RRSIG list by freeing all the data.
*
* \param qdata Query data containing the RRSIG list.
*/
void ns_reset_rrsigs(struct query_data *qdata);
/*!
* \brief Puts RRSet to packet, will store its RRSIG for later use.
*
......@@ -63,7 +56,7 @@ void ns_reset_rrsigs(struct query_data *qdata);
*/
int ns_put_rr(knot_pkt_t *pkt, const knot_rrset_t *rr,
const knot_rrset_t *rrsigs, uint16_t compr_hint,
uint32_t flags, bool expand, struct query_data *qdata);
uint32_t flags, struct query_data *qdata);
/*! \brief Require given QUERY TYPE or return error code. */
#define NS_NEED_QTYPE(qdata, qtype_want, error_rcode) \
......
......@@ -70,7 +70,7 @@ static int ns_put_nsec3_from_node(const knot_node_t *node,
int res = KNOT_EOK;
if (knot_rrset_rr_count(rrset)) {
res = ns_put_rr(resp, rrset, rrsigs, COMPR_HINT_NONE,
KNOT_PF_CHECKDUP, false, qdata);
KNOT_PF_CHECKDUP, qdata);
}
/*! \note TC bit is already set, if something went wrong. */
......@@ -309,7 +309,7 @@ static int ns_put_nsec_wildcard(const knot_zone_contents_t *zone,
if (rrset != NULL && knot_rrset_rr_count(rrset) > 0) {
// NSEC proving that there is no node with the searched name
ret = ns_put_rr(resp, rrset, rrsigs, COMPR_HINT_NONE, 0, false, qdata);
ret = ns_put_rr(resp, rrset, rrsigs, COMPR_HINT_NONE, 0, qdata);
}
return ret;
......@@ -513,7 +513,7 @@ dbg_ns_exec_verb(
}
int ret = ns_put_rr(resp, rrset, rrsigs, COMPR_HINT_NONE, 0, false, qdata);
int ret = ns_put_rr(resp, rrset, rrsigs, COMPR_HINT_NONE, 0, qdata);
if (ret != KNOT_EOK) {
dbg_ns("Failed to add NSEC for NXDOMAIN to response: %s\n",
knot_strerror(ret));
......@@ -563,7 +563,7 @@ dbg_ns_exec_verb(
// bad zone, ignore
return KNOT_EOK;
}
ret = ns_put_rr(resp, rrset, rrsigs, COMPR_HINT_NONE, 0, false, qdata);
ret = ns_put_rr(resp, rrset, rrsigs, COMPR_HINT_NONE, 0, qdata);
if (ret != KNOT_EOK) {
dbg_ns("Failed to add second NSEC for NXDOMAIN to "
"response: %s\n", knot_strerror(ret));
......@@ -715,7 +715,7 @@ static int ns_put_nsec_nsec3_nodata(const knot_node_t *node,
!= NULL) {
dbg_ns_detail("Putting the RRSet to Authority\n");
const knot_rrset_t *rrsigs = knot_node_rrset(node, KNOT_RRTYPE_RRSIG);
ret = ns_put_rr(resp, rrset, rrsigs, COMPR_HINT_NONE, 0, false, qdata);
ret = ns_put_rr(resp, rrset, rrsigs, COMPR_HINT_NONE, 0, qdata);
}
}
......@@ -770,7 +770,7 @@ int nsec_prove_dp_security(knot_pkt_t *pkt, struct query_data *qdata)
knot_rrset_t *rrset = knot_node_get_rrset(qdata->node, KNOT_RRTYPE_DS);
if (rrset != NULL) {
const knot_rrset_t *rrsigs = knot_node_get_rrset(qdata->node, KNOT_RRTYPE_RRSIG);
return ns_put_rr(pkt, rrset, rrsigs, COMPR_HINT_NONE, 0, false, qdata);
return ns_put_rr(pkt, rrset, rrsigs, COMPR_HINT_NONE, 0, qdata);
}
/* DS doesn't exist => NODATA proof. */
......@@ -788,21 +788,37 @@ int nsec_append_rrsigs(knot_pkt_t *pkt, struct query_data *qdata, bool optional)
int ret = KNOT_EOK;
uint32_t flags = (optional) ? KNOT_PF_NOTRUNC : KNOT_PF_NULL;
flags |= KNOT_PF_FREE; // Free all RRSIGs, they are synthesized
/* Append RRSIGs for section. */
node_t *n = NULL, *nxt = NULL;
WALK_LIST_DELSAFE(n, nxt, qdata->rrsigs) {
struct rrsig_info *i = (struct rrsig_info *)n;
knot_rrset_t *rrsig = i->synth_rrsig;
assert(rrsig);
uint16_t compr_hint = i->rrinfo->compress_ptr[0];
rem_node(n);
mm_free(qdata->mm, n);
struct rrsig_info *info = NULL;
WALK_LIST(info, qdata->rrsigs) {
knot_rrset_t *rrsig = info->synth_rrsig;
uint16_t compr_hint = info->rrinfo->compress_ptr[COMPR_HINT_OWNER];
ret = knot_pkt_put(pkt, compr_hint, rrsig, flags);
if (ret != KNOT_EOK) {
knot_rrset_deep_free(&rrsig, true, qdata->mm);
return ret;
break;
}
info->synth_rrsig = NULL; /* RRSIG is owned by packet now. */
};
/* Clear the list. */
nsec_clear_rrsigs(qdata);
return KNOT_EOK;
}
void nsec_clear_rrsigs(struct query_data *qdata)
{
if (qdata == NULL) {
return;
}
struct rrsig_info *info = NULL;
WALK_LIST(info, qdata->rrsigs) {
knot_rrset_t *rrsig = info->synth_rrsig;
knot_rrset_deep_free(&rrsig, true, qdata->mm);
};
ptrlist_free(&qdata->rrsigs, qdata->mm);
init_list(&qdata->rrsigs);
}
......@@ -48,6 +48,9 @@ int nsec_prove_dp_security(knot_pkt_t *pkt, struct query_data *qdata);
/*! \brief Append missing RRSIGs for current processing section. */
int nsec_append_rrsigs(knot_pkt_t *pkt, struct query_data *qdata, bool optional);
/*! \brief Clear RRSIG list. */
void nsec_clear_rrsigs(struct query_data *qdata);
#endif /* _KNOT_NSEC_PROOFS_H_ */
/*! @} */
......@@ -16,6 +16,7 @@
#include "knot/nameserver/axfr.h"
#include "knot/nameserver/ixfr.h"
#include "knot/nameserver/update.h"
#include "knot/nameserver/nsec_proofs.h"
#include "knot/server/notify.h"
#include "knot/server/server.h"
#include "knot/server/rrl.h"
......@@ -80,8 +81,7 @@ int process_query_reset(knot_process_t *ctx)
/* Free allocated data. */
knot_pkt_free(&qdata->query);
ptrlist_free(&qdata->wildcards, qdata->mm);
ns_reset_rrsigs(qdata);
ptrlist_free(&qdata->rrsigs, qdata->mm);
nsec_clear_rrsigs(qdata);
if (qdata->ext_cleanup != NULL) {
qdata->ext_cleanup(qdata);
}
......
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