diff --git a/src/common/hattrie/hat-trie.c b/src/common/hattrie/hat-trie.c index 692365ce77f324b268d3829e26be8779005fca3f..0993635026a8421f096215e65fc2401b383d8afc 100644 --- a/src/common/hattrie/hat-trie.c +++ b/src/common/hattrie/hat-trie.c @@ -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); + if (nval == NULL) { + return N; + } + /* assignment */ if (!nval) nval = hattrie_setval; diff --git a/src/knot/nameserver/update.c b/src/knot/nameserver/update.c index 26a29d9aeda0de1ed11c140c5c168f999786b220..1c91e0e5f806025c4d6cff526f1b29934572002a 100644 --- a/src/knot/nameserver/update.c +++ b/src/knot/nameserver/update.c @@ -280,7 +280,7 @@ static int zones_process_update_auth(struct query_data *qdata) sec_chs = knot_changesets_create(); sec_ch = knot_changesets_create_changeset(sec_chs); 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); free(msg); return KNOT_ENOMEM; @@ -313,7 +313,7 @@ static int zones_process_update_auth(struct query_data *qdata) log_zone_error("%s: Failed to sign incoming update (%s)" "\n", msg, knot_strerror(ret)); 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(&sec_chs); free(msg); @@ -328,7 +328,7 @@ static int zones_process_update_auth(struct query_data *qdata) if (ret != KNOT_EOK) { log_zone_error("%s: Failed to save new entry to journal (%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); free(msg); return ret; @@ -337,10 +337,10 @@ static int zones_process_update_auth(struct query_data *qdata) bool new_signatures = !knot_changeset_is_empty(sec_ch); // Apply DNSSEC changeset if (new_signatures) { - ret = xfrin_apply_changesets_dnssec_ddns(zone, old_contents, - new_contents, - sec_chs, - chgsets); + ret = xfrin_apply_changesets_dnssec_ddns(zone, + new_contents, + sec_chs, + chgsets); if (ret != KNOT_EOK) { log_zone_error("%s: Failed to sign incoming update (%s)" "\n", msg, knot_strerror(ret)); @@ -366,7 +366,7 @@ static int zones_process_update_auth(struct query_data *qdata) ret = knot_zone_contents_adjust_nsec3_pointers(new_contents); if (ret != KNOT_EOK) { 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); free(msg); return ret; @@ -379,7 +379,7 @@ static int zones_process_update_auth(struct query_data *qdata) if (ret != KNOT_EOK) { log_zone_error("%s: Failed to commit new journal entry " "(%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); free(msg); return ret; @@ -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", msg, knot_strerror(ret)); // 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. */ zones_free_merged_changesets(chgsets, sec_chs); diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c index de0d814d12fae23cafe2a7d379ae3ff2dc284e2f..2cb7736d08224b12445fac41f4127d63875b20e9 100644 --- a/src/knot/server/zones.c +++ b/src/knot/server/zones.c @@ -1470,7 +1470,7 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs, /* Commit transaction. */ ret = zones_store_changesets_commit(transaction); 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); knot_changesets_free(&chs); return ret; @@ -1486,7 +1486,7 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs, if (switch_ret != KNOT_EOK) { log_zone_error("%s Failed to replace current zone.\n", msgpref); // 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. */ knot_changesets_free(&chs); @@ -1930,7 +1930,6 @@ int zones_journal_apply(zone_t *zone) // Cleanup old and new contents xfrin_rollback_update(chsets, - zone->contents, &contents); } } @@ -2151,7 +2150,7 @@ static int store_chgsets_after_load(zone_t *old_zone, zone_t *zone, "switching zone (%s).\n", zone->conf->name, knot_strerror(ret)); // Cleanup old and new contents - xfrin_rollback_update(diff_chs, zone->contents, &new_contents); + xfrin_rollback_update(diff_chs, &new_contents); return ret; } diff --git a/src/knot/updates/xfr-in.c b/src/knot/updates/xfr-in.c index 2dd755e3e5aed143a5ff9380b16dfa5cd2f44a90..32e13b12708b79f3b00f5a120bff95b46ca3a9c6 100644 --- a/src/knot/updates/xfr-in.c +++ b/src/knot/updates/xfr-in.c @@ -597,24 +597,6 @@ cleanup: /* 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) { if (chgs == NULL) { @@ -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 // (nodes are already destroyed) dbg_zone("Destroying zone tree.\n"); @@ -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); - 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) { + if (new_contents == NULL) { return; } if (*new_contents != NULL) { // 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, - knot_zone_contents_t *old_contents, knot_zone_contents_t **new_contents) { if (chgs != NULL) { @@ -734,11 +658,11 @@ void xfrin_rollback_update(knot_changesets_t *chgs, 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); + init_list(&change->new_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, if (soa == NULL || knot_rrs_soa_serial(soa) != chset->serial_from) { 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); @@ -1140,7 +1064,7 @@ int xfrin_prepare_zone_copy(knot_zone_contents_t *old_contents, * updated. * * 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. */ knot_zone_contents_t *contents_copy = NULL; @@ -1155,19 +1079,6 @@ int xfrin_prepare_zone_copy(knot_zone_contents_t *old_contents, 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; return KNOT_EOK; @@ -1246,12 +1157,11 @@ int xfrin_apply_changesets_directly(knot_zone_contents_t *contents, /* Post-DDNS application, no need to shallow copy. */ int xfrin_apply_changesets_dnssec_ddns(zone_t *zone, - knot_zone_contents_t *z_old, knot_zone_contents_t *z_new, knot_changesets_t *sec_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) { return KNOT_EINVAL; } @@ -1262,7 +1172,7 @@ int xfrin_apply_changesets_dnssec_ddns(zone_t *zone, /* Apply changes. */ int ret = xfrin_apply_changesets_directly(z_new, sec_chsets); 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: " "%s\n", knot_strerror(ret)); return ret; @@ -1273,7 +1183,7 @@ int xfrin_apply_changesets_dnssec_ddns(zone_t *zone, if (ret != KNOT_EOK) { dbg_xfrin("Failed to finalize updated zone: %s\n", knot_strerror(ret)); - xfrin_rollback_update(sec_chsets, z_old, &z_new); + xfrin_rollback_update(sec_chsets, &z_new); return ret; } @@ -1320,8 +1230,7 @@ int xfrin_apply_changesets(zone_t *zone, &set->new_data, contents_copy, set); if (ret != KNOT_EOK) { - xfrin_rollback_update(chsets, old_contents, - &contents_copy); + xfrin_rollback_update(chsets, &contents_copy); dbg_xfrin("Failed to apply changesets to zone: " "%s\n", knot_strerror(ret)); return ret; @@ -1338,7 +1247,7 @@ int xfrin_apply_changesets(zone_t *zone, if (ret != KNOT_EOK) { dbg_xfrin("Failed to finalize updated zone: %s\n", knot_strerror(ret)); - xfrin_rollback_update(chsets, old_contents, &contents_copy); + xfrin_rollback_update(chsets, &contents_copy); return ret; } diff --git a/src/knot/updates/xfr-in.h b/src/knot/updates/xfr-in.h index ab3f95187ceca80a232483bb8ec499237d44d140..e6e772129e2db8501861038b33ef64ed3ecd5886 100644 --- a/src/knot/updates/xfr-in.h +++ b/src/knot/updates/xfr-in.h @@ -155,7 +155,6 @@ int xfrin_apply_changesets(zone_t *zone, /*! * \brief Applies DNSSEC changesets after DDNS. * - * \param z_old Old contents for possible rollbacks. * \param z_new Post DDNS/reload zone. * \param sec_chsets Changes with RRSIGs/NSEC(3)s. * \param chsets DDNS/reload changes, for rollback. @@ -165,7 +164,7 @@ int xfrin_apply_changesets(zone_t *zone, * by the UPDATE-processing function. It uses new and old zones from this * 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_changesets_t *sec_chsets, knot_changesets_t *chsets); @@ -199,7 +198,7 @@ int xfrin_switch_zone(zone_t *zone, knot_zone_contents_t *new_contents, 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); 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, knot_rrset_t *rrset_new, knot_zone_contents_t *contents); -void xfrin_zone_contents_free(knot_zone_contents_t **contents); void xfrin_cleanup_successful_update(knot_changesets_t *chgs); #endif /* _KNOTXFR_IN_H_ */ diff --git a/src/knot/zone/node.c b/src/knot/zone/node.c index ae8cfda7488140ede20759f10ce069ec00bbd68e..6e26eee43383d4ecdc67b41894b259c243c1aa4d 100644 --- a/src/knot/zone/node.c +++ b/src/knot/zone/node.c @@ -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) { if (node == NULL) { @@ -638,18 +581,21 @@ int knot_node_shallow_copy(const knot_node_t *from, knot_node_t **to) if (*to == NULL) { return KNOT_ENOMEM; } + memset(*to, 0, sizeof(knot_node_t)); - // do not use the API function to set parent, so that children count - // is not changed - memcpy(*to, from, sizeof(knot_node_t)); + // Copy owner (*to)->owner = knot_dname_copy(from->owner, NULL); + if ((*to)->owner == NULL) { + free(*to); + return KNOT_ENOMEM; + } // copy RRSets + (*to)->rrset_count = from->rrset_count; size_t rrlen = sizeof(struct rr_data) * from->rrset_count; (*to)->rrs = malloc(rrlen); if ((*to)->rrs == NULL) { - free(*to); - *to = NULL; + knot_node_free(to); return KNOT_ENOMEM; } memcpy((*to)->rrs, from->rrs, rrlen); diff --git a/src/knot/zone/node.h b/src/knot/zone/node.h index b374bdd5e182192862d36274c0906bcb9c00e80d..df636b2745982b091b99ba6c3d5b25278bc85b16 100644 --- a/src/knot/zone/node.h +++ b/src/knot/zone/node.h @@ -68,8 +68,6 @@ struct knot_node { */ struct knot_node *nsec3_node; - struct knot_node *new_node; - unsigned int children; 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, 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. * diff --git a/src/knot/zone/zone-contents.c b/src/knot/zone/zone-contents.c index 467e12de19eaa35c3f5bc1a8dd3601aa05d2a7be..3645ef62dfe8ff86aa7da27efe3cac6fa5144018 100644 --- a/src/knot/zone/zone-contents.c +++ b/src/knot/zone/zone-contents.c @@ -566,7 +566,6 @@ dbg_zone_exec_detail( /* Insert node to a tree. */ 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); if (ret != KNOT_EOK) { knot_node_free(&next_node); @@ -599,13 +598,9 @@ dbg_zone_exec_detail( /*----------------------------------------------------------------------------*/ -int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *zone, - knot_node_t *node, int create_parents, - uint8_t flags) +static int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *zone, + knot_node_t *node) { - UNUSED(create_parents); - UNUSED(flags); - if (zone == NULL || node == NULL) { return KNOT_EINVAL; } @@ -684,7 +679,7 @@ static int insert_rr(knot_zone_contents_t *z, if (*n == NULL) { 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); if (ret != KNOT_EOK) { knot_node_free(n); @@ -695,6 +690,97 @@ static int insert_rr(knot_zone_contents_t *z, 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); + if (ret != KNOT_EOK) { + hattrie_iter_free(itt); + return ret; + } + ret = knot_zone_contents_add_node(out, to_add, true, 0); + if (ret != KNOT_EOK) { + knot_node_free(&to_add); + hattrie_iter_free(itt); + return ret; + } + hattrie_iter_next(itt); + } + + hattrie_iter_free(itt); + hattrie_build_index(out->nodes); + + return KNOT_EOK; +} + +static int recreate_nsec3_tree(const knot_zone_contents_t *z, + knot_zone_contents_t *out) +{ + out->nsec3_nodes = hattrie_dup(z->nsec3_nodes, NULL); + if (out->nsec3_nodes == NULL) { + return KNOT_ENOMEM; + } + + hattrie_iter_t *itt = hattrie_iter_begin(z->nsec3_nodes, false); + if (itt == NULL) { + return KNOT_ENOMEM; + } + while (!hattrie_iter_finished(itt)) { + const knot_node_t *to_cpy = (knot_node_t *)*hattrie_iter_val(itt); + knot_node_t *to_add; + int ret = knot_node_shallow_copy(to_cpy, &to_add); + if (ret != KNOT_EOK) { + hattrie_iter_free(itt); + return ret; + } + ret = knot_zone_contents_add_nsec3_node(out, to_add); + if (ret != KNOT_EOK) { + hattrie_iter_free(itt); + knot_node_free(&to_add); + return ret; + } + hattrie_iter_next(itt); + } + + hattrie_iter_free(itt); + hattrie_build_index(out->nsec3_nodes); + + return KNOT_EOK; +} + int knot_zone_contents_add_rr(knot_zone_contents_t *z, const knot_rrset_t *rr, knot_node_t **n) { @@ -1249,41 +1335,36 @@ int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from, return KNOT_EINVAL; } - int ret = KNOT_EOK; - - knot_zone_contents_t *contents = (knot_zone_contents_t *)calloc( - 1, sizeof(knot_zone_contents_t)); + knot_zone_contents_t *contents = calloc(1, sizeof(knot_zone_contents_t)); if (contents == NULL) { ERR_ALLOC_FAILED; return KNOT_ENOMEM; } - //contents->apex = from->apex; - - contents->node_count = from->node_count; contents->flags = from->flags; - // set the 'new' flag knot_zone_contents_set_gen_new(contents); - if ((ret = knot_zone_tree_deep_copy(from->nodes, - &contents->nodes)) != KNOT_EOK - || (ret = knot_zone_tree_deep_copy(from->nsec3_nodes, - &contents->nsec3_nodes)) != KNOT_EOK) { - goto cleanup; + int ret = recreate_normal_tree(from, contents); + if (ret != KNOT_EOK) { + knot_zone_tree_free(&contents->nodes); + free(contents); + return ret; } - contents->apex = knot_node_get_new_node(from->apex); - - dbg_zone("knot_zone_contents_shallow_copy: finished OK\n"); + if (contents->nsec3_nodes) { + ret = recreate_nsec3_tree(from, contents); + if (ret != KNOT_EOK) { + knot_zone_tree_free(&contents->nodes); + knot_zone_tree_free(&contents->nsec3_nodes); + free(contents); + return ret; + } + } else { + contents->nsec3_nodes = NULL; + } *to = contents; return KNOT_EOK; - -cleanup: - knot_zone_tree_free(&contents->nodes); - knot_zone_tree_free(&contents->nsec3_nodes); - free(contents); - return ret; } /*----------------------------------------------------------------------------*/ @@ -1368,7 +1449,7 @@ knot_node_t *zone_contents_get_node_for_rr(knot_zone_contents_t *zone, if (!nsec3) { ret = knot_zone_contents_add_node(zone, node, 1, 0); } else { - ret = knot_zone_contents_add_nsec3_node(zone, node, 1, 0); + ret = knot_zone_contents_add_nsec3_node(zone, node); } if (ret != KNOT_EOK) { knot_node_free(&node); diff --git a/src/knot/zone/zone-tree.c b/src/knot/zone/zone-tree.c index 3628694878e4255732cdcaf2a39f2857c15961c3..af36361e8c10ab567fc5441d6875800681924b3f 100644 --- a/src/knot/zone/zone-tree.c +++ b/src/knot/zone/zone-tree.c @@ -23,23 +23,6 @@ #include "common/debug.h" #include "common/hattrie/hat-trie.h" -/*----------------------------------------------------------------------------*/ -/* Non-API functions */ -/*----------------------------------------------------------------------------*/ - -static value_t knot_zone_node_copy(value_t v) -{ - return v; -} - -static value_t knot_zone_node_deep_copy(value_t v) -{ - knot_node_t *n = NULL; - knot_node_shallow_copy((knot_node_t *)v, &n); - knot_node_set_new_node((knot_node_t *)v, n); - return (value_t)n; -} - /*----------------------------------------------------------------------------*/ /* API functions */ /*----------------------------------------------------------------------------*/ @@ -279,42 +262,6 @@ int knot_zone_tree_apply(knot_zone_tree_t *tree, /*----------------------------------------------------------------------------*/ -int knot_zone_tree_shallow_copy(knot_zone_tree_t *from, - knot_zone_tree_t **to) -{ - if (to == NULL) { - return KNOT_EINVAL; - } - - if (from != NULL) { - *to = hattrie_dup(from, knot_zone_node_copy); - } else { - *to = NULL; - } - - return KNOT_EOK; -} - -/*----------------------------------------------------------------------------*/ - -int knot_zone_tree_deep_copy(knot_zone_tree_t *from, - knot_zone_tree_t **to) -{ - if (to == NULL) { - return KNOT_EINVAL; - } - - if (from != NULL) { - *to = hattrie_dup(from, knot_zone_node_deep_copy); - } else { - *to = NULL; - } - - return KNOT_EOK; -} - -/*----------------------------------------------------------------------------*/ - void knot_zone_tree_free(knot_zone_tree_t **tree) { if (tree == NULL || *tree == NULL) { diff --git a/src/knot/zone/zone-tree.h b/src/knot/zone/zone-tree.h index cbc234ead678ae371f3bf66c438de3b95733a11b..07fcae54ec38674d3a8fe52204ee5e02735cf115 100644 --- a/src/knot/zone/zone-tree.h +++ b/src/knot/zone/zone-tree.h @@ -207,25 +207,6 @@ int knot_zone_tree_apply_inorder(knot_zone_tree_t *tree, int knot_zone_tree_apply(knot_zone_tree_t *tree, knot_zone_tree_apply_cb_t function, void *data); -/*! - * \brief Copies the whole zone tree structure (but not the data contained - * within). - * - * \warning This function does not check if the target zone tree is empty, - * it just replaces the root pointer. - * - * \param from Original zone tree. - * \param to Zone tree to copy the original one into. - * - * \retval KNOT_EOK - * \retval KNOT_ENOMEM - */ -int knot_zone_tree_shallow_copy(knot_zone_tree_t *from, - knot_zone_tree_t **to); - -int knot_zone_tree_deep_copy(knot_zone_tree_t *from, - knot_zone_tree_t **to); - /*! * \brief Destroys the zone tree, not touching the saved data. * diff --git a/src/libknot/rr.c b/src/libknot/rr.c index eded54e763a3400b13641d39b4b103bccbc31578..328f6d7dcb4a4af3314ae8e3d777dbf1f7362eb9 100644 --- a/src/libknot/rr.c +++ b/src/libknot/rr.c @@ -117,7 +117,7 @@ static int add_rr_at(knot_rrs_t *rrs, const knot_rr_t *rr, size_t pos, knot_rr_t *new_rr = knot_rrs_rr(rrs, pos); knot_rr_set_size(new_rr, size); knot_rr_set_ttl(new_rr, ttl); - memcpy(knot_rr_rdata, rdata, size); + memcpy(knot_rr_rdata(new_rr), rdata, size); return KNOT_EOK; }