Commit b9a6924c authored by Jan Kadlec's avatar Jan Kadlec

new_node: Removed more obsolete RRSet allocations + fixes.

parent ffaf5a1d
......@@ -50,11 +50,12 @@ static const char *get_txt_response_string(const knot_dname_t *qname)
* \param owner RR owner name.
* \param response String to be saved in RDATA. Truncated to 255 chars.
* \param mm Memory context.
* \param rrset Store here.
*
* \return Allocated RRset or NULL in case of error.
* \return KNOT_EOK
*/
static knot_rrset_t *create_txt_rrset(const knot_dname_t *owner,
const char *response, mm_ctx_t *mm)
static int create_txt_rrset(knot_rrset_t *rrset, const knot_dname_t *owner,
const char *response, mm_ctx_t *mm)
{
// truncate response to one TXT label
size_t response_len = strlen(response);
......@@ -62,27 +63,23 @@ static knot_rrset_t *create_txt_rrset(const knot_dname_t *owner,
response_len = KNOT_DNAME_MAXLEN;
}
knot_dname_t *rowner = knot_dname_copy(owner, NULL);
knot_dname_t *rowner = knot_dname_copy(owner, mm);
if (!rowner) {
return NULL;
}
knot_rrset_t *rrset;
rrset = knot_rrset_new(rowner, KNOT_RRTYPE_TXT, KNOT_CLASS_CH, mm);
if (!rrset) {
return NULL;
return KNOT_ENOMEM;
}
knot_rrset_init(rrset, rowner, KNOT_RRTYPE_TXT, KNOT_CLASS_CH);
uint8_t *rdata = knot_rrset_create_rr(rrset, response_len + 1, 0, mm);
if (!rdata) {
knot_rrset_free(&rrset, mm);
return NULL;
knot_dname_free(&rrset->owner, mm);
knot_rrs_clear(&rrset->rrs, mm);
return KNOT_ENOMEM;
}
rdata[0] = response_len;
memcpy(&rdata[1], response, response_len);
return rrset;
return KNOT_EOK;
}
/*!
......@@ -99,15 +96,15 @@ static int answer_txt(knot_pkt_t *response)
return KNOT_RCODE_REFUSED;
}
knot_rrset_t *rrset = create_txt_rrset(qname, response_str,
&response->mm);
if (!rrset) {
knot_rrset_t rrset;
int ret = create_txt_rrset(&rrset, qname, response_str, &response->mm);
if (ret != KNOT_EOK) {
return KNOT_RCODE_SERVFAIL;
}
int result = knot_pkt_put(response, 0, rrset, KNOT_PF_FREE);
int result = knot_pkt_put(response, 0, &rrset, KNOT_PF_FREE);
if (result != KNOT_EOK) {
knot_rrset_free(&rrset, &response->mm);
knot_rrset_clear(&rrset, &response->mm);
return KNOT_RCODE_SERVFAIL;
}
......
......@@ -246,18 +246,15 @@ static int put_authority_soa(knot_pkt_t *pkt, struct query_data *qdata,
uint32_t flags = KNOT_PF_NOTRUNC;
uint32_t min = knot_rrs_soa_minimum(&soa_rrset.rrs);
if (min < knot_rrset_rr_ttl(&soa_rrset, 0)) {
ret = knot_rrs_copy(&soa_rrset.rrs, &soa_rrset.rrs, &pkt->mm);
knot_rrset_t copy;
ret = knot_rrset_copy_int(&copy, &soa_rrset, &pkt->mm);
if (ret != KNOT_EOK) {
return ret;
}
knot_rrset_rr_set_ttl(&soa_rrset, 0, min);
soa_rrset.owner = knot_dname_copy(soa_rrset.owner, &pkt->mm);
if (soa_rrset.owner == NULL) {
knot_rrs_clear(&soa_rrset.rrs, &pkt->mm);
return KNOT_ENOMEM;
}
flags |= KNOT_PF_FREE;
soa_rrset = copy;
}
ret = ns_put_rr(pkt, &soa_rrset, &rrsigs, COMPR_HINT_NONE, flags, qdata);
......@@ -695,11 +692,20 @@ int ns_put_rr(knot_pkt_t *pkt, knot_rrset_t *rr,
int ret = KNOT_EOK;
if (compr_hint == COMPR_HINT_NONE && expand) {
rr->owner = (knot_dname_t *)qdata->name;
knot_rrset_t copy;
int ret = knot_rrset_copy_int(&copy, rr, &pkt->mm);
if (ret != KNOT_EOK) {
return ret;
}
flags |= KNOT_PF_FREE;
*rr = copy;
}
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);
return ret;
}
......
......@@ -223,15 +223,14 @@ static int xfrin_check_tsig(knot_pkt_t *packet, knot_ns_xfr_t *xfr,
/*----------------------------------------------------------------------------*/
static int xfrin_take_rr(const knot_pktsection_t *answer, knot_rrset_t **rr, uint16_t *cur)
static int xfrin_take_rr(const knot_pktsection_t *answer, const knot_rrset_t **rr, uint16_t *cur)
{
int ret = KNOT_EOK;
if (*cur < answer->count) {
ret = knot_rrset_copy(&answer->rr[*cur], rr, NULL);
*rr = &answer->rr[*cur];
*cur += 1;
} else {
*rr = NULL;
ret = KNOT_EOK;
}
return ret;
......@@ -246,7 +245,7 @@ int xfrin_process_axfr_packet(knot_pkt_t *pkt, knot_ns_xfr_t *xfr, knot_zone_con
}
uint16_t rr_id = 0;
knot_rrset_t *rr = NULL;
const knot_rrset_t *rr = NULL;
const knot_pktsection_t *answer = knot_pkt_section(pkt, KNOT_ANSWER);
int ret = xfrin_take_rr(answer, &rr, &rr_id);
......@@ -257,7 +256,6 @@ int xfrin_process_axfr_packet(knot_pkt_t *pkt, knot_ns_xfr_t *xfr, knot_zone_con
}
*zone = knot_zone_contents_new(rr->owner);
if (*zone == NULL) {
knot_rrset_free(&rr, NULL);
return KNOT_ENOMEM;
}
xfr->packet_nr = 0;
......@@ -274,7 +272,6 @@ int xfrin_process_axfr_packet(knot_pkt_t *pkt, knot_ns_xfr_t *xfr, knot_zone_con
knot_node_rrtype_exists(zc.z->apex, KNOT_RRTYPE_SOA)) {
// Last SOA, last message, check TSIG.
ret = xfrin_check_tsig(pkt, xfr, 1);
knot_rrset_free(&rr, NULL);
if (ret != KNOT_EOK) {
return ret;
}
......@@ -307,7 +304,7 @@ int xfrin_process_ixfr_packet(knot_pkt_t *pkt, knot_ns_xfr_t *xfr)
}
uint16_t rr_id = 0;
knot_rrset_t *rr = NULL;
const knot_rrset_t *rr = NULL;
const knot_pktsection_t *answer = knot_pkt_section(pkt, KNOT_ANSWER);
int ret = xfrin_take_rr(answer, &rr, &rr_id);
if (ret != KNOT_EOK) {
......@@ -326,20 +323,22 @@ int xfrin_process_ixfr_packet(knot_pkt_t *pkt, knot_ns_xfr_t *xfr)
ret = knot_changesets_init(chs);
if (ret != KNOT_EOK) {
knot_rrset_free(&rr, NULL);
return ret;
}
// the first RR must be a SOA
if (knot_rrset_type(rr) != KNOT_RRTYPE_SOA) {
dbg_xfrin("First RR is not a SOA RR!\n");
knot_rrset_free(&rr, NULL);
ret = KNOT_EMALF;
goto cleanup;
}
// just store the first SOA for later use
(*chs)->first_soa = rr;
(*chs)->first_soa = knot_rrset_cpy(rr, NULL);
if ((*chs)->first_soa == NULL) {
ret = KNOT_ENOMEM;
goto cleanup;
}
state = -1;
dbg_xfrin_verb("First SOA of IXFR saved, state set to -1.\n");
......@@ -367,7 +366,6 @@ int xfrin_process_ixfr_packet(knot_pkt_t *pkt, knot_ns_xfr_t *xfr)
dbg_xfrin("Response containing only SOA,\n");
return XFRIN_RES_SOA_ONLY;
} else if (knot_rrset_type(rr) != KNOT_RRTYPE_SOA) {
knot_rrset_free(&rr, NULL);
dbg_xfrin("Fallback to AXFR.\n");
ret = XFRIN_RES_FALLBACK;
return ret;
......@@ -375,7 +373,6 @@ int xfrin_process_ixfr_packet(knot_pkt_t *pkt, knot_ns_xfr_t *xfr)
} else {
if ((*chs)->first_soa == NULL) {
dbg_xfrin("Changesets don't contain SOA first!\n");
knot_rrset_free(&rr, NULL);
ret = KNOT_EINVAL;
goto cleanup;
}
......@@ -423,7 +420,6 @@ int xfrin_process_ixfr_packet(knot_pkt_t *pkt, knot_ns_xfr_t *xfr)
dbg_xfrin_detail("State is not -1, deciding...\n");
// there should be at least one started changeset right now
if (EMPTY_LIST((*chs)->sets)) {
knot_rrset_free(&rr, NULL);
ret = KNOT_EMALF;
goto cleanup;
}
......@@ -453,7 +449,6 @@ dbg_xfrin_exec_verb(
if (!knot_dname_is_sub(rr->owner, xfr->zone->name) &&
!knot_dname_is_equal(rr->owner, xfr->zone->name)) {
// out-of-zone domain
knot_rrset_free(&rr, NULL);
// take next RR
ret = xfrin_take_rr(answer, &rr, &rr_id);
continue;
......@@ -469,7 +464,6 @@ dbg_xfrin_exec_verb(
dbg_xfrin("First RR is not a SOA RR!\n");
dbg_xfrin_verb("RR type: %u\n",
knot_rrset_type(rr));
knot_rrset_free(&rr, NULL);
ret = KNOT_EMALF;
goto cleanup;
}
......@@ -483,8 +477,6 @@ dbg_xfrin_exec_verb(
ret = xfrin_check_tsig(pkt, xfr, 1);
// last SOA, discard and end
knot_rrset_free(&rr, NULL);
/*! \note [TSIG] If TSIG validates, consider
* transfer complete. */
if (ret == KNOT_EOK) {
......@@ -499,16 +491,20 @@ dbg_xfrin_exec_verb(
ret = KNOT_ESPACE;
if (ret != KNOT_EOK) {
knot_rrset_free(&rr, NULL);
goto cleanup;
}
chset = knot_changesets_create_changeset(*chs);
if (chset == NULL) {
knot_rrset_free(&rr, NULL);
goto cleanup;
}
knot_changeset_add_soa(chset, rr, KNOT_CHANGESET_REMOVE);
knot_rrset_t *soa = knot_rrset_cpy(rr, NULL);
if (soa == NULL) {
ret = KNOT_ENOMEM;
goto cleanup;
}
knot_changeset_add_soa(chset, soa, KNOT_CHANGESET_REMOVE);
// change state to REMOVE
state = KNOT_CHANGESET_REMOVE;
......@@ -520,17 +516,25 @@ dbg_xfrin_exec_verb(
if (knot_rrset_type(rr) == KNOT_RRTYPE_SOA) {
// we should not be here if soa_from is not set
assert(chset->soa_from != NULL);
knot_changeset_add_soa(chset, rr, KNOT_CHANGESET_ADD);
knot_rrset_t *soa = knot_rrset_cpy(rr, NULL);
if (soa == NULL) {
ret = KNOT_ENOMEM;
goto cleanup;
}
knot_changeset_add_soa(chset, soa, KNOT_CHANGESET_ADD);
state = KNOT_CHANGESET_ADD;
} else {
// just add the RR to the REMOVE part and
// continue
ret = knot_changeset_add_rr(chset, rr,
knot_rrset_t *cpy = knot_rrset_cpy(rr, NULL);
if (cpy == NULL) {
ret = KNOT_ENOMEM;
goto cleanup;
}
ret = knot_changeset_add_rr(chset, cpy,
KNOT_CHANGESET_REMOVE);
if (ret != KNOT_EOK) {
knot_rrset_free(&rr, NULL);
goto cleanup;
}
}
......@@ -546,12 +550,15 @@ dbg_xfrin_exec_verb(
state = -1;
continue;
} else {
// just add the RR to the ADD part and continue
ret = knot_changeset_add_rr(chset, rr,
knot_rrset_t *cpy = knot_rrset_cpy(rr, NULL);
if (cpy == NULL) {
ret = KNOT_ENOMEM;
goto cleanup;
}
ret = knot_changeset_add_rr(chset, cpy,
KNOT_CHANGESET_ADD);
if (ret != KNOT_EOK) {
knot_rrset_free(&rr, NULL);
goto cleanup;
}
}
......
......@@ -161,7 +161,7 @@ knot_node_t *knot_node_new(const knot_dname_t *owner, knot_node_t *parent,
return ret;
}
int knot_node_add_rrset_no_merge(knot_node_t *node, knot_rrset_t *rrset)
int knot_node_add_rrset_no_merge(knot_node_t *node, const knot_rrset_t *rrset)
{
if (node == NULL) {
return KNOT_EINVAL;
......@@ -200,7 +200,7 @@ int knot_node_add_rrset_replace(knot_node_t *node, knot_rrset_t *rrset)
return knot_node_add_rrset_no_merge(node, rrset);
}
int knot_node_add_rrset(knot_node_t *node, knot_rrset_t *rrset)
int knot_node_add_rrset(knot_node_t *node, const knot_rrset_t *rrset)
{
if (node == NULL) {
return KNOT_EINVAL;
......
......@@ -137,11 +137,11 @@ knot_node_t *knot_node_new(const knot_dname_t *owner, knot_node_t *parent,
* \retval KNOT_EOK on success.
* \retval KNOT_ERROR if the RRSet could not be inserted.
*/
int knot_node_add_rrset(knot_node_t *node, knot_rrset_t *rrset);
int knot_node_add_rrset(knot_node_t *node, const knot_rrset_t *rrset);
int knot_node_add_rrset_replace(knot_node_t *node, knot_rrset_t *rrset);
int knot_node_add_rrset_no_merge(knot_node_t *node, knot_rrset_t *rrset);
int knot_node_add_rrset_no_merge(knot_node_t *node, const knot_rrset_t *rrset);
const knot_rrs_t *knot_node_rrs(const knot_node_t *node, uint16_t type);
knot_rrs_t *knot_node_get_rrs(const knot_node_t *node, uint16_t type);
......
......@@ -615,7 +615,8 @@ int knot_zone_contents_create_node(knot_zone_contents_t *contents,
/*----------------------------------------------------------------------------*/
static int insert_rr(knot_zone_contents_t *z, knot_rrset_t *rr, knot_node_t **n,
static int insert_rr(knot_zone_contents_t *z,
const knot_rrset_t *rr, knot_node_t **n,
bool nsec3)
{
if (z == NULL || knot_rrset_empty(rr) || n == NULL) {
......@@ -655,7 +656,7 @@ static bool to_nsec3_tree(const knot_rrset_t *rr)
}
int knot_zone_contents_add_rr(knot_zone_contents_t *z,
knot_rrset_t *rr, knot_node_t **n)
const knot_rrset_t *rr, knot_node_t **n)
{
return insert_rr(z, rr, n, to_nsec3_tree(rr));
}
......
......@@ -127,7 +127,7 @@ int knot_zone_contents_create_node(knot_zone_contents_t *contents,
knot_node_t **node);
int knot_zone_contents_add_rr(knot_zone_contents_t *z,
knot_rrset_t *rr, knot_node_t **n);
const knot_rrset_t *rr, knot_node_t **n);
/*!
* \brief Adds a RRSet to the given zone.
......
......@@ -77,14 +77,13 @@ static bool handle_err(zcreator_t *zc,
}
}
int zcreator_step(zcreator_t *zc, knot_rrset_t *rr)
int zcreator_step(zcreator_t *zc, const knot_rrset_t *rr)
{
assert(zc && rr);
if (rr->type == KNOT_RRTYPE_SOA &&
knot_node_rrtype_exists(zc->z->apex, KNOT_RRTYPE_SOA)) {
// Ignore extra SOA
knot_rrset_free(&rr, NULL);
return KNOT_EOK;
}
......
......@@ -80,7 +80,7 @@ knot_zone_contents_t *zonefile_load(zloader_t *loader);
*/
void zonefile_close(zloader_t *loader);
int zcreator_step(zcreator_t *zl, knot_rrset_t *rr);
int zcreator_step(zcreator_t *zl, const knot_rrset_t *rr);
void process_error(const zs_scanner_t *scanner);
......
......@@ -698,6 +698,7 @@ static int knot_pkt_rr_from_wire(const uint8_t *wire, size_t *pos,
rrset->owner = owner;
rrset->type = type;
rrset->rclass = rclass;
rrset->additional = NULL;
*pos += KNOT_RR_HEADER_SIZE;
......@@ -713,6 +714,7 @@ static int knot_pkt_rr_from_wire(const uint8_t *wire, size_t *pos,
// parse RDATA
/*! \todo Merge with add_rdata_to_rr in zcompile, should be a rrset func
* probably. */
knot_rrs_init(&rrset->rrs);
int ret = knot_rrset_rdata_from_wire_one(rrset, wire, pos, size, ttl,
rdlength, mm);
if (ret != KNOT_EOK) {
......@@ -745,7 +747,6 @@ int knot_pkt_parse_rr(knot_pkt_t *pkt, unsigned flags)
/* Parse wire format. */
size_t rr_size = pkt->parsed;
knot_rrset_t *rr = &pkt->rr[pkt->rrset_count];
knot_rrs_init(&rr->rrs);
ret = knot_pkt_rr_from_wire(pkt->wire, &pkt->parsed, pkt->max_size,
&pkt->mm, rr);
if (ret != KNOT_EOK) {
......@@ -761,8 +762,7 @@ int knot_pkt_parse_rr(knot_pkt_t *pkt, unsigned flags)
return KNOT_EOK;
}
/* Append to RR list. */
pkt->rr[pkt->rrset_count] = *rr;
/* Update packet RRSet count. */
++pkt->rrset_count;
/* Update section RRSet count. */
......
......@@ -418,9 +418,16 @@ static int rrset_deserialize_rr(knot_rrset_t *rrset,
return KNOT_EOK;
}
int knot_rrset_remove_rdata_pos(knot_rrset_t *rrset, size_t pos, mm_ctx_t *mm)
void knot_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner, uint16_t type,
uint16_t rclass)
{
return knot_rrs_remove_rr_at_pos(&rrset->rrs, pos, mm);
if (rrset) {
rrset->owner = owner;
rrset->type = type;
rrset->rclass = rclass;
knot_rrs_init(&rrset->rrs);
rrset->additional = NULL;
}
}
knot_rrset_t *knot_rrset_new(knot_dname_t *owner, uint16_t type,
......@@ -837,6 +844,15 @@ void knot_rrset_free(knot_rrset_t **rrset, mm_ctx_t *mm)
*rrset = NULL;
}
void knot_rrset_clear(knot_rrset_t *rrset, mm_ctx_t *mm)
{
if (rrset == NULL) {
return;
}
rrset_deep_free_content(rrset, mm);
}
static int knot_rrset_add_rr_n(knot_rrset_t *rrset, const knot_rrset_t *rr,
size_t pos, mm_ctx_t *mm)
{
......@@ -1177,7 +1193,7 @@ static int knot_rrset_remove_rr(knot_rrset_t *rrset,
dbg_rrset_detail("rr: remove_rr: Counter position found=%zu\n",
pos_to_remove);
assert(pos_to_remove < knot_rrset_rr_count(rrset));
ret = knot_rrset_remove_rdata_pos(rrset, pos_to_remove, mm);
ret = knot_rrs_remove_rr_at_pos(&rrset->rrs, pos_to_remove, mm);
if (ret != KNOT_EOK) {
dbg_rrset("Cannot remove RDATA from RRSet (%s).\n",
knot_strerror(ret));
......@@ -1320,4 +1336,34 @@ bool knot_rrset_empty(const knot_rrset_t *rrset)
return rr_count == 0;
}
int knot_rrset_copy_int(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) {
return KNOT_ENOMEM;
}
knot_rrs_init(&dst->rrs);
int ret = knot_rrs_copy(&dst->rrs, &src->rrs, mm);
if (ret != KNOT_EOK) {
knot_dname_free(&dst->owner, mm);
return ret;
}
return KNOT_EOK;
}
knot_rrset_t *knot_rrset_cpy(const knot_rrset_t *src, mm_ctx_t *mm)
{
knot_rrset_t *dst = NULL;
int ret = knot_rrset_copy(src, &dst, mm);
return ret == KNOT_EOK ? dst : NULL;
}
......@@ -86,6 +86,10 @@ knot_rrset_t *knot_rrset_new(knot_dname_t *owner, uint16_t type,
uint16_t rclass,
mm_ctx_t *mm);
void knot_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner, uint16_t type,
uint16_t rclass);
void knot_rrset_clear(knot_rrset_t *rrset, mm_ctx_t *mm);
/*!
* \brief Creates a new RRSet according to given template RRSet.
*
......@@ -426,5 +430,7 @@ int knot_rrset_synth_rrsig(const knot_dname_t *owner, uint16_t type,
knot_rrset_t **out_sig, mm_ctx_t *mm);
bool knot_rrset_empty(const knot_rrset_t *rrset);
int knot_rrset_copy_int(knot_rrset_t *dst, const knot_rrset_t *src, mm_ctx_t *mm);
knot_rrset_t *knot_rrset_cpy(const knot_rrset_t *src, mm_ctx_t *mm);
/*! @} */
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