Commit 4e636312 authored by Jan Kadlec's avatar Jan Kadlec

new_node: Leak fixes, cleanup, finalization.

 - tests are passing, however some work is still pending, namely storage
   of additionals for freeing.
 - removed some obsolete node API functions
parent ee6514e5
......@@ -119,13 +119,11 @@ static int shallow_copy_signature(const knot_node_t *from, knot_node_t *to)
assert(valid_nsec3_node(from));
assert(valid_nsec3_node(to));
knot_rrset_t *from_sig = knot_node_create_rrset(from, KNOT_RRTYPE_RRSIG);
if (from_sig == NULL) {
knot_rrset_t from_sig = RRSET_INIT(from, KNOT_RRTYPE_RRSIG);
if (knot_rrset_empty(&from_sig)) {
return KNOT_EOK;
}
int ret = knot_node_add_rrset(to, from_sig);
knot_rrset_free(&from_sig, NULL);
return ret;
return knot_node_add_rrset(to, &from_sig);
}
/*!
......@@ -166,9 +164,6 @@ static int copy_signatures(const knot_zone_tree_t *from, knot_zone_tree_t *to)
/*!
* \brief Custom NSEC3 tree free function.
*
* - Leaves RRSIGs, as these are only referenced (shallow copied).
* - Deep frees NSEC3 RRs, as these nodes were created.
*
*/
static void free_nsec3_tree(knot_zone_tree_t *nodes)
{
......@@ -180,7 +175,9 @@ static void free_nsec3_tree(knot_zone_tree_t *nodes)
knot_node_t *node = (knot_node_t *)*hattrie_iter_val(it);
// newly allocated NSEC3 nodes
knot_rrs_t *nsec3 = knot_node_get_rrs(node, KNOT_RRTYPE_NSEC3);
knot_rrs_t *rrsig = knot_node_get_rrs(node, KNOT_RRTYPE_RRSIG);
knot_rrs_clear(nsec3, NULL);
knot_rrs_clear(rrsig, NULL);
knot_node_free(&node);
}
......@@ -304,7 +301,7 @@ static knot_node_t *create_nsec3_node(knot_dname_t *owner,
return NULL;
}
ret = knot_node_add_rrset_no_merge(new_node, &nsec3_rrset);
ret = knot_node_add_rrset(new_node, &nsec3_rrset);
knot_rrset_clear(&nsec3_rrset, NULL);
if (ret != KNOT_EOK) {
knot_node_free(&new_node);
......
......@@ -1378,6 +1378,9 @@ int knot_zone_sign_update_soa(const knot_rrset_t *soa,
// save the result
assert(changeset->soa_from == NULL);
assert(changeset->soa_to == NULL);
changeset->soa_from = soa_from;
changeset->soa_to = soa_to;
changeset->serial_from = serial;
......
......@@ -246,6 +246,8 @@ static int zones_process_update_auth(struct query_data *qdata)
knot_zone_contents_t *old_contents = zone->contents;
ret = knot_ns_process_update(qdata->query, zone, chgsets, &qdata->rcode, new_serial);
if (ret != KNOT_EOK) {
knot_changesets_free(&chgsets);
free(msg);
return ret;
}
......@@ -345,6 +347,7 @@ static int zones_process_update_auth(struct query_data *qdata)
"\n", msg, knot_strerror(ret));
zones_store_changesets_rollback(transaction);
zones_free_merged_changesets(chgsets, sec_chs);
free(msg);
return ret;
}
......@@ -356,6 +359,7 @@ static int zones_process_update_auth(struct query_data *qdata)
msg, knot_strerror(ret));
zones_store_changesets_rollback(transaction);
zones_free_merged_changesets(chgsets, sec_chs);
free(msg);
return ret;
}
} else {
......@@ -403,6 +407,7 @@ static int zones_process_update_auth(struct query_data *qdata)
// Cleanup.
xfrin_cleanup_successful_update(chgsets);
xfrin_cleanup_successful_update(sec_chs);
// Free changesets, but not the data.
zones_free_merged_changesets(chgsets, sec_chs);
......
......@@ -710,14 +710,8 @@ void zones_free_merged_changesets(knot_changesets_t *diff_chs,
knot_changesets_free(&sec_chs);
knot_changesets_free(&diff_chs);
} else {
/*!
* Ending SOA from the merged changeset was used in
* zone (same as in DNSSEC changeset). It must not
* be freed.
*/
assert(knot_changesets_get_last(diff_chs)->serial_to ==
knot_changesets_get_last(sec_chs)->serial_to);
knot_changesets_get_last(diff_chs)->soa_to = NULL;
knot_changesets_free(&diff_chs);
/*!
......
......@@ -63,6 +63,32 @@ static void remove_rr_from_list(list_t *l, const knot_rrset_t *rr)
}
}
static void remove_header_from_list(list_t *l, const knot_rrset_t *rr)
{
knot_rr_ln_t *rr_node = NULL;
node_t *nxt = NULL;
WALK_LIST_DELSAFE(rr_node, nxt, *l) {
knot_rrset_t *rrset = rr_node->rr;
if (knot_rrset_equal(rrset, rr, KNOT_RRSET_COMPARE_HEADER)) {
knot_rrset_free(&rrset, NULL);
rem_node((node_t *)rr_node);
}
}
}
static void remove_owner_from_list(list_t *l, const knot_dname_t *owner)
{
knot_rr_ln_t *rr_node = NULL;
node_t *nxt = NULL;
WALK_LIST_DELSAFE(rr_node, nxt, *l) {
knot_rrset_t *rrset = rr_node->rr;
if (knot_dname_is_equal(rrset->owner, owner)) {
knot_rrset_free(&rrset, NULL);
rem_node((node_t *)rr_node);
}
}
}
static bool node_empty(const knot_node_t *node, const knot_changeset_t *changeset)
{
if (node == NULL) {
......@@ -508,6 +534,8 @@ static int add_rr_to_chgset(const knot_rrset_t *rr, knot_changeset_t *changeset,
return KNOT_ENOMEM;
}
rr_copy->rclass = KNOT_CLASS_IN;
if (skip_record_addition(changeset, rr_copy)) {
return KNOT_EOK;
}
......@@ -554,6 +582,8 @@ static int rem_rr_to_chgset(const knot_rrset_t *rr, knot_changeset_t *changeset,
return KNOT_ENOMEM;
}
rr_copy->rclass = KNOT_CLASS_IN;
if (skip_record_removal(changeset, rr_copy)) {
return KNOT_EOK;
}
......@@ -591,13 +621,13 @@ static int process_add_cname(const knot_node_t *node,
knot_changeset_t *changeset)
{
knot_rrset_t cname = RRSET_INIT(node, KNOT_RRTYPE_CNAME);
if (!knot_rrset_empty(&cname) && !removed_rr(changeset, &cname)) {
if (!knot_rrset_empty(&cname)) {
// If they are identical, ignore.
if (knot_rrset_equal(&cname, rr, KNOT_RRSET_COMPARE_WHOLE)) {
return KNOT_EOK;
}
int ret = rem_rr_to_chgset(rr, changeset, NULL);
int ret = rem_rr_to_chgset(&cname, changeset, NULL);
if (ret != KNOT_EOK) {
return ret;
}
......@@ -619,22 +649,15 @@ static int process_add_nsec3param(const knot_node_t *node,
{
if (node == NULL || !knot_node_rrtype_exists(node, KNOT_RRTYPE_SOA)) {
// Ignore non-apex additions
return KNOT_EOK;
return KNOT_EDENIED;
}
knot_rrset_t param = RRSET_INIT(node, KNOT_RRTYPE_NSEC3PARAM);
if (!knot_rrset_empty(&param) && !removed_rr(changeset, &param)) {
// If they are identical, ignore.
if (knot_rrset_equal(&param, rr, KNOT_RRSET_COMPARE_WHOLE)) {
return KNOT_EOK;
}
// Replace otherwise
int ret = rem_rr_to_chgset(&param, changeset, NULL);
if (ret != KNOT_EOK) {
return ret;
}
if (knot_rrset_empty(&param) || removed_rr(changeset, &param)) {
return add_rr_to_chgset(rr, changeset, NULL);
}
return add_rr_to_chgset(rr, changeset, NULL);
1 == 1; // log ignore
return KNOT_EOK;
}
static int process_rem_rr(const knot_rrset_t *rr,
......@@ -642,6 +665,12 @@ static int process_rem_rr(const knot_rrset_t *rr,
knot_changeset_t *changeset,
int *apex_ns_rem)
{
if (node == NULL) {
// Removing from node that did not exists before update
remove_rr_from_list(&changeset->add, rr);
return KNOT_EOK;
}
uint16_t type = rr->type;
const bool apex_ns = knot_node_rrtype_exists(node, KNOT_RRTYPE_SOA) &&
type == KNOT_RRTYPE_NS;
......@@ -655,7 +684,8 @@ static int process_rem_rr(const knot_rrset_t *rr,
knot_rrset_t to_modify = RRSET_INIT(node, rr->type);
if (knot_rrset_empty(&to_modify)) {
// Nothing to remove from
// No such RRSet, but check duplicates
remove_rr_from_list(&changeset->add, rr);
return KNOT_EOK;
}
......@@ -667,12 +697,12 @@ static int process_rem_rr(const knot_rrset_t *rr,
if (knot_rrset_empty(&intersection)) {
// No such RR, but check duplicates
return rem_rrset_to_chgset(rr, changeset, NULL);
remove_rr_from_list(&changeset->add, rr);
return KNOT_EOK;
}
assert(intersection.rrs.rr_count == 1);
ret = rem_rrset_to_chgset(&intersection, changeset,
apex_ns ? apex_ns_rem : NULL);
ret = rem_rr_to_chgset(&intersection, changeset,
apex_ns ? apex_ns_rem : NULL);
knot_rrs_clear(&intersection.rrs, NULL);
return ret;
}
......@@ -681,16 +711,20 @@ static int process_rem_rrset(const knot_rrset_t *rrset,
const knot_node_t *node,
knot_changeset_t *changeset)
{
// Removing all added RRs with this owner and type
remove_header_from_list(&changeset->add, rrset);
if (node == NULL) {
return KNOT_EOK;
}
uint16_t type = rrset->type;
// this should be ruled out before
if (type == KNOT_RRTYPE_SOA || knot_rrtype_is_ddns_forbidden(type)) {
// Ignore SOA and DNSSEC removals.
return KNOT_EOK;
}
if (knot_node_rrtype_exists(node, KNOT_RRTYPE_SOA)
&& type == KNOT_RRTYPE_NS) {
// if removing NS from apex, ignore
if (knot_node_rrtype_exists(node, KNOT_RRTYPE_SOA) && type == KNOT_RRTYPE_NS) {
// Ignore whole NS apex removals.
return KNOT_EOK;
}
......@@ -704,8 +738,16 @@ static int process_rem_rrset(const knot_rrset_t *rrset,
return rem_rrset_to_chgset(&to_remove, changeset, NULL);
}
static int process_rem_node(const knot_node_t *node, knot_changeset_t *changeset)
static int process_rem_node(const knot_rrset_t *rr,
const knot_node_t *node, knot_changeset_t *changeset)
{
// Remove all added records
remove_owner_from_list(&changeset->add, rr->owner);
if (node == NULL) {
return KNOT_EOK;
}
for (int i = 0; i < node->rrset_count; ++i) {
knot_rrset_t rrset = RRSET_INIT_N(node, i);
int ret = process_rem_rrset(&rrset, node, changeset);
......@@ -754,18 +796,37 @@ static bool node_contains_rr(const knot_node_t *node,
}
}
static bool adding_to_cname(const knot_node_t *node,
knot_changeset_t *changeset)
{
if (node == NULL) {
// Node did not exist before update.
return false;
}
knot_rrset_t cname = RRSET_INIT(node, KNOT_RRTYPE_CNAME);
if (knot_rrset_empty(&cname)) {
// Node did not contain CNAME before update.
return false;
}
return !removed_rr(changeset, &cname);
}
static int process_add_normal(const knot_node_t *node,
const knot_rrset_t *rr,
knot_changeset_t *changeset,
int *apex_ns_rem)
{
if (knot_node_rrtype_exists(node, KNOT_RRTYPE_CNAME)) {
// Adding RR to CNAME node. Ignore the UPDATE RR.
if (adding_to_cname(node, changeset)) {
// Adding RR to CNAME node, ignore.
return KNOT_EOK;
}
if (node && node_contains_rr(node, rr)) {
// Adding existing RR, remove from changeset if it's there.
remove_rr_from_list(&changeset->remove, rr);
// And ignore.
return KNOT_EOK;
}
......@@ -796,16 +857,12 @@ static int process_remove(const knot_rrset_t *rr,
knot_changeset_t *changeset,
int *apex_ns_rem)
{
if (node == NULL) {
return KNOT_EOK;
}
if (is_rr_removal(rr)) {
return process_rem_rr(rr, node, changeset, apex_ns_rem);
} else if (is_rrset_removal(rr)) {
return process_rem_rrset(rr, node, changeset);
} else if (is_node_removal(rr)) {
return process_rem_node(node, changeset);
return process_rem_node(rr, node, changeset);
} else {
return KNOT_EINVAL;
}
......@@ -824,30 +881,29 @@ static bool sem_check(const knot_rrset_t *rr,
const knot_zone_contents_t *zone)
{
// Check that we have not added DNAME child
const knot_dname_t *parent_dname = knot_wire_next_label(rr->owner, NULL);
const knot_node_t *parent =
knot_zone_contents_find_node(zone,
knot_wire_next_label(rr->owner, NULL));
knot_zone_contents_find_node(zone, parent_dname);
if (parent == NULL) {
return true;
}
if (knot_node_rrtype_exists(parent, KNOT_RRTYPE_DNAME)) {
// Parent has DNAME RRSet, refuse update
return false;
}
if (rr->type != KNOT_RRTYPE_DNAME || zone_node == NULL) {
return false;
return true;
}
/*
* Check that we have not created node with DNAME children. Even if the
* node did not have any records, it would exist if it had children.
*/
// Check that we have not created node with DNAME children.
if (zone_node->children > 0) {
return true;
// Updated node has children and DNAME was added, refuse update
return false;
}
return false;
return true;
}
static int knot_ddns_process_rr(const knot_rrset_t *rr,
......
......@@ -630,6 +630,10 @@ void xfrin_zone_contents_free(knot_zone_contents_t **contents)
void xfrin_cleanup_successful_update(knot_changesets_t *chgs)
{
if (chgs == NULL) {
return;
}
knot_changeset_t *change = NULL;
WALK_LIST(change, chgs->sets) {
// Delete old RR data
......@@ -736,15 +740,17 @@ void xfrin_rollback_update(knot_changesets_t *chgs,
knot_zone_contents_t *old_contents,
knot_zone_contents_t **new_contents)
{
knot_changeset_t *change = NULL;
WALK_LIST(change, chgs->sets) {
// Delete new RR data
rrs_list_clear(&change->new_data, NULL);
// Keep old RR data
ptrlist_free(&change->old_data, NULL);
init_list(&change->new_data);
if (chgs != NULL) {
knot_changeset_t *change = NULL;
WALK_LIST(change, chgs->sets) {
// Delete new RR data
rrs_list_clear(&change->new_data, NULL);
// Keep old RR data
ptrlist_free(&change->old_data, NULL);
init_list(&change->new_data);
init_list(&change->old_data);
};
};
}
xfrin_cleanup_failed_update(old_contents, new_contents);
}
......@@ -814,6 +820,7 @@ static int xfrin_apply_remove(knot_zone_contents_t *contents,
continue;
}
1 == 1; // store additional
knot_rrs_t *rrs = knot_node_get_rrs(node, rr->type);
knot_rr_t *old_data = rrs->data;
......@@ -921,7 +928,17 @@ static int xfrin_apply_replace_soa(knot_zone_contents_t *contents,
soa_rrs = knot_node_get_rrs(node, KNOT_RRTYPE_SOA);
knot_rrs_clear(soa_rrs, NULL);
return knot_rrs_copy(soa_rrs, &chset->soa_to->rrs, NULL);
ret = knot_rrs_copy(soa_rrs, &chset->soa_to->rrs, NULL);
if (ret != KNOT_EOK) {
clear_new_rrs(node, KNOT_RRTYPE_SOA);
return KNOT_ENOMEM;
}
if (ptrlist_add(new_rrs, soa_rrs->data, NULL) == NULL) {
clear_new_rrs(node, KNOT_RRTYPE_SOA);
return KNOT_ENOMEM;
}
return KNOT_EOK;
}
/*----------------------------------------------------------------------------*/
......
......@@ -72,7 +72,7 @@ static inline void knot_node_flags_clear(knot_node_t *node, uint8_t flag)
void rr_data_clear(struct rr_data *data, mm_ctx_t *mm)
{
knot_rrs_clear(&data->rrs, mm);
mm_free(mm, data->additional);
free(data->additional);
}
int rr_data_from(const knot_rrset_t *rrset, struct rr_data *data, mm_ctx_t *mm)
......@@ -83,7 +83,7 @@ int rr_data_from(const knot_rrset_t *rrset, struct rr_data *data, mm_ctx_t *mm)
}
data->type = rrset->type;
if (rrset->additional) {
data->additional = mm_alloc(mm, data->rrs.rr_count * sizeof(void *));
data->additional = malloc(data->rrs.rr_count * sizeof(void *));
if (data->additional == NULL) {
ERR_ALLOC_FAILED;
knot_rrs_clear(&data->rrs, mm);
......@@ -119,7 +119,7 @@ static knot_rrset_t *rrset_from_rr_data(const knot_node_t *n, size_t pos,
if (data.additional) {
size_t alloc_size = data.rrs.rr_count * sizeof(knot_node_t *);
rrset->additional = mm_alloc(mm, alloc_size);
rrset->additional = malloc(alloc_size);
if (rrset->additional == NULL) {
knot_rrset_free(&rrset, mm);
return NULL;
......@@ -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, const knot_rrset_t *rrset)
static int knot_node_add_rrset_no_merge(knot_node_t *node, const knot_rrset_t *rrset)
{
if (node == NULL) {
return KNOT_EINVAL;
......@@ -182,24 +182,6 @@ int knot_node_add_rrset_no_merge(knot_node_t *node, const knot_rrset_t *rrset)
return KNOT_EOK;
}
int knot_node_add_rrset_replace(knot_node_t *node, knot_rrset_t *rrset)
{
if (node == NULL) {
return KNOT_EINVAL;
}
for (uint16_t i = 0; i < node->rrset_count; ++i) {
if (node->rrs[i].type == rrset->type) {
int ret = rr_data_from(rrset, &node->rrs[i], NULL);
if (ret != KNOT_EOK) {
return ret;
}
}
}
return knot_node_add_rrset_no_merge(node, rrset);
}
int knot_node_add_rrset(knot_node_t *node, const knot_rrset_t *rrset)
{
if (node == NULL) {
......@@ -287,6 +269,8 @@ void knot_node_remove_rrset(knot_node_t *node, uint16_t type)
for (int i = 0; i < node->rrset_count; ++i) {
if (node->rrs[i].type == type) {
1 == 1; // old zone corrupted
free(node->rrs[i].additional);
memmove(node->rrs + i, node->rrs + i + 1, (node->rrset_count - i - 1) * sizeof(struct rr_data));
--node->rrset_count;
return;
......@@ -309,29 +293,6 @@ short knot_node_rrset_count(const knot_node_t *node)
/*----------------------------------------------------------------------------*/
knot_rrset_t **knot_node_create_rrsets(const knot_node_t *node)
{
if (node == NULL || node->rrset_count == 0) {
return NULL;
}
size_t rrlen = node->rrset_count * sizeof(knot_rrset_t*);
knot_rrset_t **cpy = malloc(rrlen);
if (cpy != NULL) {
for (int i = 0; i < node->rrset_count; ++i) {
cpy[i] = rrset_from_rr_data(node, i, NULL);
if (cpy[i] == NULL) {
knot_node_free_created_rrsets(node, cpy);
return NULL;
}
}
}
return cpy;
}
/*----------------------------------------------------------------------------*/
const knot_node_t *knot_node_parent(const knot_node_t *node)
{
if (node == NULL) {
......@@ -539,7 +500,7 @@ void knot_node_set_new_node(knot_node_t *node,
/*----------------------------------------------------------------------------*/
void knot_node_update_ref(knot_node_t **ref)
static void knot_node_update_ref(knot_node_t **ref)
{
if (*ref != NULL && (*ref)->new_node != NULL) {
*ref = (*ref)->new_node;
......@@ -682,19 +643,6 @@ void knot_node_free_rrsets(knot_node_t *node)
}
}
void knot_node_free_created_rrsets(const knot_node_t *node, knot_rrset_t **rrsets)
{
if (node == NULL) {
return;
}
for (uint16_t i = 0; i < node->rrset_count; ++i) {
knot_rrset_free(&rrsets[i], NULL);
}
free(rrsets);
}
/*----------------------------------------------------------------------------*/
void knot_node_free(knot_node_t **node)
......
......@@ -139,10 +139,6 @@ knot_node_t *knot_node_new(const knot_dname_t *owner, knot_node_t *parent,
*/
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, 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);
......@@ -168,17 +164,6 @@ void knot_node_remove_rrset(knot_node_t *node, uint16_t type);
*/
short knot_node_rrset_count(const knot_node_t *node);
/*!
* \brief Returns all RRSets from the node.
*
* \param node Node to get the RRSets from.
*
* \return Newly allocated array of RRSets or NULL if an error occured.
*/
knot_rrset_t **knot_node_create_rrsets(const knot_node_t *node);
int knot_node_count_rrsets(const knot_node_t *node);
/*!
* \brief Returns the parent of the node.
*
......@@ -302,18 +287,12 @@ void knot_node_set_wildcard_child(knot_node_t *node,
knot_node_t *knot_node_get_wildcard_child(const knot_node_t *node);
//const knot_node_t *knot_node_current(const knot_node_t *node);
//knot_node_t *knot_node_get_current(knot_node_t *node);
const knot_node_t *knot_node_new_node(const knot_node_t *node);
knot_node_t *knot_node_get_new_node(const knot_node_t *node);
void knot_node_set_new_node(knot_node_t *node, knot_node_t *new_node);
void knot_node_update_ref(knot_node_t **ref);
void knot_node_update_refs(knot_node_t *node);
/*!
......@@ -374,7 +353,6 @@ void knot_node_clear_empty(knot_node_t *node);
* \param node Node to be destroyed.
*/
void knot_node_free_rrsets(knot_node_t *node);
void knot_node_free_created_rrsets(const knot_node_t *node, knot_rrset_t **rrsets);
/*!
* \brief Destroys the node structure.
......
......@@ -696,14 +696,7 @@ dbg_zone_exec_detail(
// add all domain names from the RRSet to domain name table
int rc;
/*! \todo REMOVE RRSET */
if (dupl == KNOT_RRSET_DUPL_MERGE) {
rc = knot_node_add_rrset(*node, rrset);
} else {
rc = knot_node_add_rrset_no_merge(*node, rrset);
}
rc = knot_node_add_rrset(*node, rrset);
if (rc < 0) {
dbg_zone("Failed to add RRSet to node.\n");
return rc;
......
......@@ -388,8 +388,7 @@ static int knot_zone_diff_node(knot_node_t **node_ptr, void *data)
dbg_zonediff_detail("zone_diff: diff_node: Node %p is present in "
"both trees.\n", node_owner);
/* The nodes are in both trees, we have to diff each RRSet. */
knot_rrset_t **rrsets = knot_node_create_rrsets(node);
if (rrsets == NULL) {
if (node->rrset_count == 0) {
dbg_zonediff("zone_diff: Node in first tree has no RRSets.\n");
/*
* If there are no RRs in the first tree, all of the RRs
......@@ -407,79 +406,58 @@ static int knot_zone_diff_node(knot_node_t **node_ptr, void *data)
for (uint i = 0; i < knot_node_rrset_count(node); i++) {
/* Search for the RRSet in the node from the second tree. */
const knot_rrset_t *rrset = rrsets[i];
assert(rrset);
knot_rrset_t rrset = RRSET_INIT_N(node, i);
/* SOAs are handled explicitly. */
if (knot_rrset_type(rrset) == KNOT_RRTYPE_SOA) {
/* SOAs are handled explicitely. */
if (rrset.type == KNOT_RRTYPE_SOA) {
continue;
}
knot_rrset_t rrset_from_second_node = RRSET_INIT(node_in_second_tree, rrset->type);
knot_rrset_t rrset_from_second_node = RRSET_INIT(node_in_second_tree, rrset.type);
if (knot_rrset_empty(&rrset_from_second_node)) {
dbg_zonediff("zone_diff: diff_node: There is no counterpart "
"for RRSet of type %u in second tree.\n",
knot_rrset_type(rrset));
/* RRSet has been removed. Make a copy and remove. */
assert(rrset);
int ret = knot_zone_diff_changeset_remove_rrset(
param->changeset,
rrset);
&rrset);
if (ret != KNOT_EOK) {
dbg_zonediff("zone_diff: diff_node: "
"Failed to remove RRSet.\n");
free(rrsets);
return ret;
}
} else {
dbg_zonediff("zone_diff: diff_node: There is a counterpart "
"for RRSet of type %u in second tree.\n",
knot_rrset_type(rrset));
/* Diff RRSets. */
int ret = knot_zone_diff_rrsets(rrset,
int ret = knot_zone_diff_rrsets(&rrset,
&rrset_from_second_node,
param->changeset);
if (ret != KNOT_EOK) {
dbg_zonediff("zone_diff: "
"Failed to diff RRSets.\n");
free(rrsets);
return ret;
}
}
}
knot_node_free_created_rrsets(node, rrsets);
/*! \todo move to one function with the code above. */
rrsets = knot_node_create_rrsets(node_in_second_tree);
if (rrsets == NULL) {
return KNOT_EOK;
}
for (uint i = 0; i < knot_node_rrset_count(node_in_second_tree); i++) {
/* Search for the RRSet in the node from the second tree. */
const knot_rrset_t *rrset = rrsets[i];
assert(rrset);
knot_rrset_t rrset = RRSET_INIT_N(node_in_second_tree, i);
/* SOAs are handled explicitly. */
if (knot_rrset_type(rrset) == KNOT_RRTYPE_SOA) {
/* SOAs are handled explicitely. */
if (rrset.type == KNOT_RRTYPE_SOA) {
continue;
}
knot_rrset_t rrset_from_first_node = RRSET_INIT(node, rrset->type);
knot_rrset_t rrset_from_first_node = RRSET_INIT(node, rrset.type);
if (knot_rrset_empty(&rrset_from_first_node)) {
dbg_zonediff("zone_diff: diff_node: There is no counterpart "
"for RRSet of type %u in first tree.\n",
knot_rrset_type(rrset));
/* RRSet has been added. Make a copy and add. */
assert(rrset);
int ret = knot_zone_diff_changeset_add_rrset(
param->changeset,
rrset);
&rrset);
if (ret != KNOT_EOK) {
dbg_zonediff("zone_diff: diff_node: "
"Failed to add RRSet.\n");
knot_node_free_created_rrsets(node, rrsets);
return ret;
}
} else {
......@@ -488,8 +466,6 @@ static int knot_zone_diff_node(knot_node_t **node_ptr, void *data)
}
}
knot_node_free_created_rrsets(node, rrsets);
return KNOT_EOK;
}