Skip to content
Snippets Groups Projects
Commit 4822c2e1 authored by Jan Včelák's avatar Jan Včelák :rocket:
Browse files

zone-diff: refactor internal functions

- split the functions to smaller chunks
- delegate repeated code
- work with zone tree instead of zone content
parent d64a97eb
No related branches found
No related tags found
No related merge requests found
......@@ -26,8 +26,7 @@
#include "common/descriptor.h"
struct zone_diff_param {
const knot_zone_contents_t *contents;
char nsec3;
knot_zone_tree_t *nodes;
knot_changeset_t *changeset;
int ret;
};
......@@ -599,15 +598,17 @@ static int knot_zone_diff_rrsets(const knot_rrset_t *rrset1,
}
/*!< \todo this could be generic function for adding / removing. */
static void knot_zone_diff_node(knot_node_t *node, void *data)
static void knot_zone_diff_node(knot_node_t **node_ptr, void *data)
{
if (node == NULL || data == NULL) {
if (node_ptr == NULL || *node_ptr == NULL || data == NULL) {
dbg_zonediff("zone_diff: diff_node: NULL arguments.\n");
return;
}
knot_node_t *node = *node_ptr;
struct zone_diff_param *param = (struct zone_diff_param *)data;
if (param->changeset == NULL || param->contents == NULL) {
if (param->changeset == NULL || param->nodes == NULL) {
dbg_zonediff("zone_diff: diff_node: NULL arguments.\n");
param->ret = KNOT_EINVAL;
return;
......@@ -627,16 +628,8 @@ static void knot_zone_diff_node(knot_node_t *node, void *data)
const knot_node_t *node_in_second_tree = NULL;
const knot_dname_t *node_owner = knot_node_owner(node);
assert(node_owner);
if (!param->nsec3) {
node_in_second_tree =
knot_zone_contents_find_node(param->contents,
node_owner);
} else {
dbg_zonediff_verb("zone_diff: diff_node: NSEC3 zone.\n");
node_in_second_tree =
knot_zone_contents_find_nsec3_node(param->contents,
node_owner);
}
knot_zone_tree_find(param->nodes, node_owner, &node_in_second_tree);
if (node_in_second_tree == NULL) {
dbg_zonediff_detail("zone_diff: diff_node: Node %s is not "
......@@ -827,16 +820,17 @@ static void knot_zone_diff_node(knot_node_t *node, void *data)
}
/*!< \todo possibly not needed! */
static void knot_zone_diff_add_new_nodes(knot_node_t *node, void *data)
static void knot_zone_diff_add_new_nodes(knot_node_t **node_ptr, void *data)
{
assert(node);
if (node == NULL || data == NULL) {
if (node_ptr == NULL || *node_ptr == NULL || data == NULL) {
dbg_zonediff("zone_diff: add_new_nodes: NULL arguments.\n");
return;
}
knot_node_t *node = *node_ptr;
struct zone_diff_param *param = (struct zone_diff_param *)data;
if (param->changeset == NULL || param->contents == NULL) {
if (param->changeset == NULL || param->nodes == NULL) {
dbg_zonediff("zone_diff: add_new_nodes: NULL arguments.\n");
param->ret = KNOT_EINVAL;
return;
......@@ -854,8 +848,6 @@ static void knot_zone_diff_add_new_nodes(knot_node_t *node, void *data)
* and has to be added to changeset. Differencies on the RRSet level are
* already handled.
*/
const knot_zone_contents_t *other_zone = param->contents;
assert(other_zone);
const knot_dname_t *node_owner = knot_node_owner(node);
/*
......@@ -865,12 +857,7 @@ static void knot_zone_diff_add_new_nodes(knot_node_t *node, void *data)
assert(node_owner);
knot_node_t *new_node = NULL;
if (!param->nsec3) {
new_node = knot_zone_contents_get_node(other_zone, node_owner);
} else {
new_node = knot_zone_contents_get_nsec3_node(other_zone,
node_owner);
}
knot_zone_tree_get(param->nodes, node_owner, &new_node);
if (!new_node) {
assert(node);
......@@ -886,94 +873,65 @@ static void knot_zone_diff_add_new_nodes(knot_node_t *node, void *data)
assert(param->ret == KNOT_EOK);
}
static int knot_zone_diff_load_trees(knot_zone_tree_t *nodes1,
knot_zone_tree_t *nodes2,
knot_changeset_t *changeset)
{
assert(nodes1);
assert(nodes2);
assert(changeset);
struct zone_diff_param param = { 0 };
param.ret = KNOT_EOK;
param.changeset = changeset;
// Traverse one tree, compare every node, each RRSet with its rdata.
param.nodes = nodes2;
int result = knot_zone_tree_apply(nodes1, knot_zone_diff_node, &param);
if (result != KNOT_EOK)
return result;
// Some nodes may have been added. Add missing nodes to changeset.
param.nodes = nodes1;
result = knot_zone_tree_apply(nodes2, knot_zone_diff_add_new_nodes, &param);
return result;
}
static int knot_zone_diff_load_content(const knot_zone_contents_t *zone1,
const knot_zone_contents_t *zone2,
knot_changeset_t *changeset)
{
int result;
result = knot_zone_diff_load_trees(zone1->nodes, zone2->nodes, changeset);
if (result != KNOT_EOK)
return result;
result = knot_zone_diff_load_trees(zone1->nsec3_nodes, zone2->nsec3_nodes,
changeset);
return result;
}
int knot_zone_contents_diff(const knot_zone_contents_t *zone1,
const knot_zone_contents_t *zone2,
knot_changeset_t *changeset)
{
if (zone1 == NULL || zone2 == NULL) {
dbg_zonediff("zone_diff: NULL argument(s).\n");
return KNOT_EINVAL;
}
// /* Create changeset structure. */
// *changeset = malloc(sizeof(knot_changeset_t));
// if (*changeset == NULL) {
// ERR_ALLOC_FAILED;
// return KNOT_ENOMEM;
// }
memset(changeset, 0, sizeof(knot_changeset_t));
/* Settle SOAs first. */
int ret = knot_zone_diff_load_soas(zone1, zone2, changeset);
if (ret != KNOT_EOK) {
dbg_zonediff("zone_diff: loas_SOAs failed with error: %s\n",
knot_strerror(ret));
return ret;
int result = knot_zone_diff_load_soas(zone1, zone2, changeset);
if (result != KNOT_EOK) {
return result;
}
dbg_zonediff("zone_diff: SOAs loaded.\n");
/* Traverse one tree, compare every node, each RRSet with its rdata. */
struct zone_diff_param param;
param.contents = zone2;
param.nsec3 = 0;
param.changeset = changeset;
param.ret = KNOT_EOK;
ret = knot_zone_contents_tree_apply_inorder(
(knot_zone_contents_t *)zone1,
knot_zone_diff_node,
&param);
if (ret != KNOT_EOK) {
dbg_zonediff("zone_diff: Tree traversal failed "
"with error: %s. Error from inner function: %s\n",
knot_strerror(ret),
knot_strerror(param.ret));
return ret;
}
/* Do the same for NSEC3 nodes. */
param.nsec3 = 1;
ret = knot_zone_contents_nsec3_apply_inorder((knot_zone_contents_t *)zone1, knot_zone_diff_node,
&param);
if (ret != KNOT_EOK) {
dbg_zonediff("zone_diff: Tree traversal failed "
"with error: %s\n",
knot_strerror(ret));
return ret;
}
/*
* Some nodes may have been added. The code above will not notice,
* we have to go through the second tree and add missing nodes to
* changeset.
*/
param.nsec3 = 0;
param.contents = zone1;
ret = knot_zone_contents_tree_apply_inorder((knot_zone_contents_t *)zone2,
knot_zone_diff_add_new_nodes,
&param);
if (ret != KNOT_EOK) {
dbg_zonediff("zone_diff: Tree traversal failed "
"with error: %s. Error from inner function: %s\n",
knot_strerror(ret),
knot_strerror(param.ret));
return ret;
}
/* NSEC3 nodes. */
param.nsec3 = 1;
param.contents = zone1;
ret = knot_zone_contents_nsec3_apply_inorder((knot_zone_contents_t *)zone2,
knot_zone_diff_add_new_nodes,
&param);
if (ret != KNOT_EOK) {
dbg_zonediff("zone_diff: Tree traversal failed "
"with error: %s\n",
knot_strerror(ret));
return ret;
}
return KNOT_EOK;
return knot_zone_diff_load_content(zone1, zone2, changeset);
}
#ifdef KNOT_ZONEDIFF_DEBUG
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment