Commit 3ef48522 authored by Jan Kadlec's avatar Jan Kadlec

new_node: Reuse RRSet code in internet.c/pkt.c + fixes.

- ns_put_rr function now accepts consts rrsets only
- fixed wrong TTL set in SOA copy
- removed a function move_rrset, to be replaced with RRSet function
  later.
parent c0f08b62
......@@ -40,28 +40,26 @@ static int wildcard_visit(struct query_data *qdata, const knot_node_t *node, con
return KNOT_EOK;
}
/*! \brief Moves data from 'src' to 'dst', owner and RRs are deep copied. */
int move_rrset(knot_rrset_t *dst, const knot_rrset_t *src, mm_ctx_t *mm)
{
if (dst == NULL || src == NULL) {
return KNOT_EINVAL;
}
dst->type = src->type;
dst->additional = src->additional;
dst->rclass = src->rclass;
dst->owner = knot_dname_copy(src->owner, mm);
if (dst->owner == NULL) {
knot_dname_t *owner_cpy = knot_dname_copy(src->owner, mm);
if (owner_cpy == NULL) {
return KNOT_ENOMEM;
}
knot_rrs_init(&dst->rrs);
knot_rrset_init(dst, owner_cpy, src->type, src->rclass);
int ret = knot_rrs_copy(&dst->rrs, &src->rrs, mm);
if (ret != KNOT_EOK) {
knot_dname_free(&dst->owner, mm);
return ret;
}
dst->additional = src->additional;
return KNOT_EOK;
}
......@@ -76,13 +74,11 @@ static int dname_cname_synth(const knot_rrset_t *dname_rr,
}
dbg_ns("%s(%p, %p)\n", __func__, dname_rr, qname);
cname_rrset->owner = knot_dname_copy(qname, mm);
if (cname_rrset->owner == NULL) {
knot_dname_t *owner_copy = knot_dname_copy(qname, mm);
if (owner_copy == NULL) {
return KNOT_ENOMEM;
}
cname_rrset->type = KNOT_RRTYPE_CNAME;
cname_rrset->rclass = KNOT_CLASS_IN;
knot_rrs_init(&cname_rrset->rrs);
knot_rrset_init(cname_rrset, owner_copy, KNOT_RRTYPE_CNAME, dname_rr->type);
/* Replace last labels of qname with DNAME. */
const knot_dname_t *dname_wire = dname_rr->owner;
......@@ -132,9 +128,9 @@ static int put_rrsig(const knot_dname_t *sig_owner, uint16_t type,
knot_rrinfo_t *rrinfo,
struct query_data *qdata)
{
knot_rrset_t synth_sig;
knot_rrs_init(&synth_sig.rrs);
int ret = knot_synth_rrsig(type, &rrsigs->rrs, &synth_sig.rrs, qdata->mm);
knot_rrs_t synth_rrs;
knot_rrs_init(&synth_rrs);
int ret = knot_synth_rrsig(type, &rrsigs->rrs, &synth_rrs, qdata->mm);
if (ret == KNOT_ENOENT) {
// No signature
return KNOT_EOK;
......@@ -142,21 +138,17 @@ static int put_rrsig(const knot_dname_t *sig_owner, uint16_t type,
if (ret != KNOT_EOK) {
return ret;
}
synth_sig.owner = knot_dname_copy(sig_owner, qdata->mm);
if (synth_sig.owner == NULL) {
knot_rrs_clear(&synth_sig.rrs, qdata->mm);
}
synth_sig.type = KNOT_RRTYPE_RRSIG;
synth_sig.rclass = KNOT_CLASS_IN;
synth_sig.additional = NULL;
knot_dname_t *owner_copy = knot_dname_copy(sig_owner, qdata->mm);
knot_rrset_t synth_rrsig;
knot_rrset_init(&synth_rrsig, owner_copy, rrsigs->type, rrsigs->rclass);
synth_rrsig.rrs = synth_rrs;
struct rrsig_info *info = mm_alloc(qdata->mm, sizeof(struct rrsig_info));
if (info == NULL) {
ERR_ALLOC_FAILED;
knot_dname_free(&synth_sig.owner, qdata->mm);
knot_rrs_clear(&synth_sig.rrs, qdata->mm);
knot_rrset_clear(&synth_rrsig, qdata->mm);
return KNOT_ENOMEM;
}
info->synth_rrsig = synth_sig;
info->synth_rrsig = synth_rrsig;
info->rrinfo = rrinfo;
add_tail(&qdata->rrsigs, &info->n);
......@@ -168,7 +160,8 @@ static int put_rrsig(const knot_dname_t *sig_owner, uint16_t type,
*/
static int put_answer(knot_pkt_t *pkt, uint16_t type, struct query_data *qdata)
{
knot_rrset_t rrset = { 0 };
knot_rrset_t rrset;
knot_rrset_init_empty(&rrset);
/* Wildcard expansion or exact match, either way RRSet owner is
* is QNAME. We can fake name synthesis by setting compression hint to
......@@ -255,11 +248,10 @@ static int put_authority_soa(knot_pkt_t *pkt, struct query_data *qdata,
uint32_t min = knot_rrs_soa_minimum(&soa_rrset.rrs);
if (min < knot_rrset_rr_ttl(&soa_rrset, 0)) {
knot_rrset_t copy;
ret = move_rrset(&copy, &soa_rrset, &pkt->mm);
if (ret != KNOT_EOK) {
return ret;
}
knot_rrset_rr_set_ttl(&soa_rrset, 0, min);
knot_dname_t *dname_cpy = knot_dname_copy(soa_rrset.owner, &pkt->mm);
knot_rrset_init(&copy, dname_cpy, soa_rrset.type, soa_rrset.rclass);
knot_rrs_copy(&copy.rrs, &soa_rrset.rrs, &pkt->mm);
knot_rrset_rr_set_ttl(&copy, 0, min);
flags |= KNOT_PF_FREE;
soa_rrset = copy;
......@@ -267,8 +259,7 @@ static int put_authority_soa(knot_pkt_t *pkt, struct query_data *qdata,
ret = ns_put_rr(pkt, &soa_rrset, &rrsigs, COMPR_HINT_NONE, flags, qdata);
if (ret != KNOT_EOK && (flags & KNOT_PF_FREE)) {
knot_dname_free(&soa_rrset.owner, &pkt->mm);
knot_rrs_clear(&soa_rrset.rrs, &pkt->mm);
knot_rrset_clear(&soa_rrset, &pkt->mm);
}
return ret;
......@@ -675,13 +666,11 @@ static int solve_additional_dnssec(int state, knot_pkt_t *pkt, struct query_data
}
}
int ns_put_rr(knot_pkt_t *pkt, knot_rrset_t *rr,
knot_rrset_t *rrsigs, uint16_t compr_hint,
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, struct query_data *qdata)
{
/* RFC3123 s.6 - empty APL is valid, ignore other empty RRs. */
if (knot_rrset_rr_count(rr) < 1 &&
rr->type != KNOT_RRTYPE_APL) {
if (knot_rrset_rr_count(rr) < 1) {
dbg_ns("%s: refusing to put empty RR of type %u\n", __func__, rr->type);
return KNOT_EMALF;
}
......@@ -697,26 +686,25 @@ int ns_put_rr(knot_pkt_t *pkt, knot_rrset_t *rr,
* we can just insert RRSet and fake synthesis by using compression
* hint. */
int ret = KNOT_EOK;
knot_rrset_t to_add;
if (compr_hint == COMPR_HINT_NONE && expand) {
rr->owner = (knot_dname_t *)qdata->name;
knot_rrset_t copy;
int ret = move_rrset(&copy, rr, &pkt->mm);
if (ret != KNOT_EOK) {
return ret;
}
knot_dname_t *qname_cpy = knot_dname_copy(qdata->name, &pkt->mm);
knot_rrset_init(&to_add, qname_cpy, rr->type, rr->rclass);
knot_rrs_copy(&to_add.rrs, &rr->rrs, &pkt->mm);
to_add.additional = rr->additional;
flags |= KNOT_PF_FREE;
*rr = copy;
} else {
to_add = *rr;
}
uint16_t prev_count = pkt->rrset_count;
ret = knot_pkt_put(pkt, compr_hint, rr, flags);
if (ret != KNOT_EOK) {
knot_dname_free(&rr->owner, &pkt->mm);
knot_rrs_clear(&rr->rrs, &pkt->mm);
ret = knot_pkt_put(pkt, compr_hint, &to_add, flags);
if (ret != KNOT_EOK && (flags & KNOT_PF_FREE)) {
knot_rrset_clear(&to_add, &pkt->mm);
return ret;
}
bool inserted = (prev_count != pkt->rrset_count);
const bool inserted = (prev_count != pkt->rrset_count);
if (inserted &&
!knot_rrset_empty(rrsigs) && rr->type != KNOT_RRTYPE_RRSIG) {
// Get rrinfo of just inserted RR.
......
......@@ -74,8 +74,8 @@ int internet_query_plan(struct query_plan *plan);
*
* \return KNOT_E*
*/
int ns_put_rr(knot_pkt_t *pkt, knot_rrset_t *rr,
knot_rrset_t *rrsigs, uint16_t compr_hint,
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, struct query_data *qdata);
/*! \brief Require given QUERY TYPE or return error code. */
......
......@@ -26,12 +26,6 @@
#include "libknot/tsig.h"
#include "libknot/tsig-op.h"
static void clear_pkt_rr(knot_rrset_t *rr, mm_ctx_t *mm)
{
knot_dname_free(&rr->owner, mm);
knot_rrs_clear(&rr->rrs, mm);
}
/*! \brief Scan packet for RRSet existence. */
static bool pkt_contains(const knot_pkt_t *packet,
const knot_rrset_t *rrset)
......@@ -58,7 +52,7 @@ static void pkt_free_data(knot_pkt_t *pkt)
/* Free RRSets if applicable. */
for (uint16_t i = 0; i < pkt->rrset_count; ++i) {
if (pkt->rr_info[i].flags & KNOT_PF_FREE) {
clear_pkt_rr(&pkt->rr[i], &pkt->mm);
knot_rrset_clear(&pkt->rr[i], &pkt->mm);
}
}
......@@ -673,7 +667,7 @@ static int knot_pkt_rr_from_wire(const uint8_t *wire, size_t *pos,
if (size - *pos < rdlength) {
dbg_packet("%s: not enough data to parse RDATA\n", __func__);
clear_pkt_rr(rrset, mm);
knot_rrset_clear(rrset, mm);
return KNOT_EMALF;
}
......@@ -685,7 +679,7 @@ static int knot_pkt_rr_from_wire(const uint8_t *wire, size_t *pos,
rdlength, mm);
if (ret != KNOT_EOK) {
dbg_packet("%s: couldn't parse RDATA (%d)\n", __func__, ret);
clear_pkt_rr(rrset, mm);
knot_rrset_clear(rrset, mm);
return ret;
}
......
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