Commit 63384e60 authored by Jan Kadlec's avatar Jan Kadlec

new_node: Do not reuse old pointers in zone copy.

 - node->new_node is thus obosolete.
 - since hattrie_dup made almost a full copy anyway, it's feasible to
   let the zone contents recreate the zone anew, with proper pointers.
(new node was used to set only parent pointer, others were reset anyway
in adjusting, all this will die in the new zone API, but at least like
this it's easier to maintain.)
parent f0c85d1e
...@@ -317,6 +317,10 @@ hattrie_t* hattrie_dup(const hattrie_t* T, value_t (*nval)(value_t)) ...@@ -317,6 +317,10 @@ hattrie_t* hattrie_dup(const hattrie_t* T, value_t (*nval)(value_t))
{ {
hattrie_t *N = hattrie_create_n(T->bsize, &T->mm); hattrie_t *N = hattrie_create_n(T->bsize, &T->mm);
if (nval == NULL) {
return N;
}
/* assignment */ /* assignment */
if (!nval) nval = hattrie_setval; if (!nval) nval = hattrie_setval;
......
...@@ -280,7 +280,7 @@ static int zones_process_update_auth(struct query_data *qdata) ...@@ -280,7 +280,7 @@ static int zones_process_update_auth(struct query_data *qdata)
sec_chs = knot_changesets_create(); sec_chs = knot_changesets_create();
sec_ch = knot_changesets_create_changeset(sec_chs); sec_ch = knot_changesets_create_changeset(sec_chs);
if (sec_chs == NULL || sec_ch == NULL) { if (sec_chs == NULL || sec_ch == NULL) {
xfrin_rollback_update(chgsets, old_contents, &new_contents); xfrin_rollback_update(chgsets, &new_contents);
knot_changesets_free(&chgsets); knot_changesets_free(&chgsets);
free(msg); free(msg);
return KNOT_ENOMEM; return KNOT_ENOMEM;
...@@ -313,7 +313,7 @@ static int zones_process_update_auth(struct query_data *qdata) ...@@ -313,7 +313,7 @@ static int zones_process_update_auth(struct query_data *qdata)
log_zone_error("%s: Failed to sign incoming update (%s)" log_zone_error("%s: Failed to sign incoming update (%s)"
"\n", msg, knot_strerror(ret)); "\n", msg, knot_strerror(ret));
1 == 1; // TODO: rollback 1 == 1; // TODO: rollback
xfrin_rollback_update(chgsets, old_contents, &new_contents); xfrin_rollback_update(chgsets, &new_contents);
knot_changesets_free(&chgsets); knot_changesets_free(&chgsets);
knot_changesets_free(&sec_chs); knot_changesets_free(&sec_chs);
free(msg); free(msg);
...@@ -328,7 +328,7 @@ static int zones_process_update_auth(struct query_data *qdata) ...@@ -328,7 +328,7 @@ static int zones_process_update_auth(struct query_data *qdata)
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
log_zone_error("%s: Failed to save new entry to journal (%s)\n", log_zone_error("%s: Failed to save new entry to journal (%s)\n",
msg, knot_strerror(ret)); msg, knot_strerror(ret));
xfrin_rollback_update(chgsets, old_contents, &new_contents); xfrin_rollback_update(chgsets, &new_contents);
zones_free_merged_changesets(chgsets, sec_chs); zones_free_merged_changesets(chgsets, sec_chs);
free(msg); free(msg);
return ret; return ret;
...@@ -337,10 +337,10 @@ static int zones_process_update_auth(struct query_data *qdata) ...@@ -337,10 +337,10 @@ static int zones_process_update_auth(struct query_data *qdata)
bool new_signatures = !knot_changeset_is_empty(sec_ch); bool new_signatures = !knot_changeset_is_empty(sec_ch);
// Apply DNSSEC changeset // Apply DNSSEC changeset
if (new_signatures) { if (new_signatures) {
ret = xfrin_apply_changesets_dnssec_ddns(zone, old_contents, ret = xfrin_apply_changesets_dnssec_ddns(zone,
new_contents, new_contents,
sec_chs, sec_chs,
chgsets); chgsets);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
log_zone_error("%s: Failed to sign incoming update (%s)" log_zone_error("%s: Failed to sign incoming update (%s)"
"\n", msg, knot_strerror(ret)); "\n", msg, knot_strerror(ret));
...@@ -366,7 +366,7 @@ static int zones_process_update_auth(struct query_data *qdata) ...@@ -366,7 +366,7 @@ static int zones_process_update_auth(struct query_data *qdata)
ret = knot_zone_contents_adjust_nsec3_pointers(new_contents); ret = knot_zone_contents_adjust_nsec3_pointers(new_contents);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
zones_store_changesets_rollback(transaction); zones_store_changesets_rollback(transaction);
xfrin_rollback_update(chgsets, old_contents, &new_contents); xfrin_rollback_update(chgsets, &new_contents);
zones_free_merged_changesets(chgsets, sec_chs); zones_free_merged_changesets(chgsets, sec_chs);
free(msg); free(msg);
return ret; return ret;
...@@ -379,7 +379,7 @@ static int zones_process_update_auth(struct query_data *qdata) ...@@ -379,7 +379,7 @@ static int zones_process_update_auth(struct query_data *qdata)
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
log_zone_error("%s: Failed to commit new journal entry " log_zone_error("%s: Failed to commit new journal entry "
"(%s).\n", msg, knot_strerror(ret)); "(%s).\n", msg, knot_strerror(ret));
xfrin_rollback_update(chgsets, old_contents, &new_contents); xfrin_rollback_update(chgsets, &new_contents);
zones_free_merged_changesets(chgsets, sec_chs); zones_free_merged_changesets(chgsets, sec_chs);
free(msg); free(msg);
return ret; return ret;
...@@ -395,7 +395,7 @@ static int zones_process_update_auth(struct query_data *qdata) ...@@ -395,7 +395,7 @@ static int zones_process_update_auth(struct query_data *qdata)
log_zone_error("%s: Failed to replace current zone (%s)\n", log_zone_error("%s: Failed to replace current zone (%s)\n",
msg, knot_strerror(ret)); msg, knot_strerror(ret));
// Cleanup old and new contents // Cleanup old and new contents
xfrin_rollback_update(chgsets, old_contents, &new_contents); xfrin_rollback_update(chgsets, &new_contents);
/* Free changesets, but not the data. */ /* Free changesets, but not the data. */
zones_free_merged_changesets(chgsets, sec_chs); zones_free_merged_changesets(chgsets, sec_chs);
......
...@@ -1470,7 +1470,7 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs, ...@@ -1470,7 +1470,7 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs,
/* Commit transaction. */ /* Commit transaction. */
ret = zones_store_changesets_commit(transaction); ret = zones_store_changesets_commit(transaction);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
xfrin_rollback_update(chs, zone->contents, new_contents); xfrin_rollback_update(chs, new_contents);
log_zone_error("%s Failed to commit stored changesets.\n", msgpref); log_zone_error("%s Failed to commit stored changesets.\n", msgpref);
knot_changesets_free(&chs); knot_changesets_free(&chs);
return ret; return ret;
...@@ -1486,7 +1486,7 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs, ...@@ -1486,7 +1486,7 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs,
if (switch_ret != KNOT_EOK) { if (switch_ret != KNOT_EOK) {
log_zone_error("%s Failed to replace current zone.\n", msgpref); log_zone_error("%s Failed to replace current zone.\n", msgpref);
// Cleanup old and new contents // Cleanup old and new contents
xfrin_rollback_update(chs, zone->contents, new_contents); xfrin_rollback_update(chs, new_contents);
/* Free changesets, but not the data. */ /* Free changesets, but not the data. */
knot_changesets_free(&chs); knot_changesets_free(&chs);
...@@ -1930,7 +1930,6 @@ int zones_journal_apply(zone_t *zone) ...@@ -1930,7 +1930,6 @@ int zones_journal_apply(zone_t *zone)
// Cleanup old and new contents // Cleanup old and new contents
xfrin_rollback_update(chsets, xfrin_rollback_update(chsets,
zone->contents,
&contents); &contents);
} }
} }
...@@ -2151,7 +2150,7 @@ static int store_chgsets_after_load(zone_t *old_zone, zone_t *zone, ...@@ -2151,7 +2150,7 @@ static int store_chgsets_after_load(zone_t *old_zone, zone_t *zone,
"switching zone (%s).\n", "switching zone (%s).\n",
zone->conf->name, knot_strerror(ret)); zone->conf->name, knot_strerror(ret));
// Cleanup old and new contents // Cleanup old and new contents
xfrin_rollback_update(diff_chs, zone->contents, &new_contents); xfrin_rollback_update(diff_chs, &new_contents);
return ret; return ret;
} }
......
...@@ -597,24 +597,6 @@ cleanup: ...@@ -597,24 +597,6 @@ cleanup:
/* Applying changesets to zone */ /* Applying changesets to zone */
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void xfrin_zone_contents_free(knot_zone_contents_t **contents)
{
/*! \todo This should be all in some API!! */
// free the zone tree with nodes
dbg_zone("Destroying zone tree.\n");
knot_zone_tree_deep_free(&(*contents)->nodes);
dbg_zone("Destroying NSEC3 zone tree.\n");
knot_zone_tree_deep_free(&(*contents)->nsec3_nodes);
knot_nsec3_params_free(&(*contents)->nsec3_params);
free(*contents);
*contents = NULL;
}
/*----------------------------------------------------------------------------*/
void xfrin_cleanup_successful_update(knot_changesets_t *chgs) void xfrin_cleanup_successful_update(knot_changesets_t *chgs)
{ {
if (chgs == NULL) { if (chgs == NULL) {
...@@ -632,46 +614,10 @@ void xfrin_cleanup_successful_update(knot_changesets_t *chgs) ...@@ -632,46 +614,10 @@ void xfrin_cleanup_successful_update(knot_changesets_t *chgs)
}; };
} }
/*----------------------------------------------------------------------------*/
/* New changeset applying */
/*----------------------------------------------------------------------------*/
static int xfrin_switch_nodes_in_node(knot_node_t **node, void *data)
{
UNUSED(data);
assert(node && *node);
assert(knot_node_new_node(*node) == NULL);
knot_node_update_refs(*node);
return KNOT_EOK;
}
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
static int xfrin_switch_nodes(knot_zone_contents_t *contents_copy) static void xfrin_zone_contents_free(knot_zone_contents_t **contents)
{ {
assert(contents_copy != NULL);
// Traverse the trees and for each node check every reference
// stored in that node. The node itself should be new.
int ret = knot_zone_tree_apply(contents_copy->nodes,
xfrin_switch_nodes_in_node, NULL);
if (ret == KNOT_EOK) {
ret = knot_zone_tree_apply(contents_copy->nsec3_nodes,
xfrin_switch_nodes_in_node, NULL);
}
return ret;
}
/*----------------------------------------------------------------------------*/
static void xfrin_zone_contents_free2(knot_zone_contents_t **contents)
{
/*! \todo This should be all in some API!! */
// free the zone tree, but only the structure // free the zone tree, but only the structure
// (nodes are already destroyed) // (nodes are already destroyed)
dbg_zone("Destroying zone tree.\n"); dbg_zone("Destroying zone tree.\n");
...@@ -687,44 +633,22 @@ static void xfrin_zone_contents_free2(knot_zone_contents_t **contents) ...@@ -687,44 +633,22 @@ static void xfrin_zone_contents_free2(knot_zone_contents_t **contents)
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
static int xfrin_cleanup_old_nodes(knot_node_t **node, void *data) static void xfrin_cleanup_failed_update(knot_zone_contents_t **new_contents)
{ {
UNUSED(data); if (new_contents == NULL) {
assert(node && *node);
knot_node_set_new_node(*node, NULL);
return KNOT_EOK;
}
/*----------------------------------------------------------------------------*/
static void xfrin_cleanup_failed_update(knot_zone_contents_t *old_contents,
knot_zone_contents_t **new_contents)
{
if (old_contents == NULL && new_contents == NULL) {
return; return;
} }
if (*new_contents != NULL) { if (*new_contents != NULL) {
// destroy the shallow copy of zone // destroy the shallow copy of zone
xfrin_zone_contents_free2(new_contents); xfrin_zone_contents_free(new_contents);
} }
if (old_contents != NULL) {
// cleanup old zone tree - reset pointers to new node to NULL
knot_zone_tree_apply(old_contents->nodes, xfrin_cleanup_old_nodes,
NULL);
knot_zone_tree_apply(old_contents->nsec3_nodes, xfrin_cleanup_old_nodes,
NULL);
}
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void xfrin_rollback_update(knot_changesets_t *chgs, void xfrin_rollback_update(knot_changesets_t *chgs,
knot_zone_contents_t *old_contents,
knot_zone_contents_t **new_contents) knot_zone_contents_t **new_contents)
{ {
if (chgs != NULL) { if (chgs != NULL) {
...@@ -734,11 +658,11 @@ void xfrin_rollback_update(knot_changesets_t *chgs, ...@@ -734,11 +658,11 @@ void xfrin_rollback_update(knot_changesets_t *chgs,
rrs_list_clear(&change->new_data, NULL); rrs_list_clear(&change->new_data, NULL);
// Keep old RR data // Keep old RR data
ptrlist_free(&change->old_data, NULL); ptrlist_free(&change->old_data, NULL);
init_list(&change->new_data); init_list(&change->new_data);
init_list(&change->old_data); init_list(&change->old_data);
}; };
} }
xfrin_cleanup_failed_update(old_contents, new_contents); xfrin_cleanup_failed_update(new_contents);
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
...@@ -999,7 +923,7 @@ static int xfrin_apply_changeset(list_t *old_rrs, list_t *new_rrs, ...@@ -999,7 +923,7 @@ static int xfrin_apply_changeset(list_t *old_rrs, list_t *new_rrs,
if (soa == NULL || knot_rrs_soa_serial(soa) if (soa == NULL || knot_rrs_soa_serial(soa)
!= chset->serial_from) { != chset->serial_from) {
dbg_xfrin("SOA serials do not match!!\n"); dbg_xfrin("SOA serials do not match!!\n");
return KNOT_ERROR; return KNOT_EINVAL;
} }
int ret = xfrin_apply_remove(contents, chset, old_rrs, new_rrs); int ret = xfrin_apply_remove(contents, chset, old_rrs, new_rrs);
...@@ -1140,7 +1064,7 @@ int xfrin_prepare_zone_copy(knot_zone_contents_t *old_contents, ...@@ -1140,7 +1064,7 @@ int xfrin_prepare_zone_copy(knot_zone_contents_t *old_contents,
* updated. * updated.
* *
* This will create new zone contents structures (normal nodes' tree, * This will create new zone contents structures (normal nodes' tree,
* NSEC3 tree, hash table, domain name table), and copy all nodes. * NSEC3 tree), and copy all nodes.
* The data in the nodes (RRSets) remain the same though. * The data in the nodes (RRSets) remain the same though.
*/ */
knot_zone_contents_t *contents_copy = NULL; knot_zone_contents_t *contents_copy = NULL;
...@@ -1155,19 +1079,6 @@ int xfrin_prepare_zone_copy(knot_zone_contents_t *old_contents, ...@@ -1155,19 +1079,6 @@ int xfrin_prepare_zone_copy(knot_zone_contents_t *old_contents,
assert(knot_zone_contents_apex(contents_copy) != NULL); assert(knot_zone_contents_apex(contents_copy) != NULL);
/*
* Fix references to new nodes. Some references in new nodes may point
* to old nodes. Hash table contains only old nodes.
*/
dbg_xfrin("Switching ptrs pointing to old nodes to the new nodes.\n");
ret = xfrin_switch_nodes(contents_copy);
if (ret != KNOT_EOK) {
dbg_xfrin("Failed to switch pointers in nodes.\n");
knot_zone_contents_free(&contents_copy);
return ret;
}
assert(knot_zone_contents_apex(contents_copy) != NULL);
*new_contents = contents_copy; *new_contents = contents_copy;
return KNOT_EOK; return KNOT_EOK;
...@@ -1246,12 +1157,11 @@ int xfrin_apply_changesets_directly(knot_zone_contents_t *contents, ...@@ -1246,12 +1157,11 @@ int xfrin_apply_changesets_directly(knot_zone_contents_t *contents,
/* Post-DDNS application, no need to shallow copy. */ /* Post-DDNS application, no need to shallow copy. */
int xfrin_apply_changesets_dnssec_ddns(zone_t *zone, int xfrin_apply_changesets_dnssec_ddns(zone_t *zone,
knot_zone_contents_t *z_old,
knot_zone_contents_t *z_new, knot_zone_contents_t *z_new,
knot_changesets_t *sec_chsets, knot_changesets_t *sec_chsets,
knot_changesets_t *chsets) knot_changesets_t *chsets)
{ {
if (zone == NULL || z_old == NULL || z_new == NULL || if (zone == NULL || z_new == NULL ||
sec_chsets == NULL || chsets == NULL) { sec_chsets == NULL || chsets == NULL) {
return KNOT_EINVAL; return KNOT_EINVAL;
} }
...@@ -1262,7 +1172,7 @@ int xfrin_apply_changesets_dnssec_ddns(zone_t *zone, ...@@ -1262,7 +1172,7 @@ int xfrin_apply_changesets_dnssec_ddns(zone_t *zone,
/* Apply changes. */ /* Apply changes. */
int ret = xfrin_apply_changesets_directly(z_new, sec_chsets); int ret = xfrin_apply_changesets_directly(z_new, sec_chsets);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
xfrin_rollback_update(sec_chsets, z_old, &z_new); xfrin_rollback_update(sec_chsets, &z_new);
dbg_xfrin("Failed to apply changesets to zone: " dbg_xfrin("Failed to apply changesets to zone: "
"%s\n", knot_strerror(ret)); "%s\n", knot_strerror(ret));
return ret; return ret;
...@@ -1273,7 +1183,7 @@ int xfrin_apply_changesets_dnssec_ddns(zone_t *zone, ...@@ -1273,7 +1183,7 @@ int xfrin_apply_changesets_dnssec_ddns(zone_t *zone,
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
dbg_xfrin("Failed to finalize updated zone: %s\n", dbg_xfrin("Failed to finalize updated zone: %s\n",
knot_strerror(ret)); knot_strerror(ret));
xfrin_rollback_update(sec_chsets, z_old, &z_new); xfrin_rollback_update(sec_chsets, &z_new);
return ret; return ret;
} }
...@@ -1320,8 +1230,7 @@ int xfrin_apply_changesets(zone_t *zone, ...@@ -1320,8 +1230,7 @@ int xfrin_apply_changesets(zone_t *zone,
&set->new_data, &set->new_data,
contents_copy, set); contents_copy, set);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
xfrin_rollback_update(chsets, old_contents, xfrin_rollback_update(chsets, &contents_copy);
&contents_copy);
dbg_xfrin("Failed to apply changesets to zone: " dbg_xfrin("Failed to apply changesets to zone: "
"%s\n", knot_strerror(ret)); "%s\n", knot_strerror(ret));
return ret; return ret;
...@@ -1338,7 +1247,7 @@ int xfrin_apply_changesets(zone_t *zone, ...@@ -1338,7 +1247,7 @@ int xfrin_apply_changesets(zone_t *zone,
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
dbg_xfrin("Failed to finalize updated zone: %s\n", dbg_xfrin("Failed to finalize updated zone: %s\n",
knot_strerror(ret)); knot_strerror(ret));
xfrin_rollback_update(chsets, old_contents, &contents_copy); xfrin_rollback_update(chsets, &contents_copy);
return ret; return ret;
} }
......
...@@ -155,7 +155,6 @@ int xfrin_apply_changesets(zone_t *zone, ...@@ -155,7 +155,6 @@ int xfrin_apply_changesets(zone_t *zone,
/*! /*!
* \brief Applies DNSSEC changesets after DDNS. * \brief Applies DNSSEC changesets after DDNS.
* *
* \param z_old Old contents for possible rollbacks.
* \param z_new Post DDNS/reload zone. * \param z_new Post DDNS/reload zone.
* \param sec_chsets Changes with RRSIGs/NSEC(3)s. * \param sec_chsets Changes with RRSIGs/NSEC(3)s.
* \param chsets DDNS/reload changes, for rollback. * \param chsets DDNS/reload changes, for rollback.
...@@ -165,7 +164,7 @@ int xfrin_apply_changesets(zone_t *zone, ...@@ -165,7 +164,7 @@ int xfrin_apply_changesets(zone_t *zone,
* by the UPDATE-processing function. It uses new and old zones from this * by the UPDATE-processing function. It uses new and old zones from this
* operation. * operation.
*/ */
int xfrin_apply_changesets_dnssec_ddns(zone_t *zone, knot_zone_contents_t *z_old, int xfrin_apply_changesets_dnssec_ddns(zone_t *zone,
knot_zone_contents_t *z_new, knot_zone_contents_t *z_new,
knot_changesets_t *sec_chsets, knot_changesets_t *sec_chsets,
knot_changesets_t *chsets); knot_changesets_t *chsets);
...@@ -199,7 +198,7 @@ int xfrin_switch_zone(zone_t *zone, ...@@ -199,7 +198,7 @@ int xfrin_switch_zone(zone_t *zone,
knot_zone_contents_t *new_contents, knot_zone_contents_t *new_contents,
int transfer_type); int transfer_type);
void xfrin_rollback_update(knot_changesets_t *chgs, knot_zone_contents_t *old_contents, void xfrin_rollback_update(knot_changesets_t *chgs,
knot_zone_contents_t **new_contents); knot_zone_contents_t **new_contents);
int xfrin_copy_rrset(knot_node_t *node, uint16_t type, int xfrin_copy_rrset(knot_node_t *node, uint16_t type,
...@@ -211,7 +210,6 @@ int xfrin_replace_rrset_in_node(knot_node_t *node, ...@@ -211,7 +210,6 @@ int xfrin_replace_rrset_in_node(knot_node_t *node,
knot_rrset_t *rrset_new, knot_rrset_t *rrset_new,
knot_zone_contents_t *contents); knot_zone_contents_t *contents);
void xfrin_zone_contents_free(knot_zone_contents_t **contents);
void xfrin_cleanup_successful_update(knot_changesets_t *chgs); void xfrin_cleanup_successful_update(knot_changesets_t *chgs);
#endif /* _KNOTXFR_IN_H_ */ #endif /* _KNOTXFR_IN_H_ */
......
...@@ -401,63 +401,6 @@ const knot_node_t *knot_node_wildcard_child(const knot_node_t *node) ...@@ -401,63 +401,6 @@ const knot_node_t *knot_node_wildcard_child(const knot_node_t *node)
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
const knot_node_t *knot_node_new_node(const knot_node_t *node)
{
if (node == NULL) {
return NULL;
}
return node->new_node;
}
/*----------------------------------------------------------------------------*/
knot_node_t *knot_node_get_new_node(const knot_node_t *node)
{
if (node == NULL) {
return NULL;
}
return node->new_node;
}
/*----------------------------------------------------------------------------*/
void knot_node_set_new_node(knot_node_t *node,
knot_node_t *new_node)
{
if (node == NULL) {
return;
}
node->new_node = new_node;
}
/*----------------------------------------------------------------------------*/
static void knot_node_update_ref(knot_node_t **ref)
{
if (*ref != NULL && (*ref)->new_node != NULL) {
*ref = (*ref)->new_node;
}
}
/*----------------------------------------------------------------------------*/
void knot_node_update_refs(knot_node_t *node)
{
// reference to previous node
knot_node_update_ref(&node->prev);
// reference to parent
knot_node_update_ref(&node->parent);
// reference to wildcard child
knot_node_update_ref(&node->wildcard_child);
// reference to NSEC3 node
knot_node_update_ref(&node->nsec3_node);
}
/*----------------------------------------------------------------------------*/
void knot_node_set_deleg_point(knot_node_t *node) void knot_node_set_deleg_point(knot_node_t *node)
{ {
if (node == NULL) { if (node == NULL) {
...@@ -638,18 +581,21 @@ int knot_node_shallow_copy(const knot_node_t *from, knot_node_t **to) ...@@ -638,18 +581,21 @@ int knot_node_shallow_copy(const knot_node_t *from, knot_node_t **to)
if (*to == NULL) { if (*to == NULL) {
return KNOT_ENOMEM; return KNOT_ENOMEM;
} }
memset(*to, 0, sizeof(knot_node_t));
// do not use the API function to set parent, so that children count // Copy owner
// is not changed
memcpy(*to, from, sizeof(knot_node_t));
(*to)->owner = knot_dname_copy(from->owner, NULL); (*to)->owner = knot_dname_copy(from->owner, NULL);
if ((*to)->owner == NULL) {
free(*to);
return KNOT_ENOMEM;
}
// copy RRSets // copy RRSets
(*to)->rrset_count = from->rrset_count;
size_t rrlen = sizeof(struct rr_data) * from->rrset_count; size_t rrlen = sizeof(struct rr_data) * from->rrset_count;
(*to)->rrs = malloc(rrlen); (*to)->rrs = malloc(rrlen);
if ((*to)->rrs == NULL) { if ((*to)->rrs == NULL) {
free(*to); knot_node_free(to);
*to = NULL;
return KNOT_ENOMEM; return KNOT_ENOMEM;
} }
memcpy((*to)->rrs, from->rrs, rrlen); memcpy((*to)->rrs, from->rrs, rrlen);
......
...@@ -68,8 +68,6 @@ struct knot_node { ...@@ -68,8 +68,6 @@ struct knot_node {
*/ */
struct knot_node *nsec3_node; struct knot_node *nsec3_node;
struct knot_node *new_node;
unsigned int children; unsigned int children;
uint16_t rrset_count; /*!< Number of RRSets stored in the node. */ uint16_t rrset_count; /*!< Number of RRSets stored in the node. */
...@@ -286,14 +284,6 @@ void knot_node_set_wildcard_child(knot_node_t *node, ...@@ -286,14 +284,6 @@ void knot_node_set_wildcard_child(knot_node_t *node,
knot_node_t *knot_node_get_wildcard_child(const knot_node_t *node); knot_node_t *knot_node_get_wildcard_child(const 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_refs(knot_node_t *node);
/*! /*!
* \brief Mark the node as a delegation point. * \brief Mark the node as a delegation point.
* *
......
...@@ -566,7 +566,6 @@ dbg_zone_exec_detail( ...@@ -566,7 +566,6 @@ dbg_zone_exec_detail(
/* Insert node to a tree. */ /* Insert node to a tree. */
dbg_zone_detail("Inserting new node to zone tree.\n"); dbg_zone_detail("Inserting new node to zone tree.\n");
assert(knot_zone_contents_find_node(zone, parent) == NULL);
ret = knot_zone_tree_insert(zone->nodes, next_node); ret = knot_zone_tree_insert(zone->nodes, next_node);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
knot_node_free(&next_node); knot_node_free(&next_node);
...@@ -599,13 +598,9 @@ dbg_zone_exec_detail( ...@@ -599,13 +598,9 @@ dbg_zone_exec_detail(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *zone, static int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *zone,
knot_node_t *node, int create_parents, knot_node_t *node)
uint8_t flags)
{ {
UNUSED(create_parents);
UNUSED(flags);
if (zone == NULL || node == NULL) { if (zone == NULL || node == NULL) {
return KNOT_EINVAL; return KNOT_EINVAL;
} }
...@@ -684,7 +679,7 @@ static int insert_rr(knot_zone_contents_t *z, ...@@ -684,7 +679,7 @@ static int insert_rr(knot_zone_contents_t *z,
if (*n == NULL) { if (*n == NULL) {
return KNOT_ENOMEM; return KNOT_ENOMEM;
} }
ret = nsec3 ? knot_zone_contents_add_nsec3_node(z, *n, true, 0) : ret = nsec3 ? knot_zone_contents_add_nsec3_node(z, *n) :
knot_zone_contents_add_node(z, *n, true, 0); knot_zone_contents_add_node(z, *n, true, 0);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
knot_node_free(n); knot_node_free(n);
...@@ -695,6 +690,97 @@ static int insert_rr(knot_zone_contents_t *z, ...@@ -695,6 +690,97 @@ static int insert_rr(knot_zone_contents_t *z,
return knot_node_add_rrset(*n, rr); return knot_node_add_rrset(*n, rr);
} }
static int recreate_normal_tree(const knot_zone_contents_t *z,
knot_zone_contents_t *out)
{
out->nodes = hattrie_dup(z->nodes, NULL);
if (out->nodes == NULL) {
return KNOT_ENOMEM;
}
// Insert APEX first.
knot_node_t *apex_cpy;
int ret = knot_node_shallow_copy(z->apex, &apex_cpy);
if (ret != KNOT_EOK) {
return ret;
}
// Normal additions need apex ... so we need to insert directly.
ret = knot_zone_tree_insert(out->nodes, apex_cpy);
if (ret != KNOT_EOK) {
knot_node_free(&apex_cpy);
return ret;
}
out->apex = apex_cpy;
hattrie_iter_t *itt = hattrie_iter_begin(z->nodes, true);
if (itt == NULL) {
return KNOT_ENOMEM;
}
while (!hattrie_iter_finished(itt)) {
const knot_node_t *to_cpy = (knot_node_t *)*hattrie_iter_val(itt);
if (to_cpy == z->apex) {
// Inserted already.
hattrie_iter_next(itt);
continue;
}
knot_node_t *to_add;
int ret = knot_node_shallow_copy(to_cpy, &to_add);