summaryrefslogtreecommitdiff
path: root/src/libknot/zone/zone-contents.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libknot/zone/zone-contents.c')
-rw-r--r--src/libknot/zone/zone-contents.c1976
1 files changed, 493 insertions, 1483 deletions
diff --git a/src/libknot/zone/zone-contents.c b/src/libknot/zone/zone-contents.c
index 90aee0d..ff1a1d4 100644
--- a/src/libknot/zone/zone-contents.c
+++ b/src/libknot/zone/zone-contents.c
@@ -14,13 +14,16 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <config.h>
#include <assert.h>
#include "zone/zone-contents.h"
#include "util/debug.h"
+#include "libknot/rrset.h"
#include "common/base32hex.h"
-/*! \todo XXX TODO FIXME remove once testing is done. */
-#include "zcompile/zcompile.h"
+#include "common/descriptor.h"
+#include "common/hattrie/hat-trie.h"
+#include "libknot/zone/zone-tree.h"
#include "consts.h"
/*----------------------------------------------------------------------------*/
@@ -36,6 +39,7 @@ typedef struct {
knot_node_t *first_node;
knot_zone_contents_t *zone;
knot_node_t *previous_node;
+ hattrie_t *lookup_tree;
int err;
} knot_zone_adjust_arg_t;
@@ -50,7 +54,7 @@ const uint8_t KNOT_ZONE_FLAGS_ANY = 4; /* 00000100 */
/*----------------------------------------------------------------------------*/
-static void knot_zone_tree_apply(knot_zone_tree_node_t *node,
+static void tree_apply_cb(knot_node_t **node,
void *data)
{
if (node == NULL || data == NULL) {
@@ -58,7 +62,7 @@ static void knot_zone_tree_apply(knot_zone_tree_node_t *node,
}
knot_zone_tree_func_t *f = (knot_zone_tree_func_t *)data;
- f->func(node->node, f->data);
+ f->func(*node, f->data);
}
/*----------------------------------------------------------------------------*/
@@ -87,13 +91,13 @@ static int knot_zone_contents_check_node(
assert(contents->apex != NULL);
if (!knot_dname_is_subdomain(node->owner,
- knot_node_owner(contents->apex))) {
+ knot_node_owner(contents->apex))) {
dbg_zone_exec(
char *node_owner = knot_dname_to_str(knot_node_owner(node));
char *apex_owner = knot_dname_to_str(contents->apex->owner);
dbg_zone("zone: Trying to insert foreign node to a "
- "zone. Node owner: %s, zone apex: %s\n",
- node_owner, apex_owner);
+ "zone. Node owner: %s, zone apex: %s\n",
+ node_owner, apex_owner);
free(node_owner);
free(apex_owner);
);
@@ -112,166 +116,14 @@ dbg_zone_exec(
* \param data Unused parameter.
*/
static void knot_zone_contents_destroy_node_rrsets_from_tree(
- knot_zone_tree_node_t *tnode, void *data)
+ knot_node_t **tnode, void *data)
{
assert(tnode != NULL);
- assert(tnode->node != NULL);
+ if (*tnode == NULL) return; /* non-existent node */
int free_rdata_dnames = (int)((intptr_t)data);
- knot_node_free_rrsets(tnode->node, free_rdata_dnames);
-}
-
-/*----------------------------------------------------------------------------*/
-/*!
- * \brief Destroys node owner.
- *
- * This function is designed to be used in the tree-iterating functions.
- *
- * \param node Node to destroy the owner of.
- * \param data Unused parameter.
- */
-static void knot_zone_contents_destroy_node_owner_from_tree(
- knot_zone_tree_node_t *tnode, void *data)
-{
- assert(tnode != NULL);
- assert(tnode->node != NULL);
-
- UNUSED(data);
- /*!< \todo change completely! */
- knot_node_free(&tnode->node);
-}
-
-/*----------------------------------------------------------------------------*/
-
-static int knot_zone_contents_dnames_from_rdata_to_table(
- knot_dname_table_t *table, knot_rdata_t *rdata,
- knot_rrtype_descriptor_t *d)
-{
- unsigned int count = knot_rdata_item_count(rdata);
- int rc = 0;
- if (d->fixed_items) {
- assert(count <= d->length);
- }
- // for each RDATA item
- for (unsigned int j = 0; j < count; ++j) {
- if (d->wireformat[j]
- == KNOT_RDATA_WF_COMPRESSED_DNAME
- || d->wireformat[j]
- == KNOT_RDATA_WF_UNCOMPRESSED_DNAME
- || d->wireformat[j]
- == KNOT_RDATA_WF_LITERAL_DNAME) {
- rc = knot_dname_table_add_dname_check(table,
- &knot_rdata_get_item(rdata, j)->dname);
- if (rc < 0) {
- dbg_zone("Error: %s\n", knot_strerror(rc));
- return rc;
- }
- }
- }
-
- dbg_zone_detail("RDATA OK.\n");
- return KNOT_EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-
-static int knot_zone_contents_dnames_from_rrset_to_table(
- knot_dname_table_t *table, knot_rrset_t *rrset, int replace_owner,
- knot_dname_t *owner)
-{
- assert(table != NULL && rrset != NULL && owner != NULL);
-
-dbg_zone_exec_detail(
- char *name = knot_dname_to_str(knot_rrset_owner(rrset));
- dbg_zone_detail("Putting dnames from RRSet to table: owner: (%p) %s,"
- " type: %s\n", knot_rrset_owner(rrset),
- name, knot_rrtype_to_string(
- knot_rrset_type(rrset)));
- free(name);
-);
-
- if (replace_owner) {
- // discard the old owner and replace it with the new
- knot_rrset_set_owner(rrset, owner);
- }
- dbg_zone_detail("RRSet owner: %p\n", rrset->owner);
-
- knot_rrtype_descriptor_t *desc = knot_rrtype_descriptor_by_type(
- knot_rrset_type(rrset));
- if (desc == NULL) {
- // not recognized RR type, ignore
- dbg_zone("RRSet type not recognized.\n");
- return KNOT_EOK;
- }
- // for each RDATA in RRSet
- knot_rdata_t *rdata = knot_rrset_get_rdata(rrset);
- while (rdata != NULL) {
- int rc = knot_zone_contents_dnames_from_rdata_to_table(table,
- rdata, desc);
- if (rc != KNOT_EOK) {
- return rc;
- }
-
- rdata = knot_rrset_rdata_get_next(rrset, rdata);
- }
-
- dbg_zone("RRSet OK.\n");
- return KNOT_EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-
-static int knot_zone_contents_dnames_from_node_to_table(
- knot_dname_table_t *table, knot_node_t *node)
-{
- /*
- * Assuming that all the RRSets have the same owner as the node.
- */
-
- // insert owner
- char *name = knot_dname_to_str(node->owner);
- dbg_zone_detail("Node owner before inserting to dname table: %p.\n",
- node->owner);
- dbg_zone_detail("Node owner before inserting to dname table: %s.\n",
- name);
- free(name);
- //knot_dname_t *old_owner = node->owner;
- int rc = knot_dname_table_add_dname_check(table, &node->owner);
- if (rc < 0) {
- dbg_zone("Failed to add dname to dname table.\n");
- return rc;
- }
- int replace_owner = (rc > 0);
-
-dbg_zone_exec_detail(
- name = knot_dname_to_str(node->owner);
- dbg_zone_detail("Node owner after inserting to dname table: %p (%s).\n",
- node->owner, name);
- free(name);
-);
-
- knot_rrset_t **rrsets = knot_node_get_rrsets(node);
- // for each RRSet
- for (int i = 0; i < knot_node_rrset_count(node); ++i) {
- dbg_zone_detail("Inserting RRSets from node to table.\n");
- rc = knot_zone_contents_dnames_from_rrset_to_table(table,
- rrsets[i], replace_owner, node->owner);
-
- if (rc == KNOT_EOK && knot_rrset_rrsigs(rrsets[i]) != NULL) {
- rc = knot_zone_contents_dnames_from_rrset_to_table(
- table, knot_rrset_get_rrsigs(rrsets[i]),
- replace_owner, node->owner);
- }
-
- if (rc != KNOT_EOK) {
- return rc;
- }
- }
-
- free(rrsets);
-
- dbg_zone("Node OK\n");
- return KNOT_EOK;
+ knot_node_free_rrsets(*tnode, free_rdata_dnames);
+ knot_node_free(tnode);
}
/*----------------------------------------------------------------------------*/
@@ -286,7 +138,7 @@ static const knot_node_t *knot_zone_contents_find_wildcard_child(
CHECK_ALLOC(tmp, NULL);
knot_dname_t *wildcard = knot_dname_cat(tmp, knot_node_owner(
- closest_encloser));
+ closest_encloser));
if (wildcard == NULL) {
free(tmp);
return NULL;
@@ -298,14 +150,14 @@ dbg_zone_exec_detail(
char *name = knot_dname_to_str(knot_node_owner(closest_encloser));
char *name2 = knot_dname_to_str(wildcard);
dbg_zone_detail("Searching for wildcard child of %s (%s)\n", name,
- name2);
+ name2);
free(name);
free(name2);
);
const knot_node_t *found = NULL, *ce = NULL, *prev = NULL;
int ret = knot_zone_contents_find_dname(zone, wildcard, &found, &ce,
- &prev);
+ &prev);
knot_dname_free(&wildcard);
@@ -316,6 +168,29 @@ dbg_zone_exec_detail(
}
}
+void knot_zone_contents_insert_dname_into_table(knot_dname_t **in_dname,
+ hattrie_t *lookup_tree)
+{
+ if (lookup_tree == NULL) {
+ /* = Do not check duplicates. */
+ return;
+ }
+ assert(in_dname && *in_dname);
+ /* First thing - make sure dname is not duplicated. */
+ knot_dname_t *found_dname = hattrie_get_dname(lookup_tree, *in_dname);
+ if (found_dname != NULL && found_dname != *in_dname) {
+ /* Duplicate. */
+ knot_dname_release(*in_dname);
+ knot_dname_retain(found_dname);
+ *in_dname = found_dname;
+ } else if (found_dname == NULL) {
+ /* Into the tree it goes. */
+ hattrie_insert_dname(lookup_tree, *in_dname);
+ } else {
+ assert(found_dname == *in_dname);
+ }
+}
+
/*----------------------------------------------------------------------------*/
/*!
* \brief Adjusts one RDATA item by replacing domain name by one present in the
@@ -333,49 +208,48 @@ dbg_zone_exec_detail(
* \param zone Zone to which the RDATA belongs.
* \param pos Position of the RDATA item in the RDATA.
*/
-static void knot_zone_contents_adjust_rdata_item(knot_rdata_t *rdata,
- knot_zone_contents_t *zone,
- knot_node_t *node, int pos)
-{
- const knot_rdata_item_t *dname_item = knot_rdata_item(rdata, pos);
-
- assert(dname_item);
-
- if (dname_item != NULL) {
- knot_dname_t *dname = dname_item->dname;
-
- /*
- * The case when dname.node is already set is handled here.
- * No use to check it later.
- */
- if (knot_dname_node(dname) != NULL
- || !knot_dname_is_subdomain(dname, knot_node_owner(
- knot_zone_contents_apex(zone)))) {
- // The name's node is either already set
- // or the name does not belong to the zone
- dbg_zone_detail("Name's (%p) node either set or the name"
- "does not belong to the zone (%p).\n",
- dname, knot_dname_node(dname));
- return;
- }
+static void knot_zone_contents_adjust_rdata_dname(knot_zone_contents_t *zone,
+ hattrie_t *lookup_tree,
+ knot_node_t *node,
+ knot_dname_t **in_dname)
+{
+// const knot_node_t *old_dname_node = (*in_dname)->node;
+ knot_zone_contents_insert_dname_into_table(in_dname, lookup_tree);
+// assert((*in_dname)->node == old_dname_node || old_dname_node == NULL);
- const knot_node_t *n = NULL;
- const knot_node_t *closest_encloser = NULL;
- const knot_node_t *prev = NULL;
+ knot_dname_t *dname = *in_dname;
+ /*
+ * The case when dname.node is already set is handled here.
+ * No use to check it later.
+ */
+ if (knot_dname_node(dname) != NULL
+ || !knot_dname_is_subdomain(dname, knot_node_owner(
+ knot_zone_contents_apex(zone)))) {
+ // The name's node is either already set
+ // or the name does not belong to the zone
+ dbg_zone_detail("Name's node either set or the name "
+ "does not belong to the zone (%p).\n",
+ knot_dname_node(dname));
+ return;
+ }
- int ret = knot_zone_contents_find_dname(zone, dname, &n,
- &closest_encloser, &prev);
+ const knot_node_t *n = NULL;
+ const knot_node_t *closest_encloser = NULL;
+ const knot_node_t *prev = NULL;
- if (ret == KNOT_EINVAL || ret == KNOT_EBADZONE) {
- // TODO: do some cleanup if needed
- dbg_zone_detail("Failed to find the name in zone: %s\n",
- knot_strerror(ret));
- return;
- }
+ int ret = knot_zone_contents_find_dname(zone, dname, &n,
+ &closest_encloser, &prev);
- assert(ret != KNOT_ZONE_NAME_FOUND || n == closest_encloser);
+ if (ret == KNOT_EINVAL || ret == KNOT_EBADZONE) {
+ // TODO: do some cleanup if needed
+ dbg_zone_detail("Failed to find the name in zone: %s\n",
+ knot_strerror(ret));
+ return;
+ }
- if (ret != KNOT_ZONE_NAME_FOUND && (closest_encloser != NULL)) {
+ assert(ret != KNOT_ZONE_NAME_FOUND || n == closest_encloser);
+
+ if (ret != KNOT_ZONE_NAME_FOUND && (closest_encloser != NULL)) {
/*!
* \note There is no need to set closer encloser to the
* name. We may find the possible wildcard child
@@ -388,57 +262,22 @@ static void knot_zone_contents_adjust_rdata_item(knot_rdata_t *rdata,
dbg_zone_verb("Trying to find wildcard child.\n");
n = knot_zone_contents_find_wildcard_child(zone,
- closest_encloser);
+ closest_encloser);
if (n != NULL) {
knot_dname_set_node(dname, (knot_node_t *)n);
dbg_zone_exec_detail(
char *name = knot_dname_to_str(
- knot_node_owner(n));
+ knot_node_owner(n));
char *name2 = knot_dname_to_str(dname);
dbg_zone_detail("Set wildcard node %s "
- "to RDATA dname %s.\n",
- name, name2);
+ "to RDATA dname %s.\n",
+ name, name2);
free(name);
free(name2);
);
}
- }
- }
-}
-
-/*----------------------------------------------------------------------------*/
-
-static int knot_zone_contents_adjust_rdata(knot_rdata_t *rdata,
- knot_rrtype_descriptor_t *desc,
- knot_zone_contents_t *zone,
- knot_node_t *node)
-{
- for (int i = 0; i < rdata->count; ++i) {
- if (desc->wireformat[i]
- == KNOT_RDATA_WF_COMPRESSED_DNAME
- || desc->wireformat[i]
- == KNOT_RDATA_WF_UNCOMPRESSED_DNAME
- || desc->wireformat[i]
- == KNOT_RDATA_WF_LITERAL_DNAME) {
- dbg_zone_detail("Adjusting domain name at position %d"
- " of the RDATA\n", i);
- knot_zone_contents_adjust_rdata_item(rdata, zone, node,
- i);
- }
- }
-
- /*
- * DS digest length check (#2050).
- */
- int ret;
- if (desc->type == KNOT_RRTYPE_DS
- && (ret = knot_rdata_ds_check(rdata)) != KNOT_EOK) {
- dbg_zone("DS RDATA check failed: %s\n", knot_strerror(ret));
- return KNOT_EMALF;
}
-
- return KNOT_EOK;
}
/*----------------------------------------------------------------------------*/
@@ -453,51 +292,18 @@ static int knot_zone_contents_adjust_rdata(knot_rdata_t *rdata,
* \param rrset RRSet to adjust RDATA in.
* \param zone Zone to which the RRSet belongs.
*/
-static int knot_zone_contents_adjust_rdata_in_rrset(knot_rrset_t *rrset,
- knot_zone_contents_t *zone,
- knot_node_t *node)
+static void knot_zone_contents_adjust_rdata_in_rrset(knot_rrset_t *rrset,
+ hattrie_t *lookup_tree,
+ knot_zone_contents_t *zone,
+ knot_node_t *node)
{
- uint16_t type = knot_rrset_type(rrset);
-
- knot_rrtype_descriptor_t *desc =
- knot_rrtype_descriptor_by_type(type);
- assert(desc);
-
- knot_rdata_t *rdata_first = knot_rrset_get_rdata(rrset);
- knot_rdata_t *rdata = rdata_first;
-
- if (rdata == NULL) {
- return KNOT_EOK;
- }
-
- int i = 1;
- int ret;
- while (rdata->next != rdata_first) {
-dbg_zone_exec_detail(
- char *name = knot_dname_to_str(knot_rrset_owner(rrset));
- dbg_zone_detail("Adjusting domain name at %d. RDATA of RRSet "
- "with owner %s and type %s.\n", i, name,
- knot_rrtype_to_string(type));
- free(name);
-);
- ret = knot_zone_contents_adjust_rdata(rdata, desc,
- zone, node);
- if (ret != KNOT_EOK) {
- return ret;
- }
-
- rdata = rdata->next;
- ++i;
+ knot_dname_t **dn = NULL;
+ while((dn = knot_rrset_get_next_dname(rrset, dn))) {
+ knot_zone_contents_adjust_rdata_dname(zone,
+ lookup_tree,
+ node,
+ dn);
}
-
-dbg_zone_exec_detail(
- char *name = knot_dname_to_str(knot_rrset_owner(rrset));
- dbg_zone_detail("Adjusting domain name at %d. RDATA of RRSet "
- "with owner %s and type %s.\n", i, name,
- knot_rrtype_to_string(type));
- free(name);
-);
- return knot_zone_contents_adjust_rdata(rdata, desc, zone, node);
}
/*----------------------------------------------------------------------------*/
@@ -512,36 +318,46 @@ dbg_zone_exec_detail(
* \param zone Zone to which the node belongs.
*/
static int knot_zone_contents_adjust_rrsets(knot_node_t *node,
- knot_zone_contents_t *zone)
+ hattrie_t *lookup_tree,
+ knot_zone_contents_t *zone)
{
- knot_rrset_t **rrsets = knot_node_get_rrsets(node);
+ knot_rrset_t **rrsets = knot_node_get_rrsets_no_copy(node);
short count = knot_node_rrset_count(node);
assert(count == 0 || rrsets != NULL);
- int ret = KNOT_EOK;
for (int r = 0; r < count; ++r) {
assert(rrsets[r] != NULL);
- dbg_zone("Adjusting next RRSet.\n");
- ret = knot_zone_contents_adjust_rdata_in_rrset(rrsets[r], zone,
- node);
+ /* Make sure that RRSet owner is the same as node's. */
+ if (node->owner != rrsets[r]->owner) {
+ knot_rrset_set_owner(rrsets[r], node->owner);
+ }
+
+ dbg_zone("Adjusting next RRSet.\n");
+ knot_rrset_dump(rrsets[r]);
+ knot_zone_contents_adjust_rdata_in_rrset(rrsets[r],
+ lookup_tree, zone,
+ node);
knot_rrset_t *rrsigs = rrsets[r]->rrsigs;
- if (ret == KNOT_EOK && rrsigs != NULL) {
+ if (rrsigs != NULL) {
dbg_zone("Adjusting next RRSIGs.\n");
- ret = knot_zone_contents_adjust_rdata_in_rrset(rrsigs,
- zone,
- node);
+ knot_rrset_dump(rrsigs);
+ knot_zone_contents_adjust_rdata_in_rrset(rrsigs,
+ lookup_tree, zone,
+ node);
}
- if (ret != KNOT_EOK) {
- break;
+ if (rrsets[r]->type == KNOT_RRTYPE_DS) {
+ int ret = knot_rrset_ds_check(rrsets[r]);
+ if (ret != KNOT_EOK) {
+ dbg_zone("DS RDATA check failed: %s\n", knot_strerror(ret));
+ return KNOT_EMALF;
+ }
}
}
- free(rrsets);
-
- return ret;
+ return KNOT_EOK;
}
/*----------------------------------------------------------------------------*/
/*!
@@ -561,15 +377,20 @@ static int knot_zone_contents_adjust_rrsets(knot_node_t *node,
* old changeset processing).
*/
static int knot_zone_contents_adjust_node(knot_node_t *node,
+ hattrie_t *lookup_tree,
knot_zone_contents_t *zone)
{
// adjust domain names in RDATA
- /*! \note Enabled again after a LONG time. Should test thoroughly. */
- int ret = knot_zone_contents_adjust_rrsets(node, zone);
+ int ret = knot_zone_contents_adjust_rrsets(node, lookup_tree,
+ zone);
if (ret != KNOT_EOK) {
return ret;
}
+// const knot_node_t *old_dname_node = node->owner->node;
+ knot_zone_contents_insert_dname_into_table(&node->owner, lookup_tree);
+// assert(node->owner->node == old_dname_node || old_dname_node == NULL);
+
// assure that owner has proper node
if (knot_dname_node(knot_node_owner(node)) == NULL) {
knot_dname_set_node(knot_node_get_owner(node), node);
@@ -582,25 +403,30 @@ static int knot_zone_contents_adjust_node(knot_node_t *node,
}
// NSEC3 node (only if NSEC3 tree is not empty)
- const knot_node_t *prev;
- const knot_node_t *nsec3;
- int match = knot_zone_contents_find_nsec3_for_name(zone,
- knot_node_owner(node),
- &nsec3, &prev);
- UNUSED(prev);
-
- if (match != KNOT_ZONE_NAME_FOUND) {
- nsec3 = NULL;
+ /*! \todo We need only exact matches, what if node has no nsec3 node? */
+ /* This is faster, as it doesn't need ordered access. */
+ knot_node_t *nsec3 = NULL;
+ knot_dname_t *nsec3_name = NULL;
+ ret = knot_zone_contents_nsec3_name(zone, knot_node_owner(node),
+ &nsec3_name);
+ if (ret == KNOT_EOK) {
+ assert(nsec3_name);
+ knot_zone_tree_get(zone->nsec3_nodes, nsec3_name, &nsec3);
+ knot_node_set_nsec3_node(node, nsec3);
+ } else if (ret == KNOT_ENSEC3PAR) {
+ knot_node_set_nsec3_node(node, NULL);
+ } else {
+ /* Something could be in DNAME. */
+ knot_dname_free(&nsec3_name);
+ return ret;
}
-
- knot_node_set_nsec3_node(node, (knot_node_t *)nsec3);
+ knot_dname_free(&nsec3_name);
dbg_zone_detail("Set flags to the node: \n");
dbg_zone_detail("Delegation point: %s\n",
- knot_node_is_deleg_point(node) ? "yes" : "no");
+ knot_node_is_deleg_point(node) ? "yes" : "no");
dbg_zone_detail("Non-authoritative: %s\n",
- knot_node_is_non_auth(node) ? "yes" : "no");
-
+ knot_node_is_non_auth(node) ? "yes" : "no");
return KNOT_EOK;
}
@@ -615,18 +441,17 @@ static int knot_zone_contents_adjust_node(knot_node_t *node,
* \param data Zone the node belongs to.
*/
static void knot_zone_contents_adjust_node_in_tree(
- knot_zone_tree_node_t *tnode, void *data)
+ knot_node_t **tnode, void *data)
{
assert(data != NULL);
assert(tnode != NULL);
- assert(tnode->node != NULL);
knot_zone_adjust_arg_t *args = (knot_zone_adjust_arg_t *)data;
- knot_node_t *node = tnode->node;
+ knot_node_t *node = *tnode;
if (args->err != KNOT_EOK) {
dbg_xfrin_detail("Error during adjusting: %s, skipping node.\n",
- knot_strerror(args->err));
+ knot_strerror(args->err));
return;
}
@@ -639,43 +464,22 @@ dbg_zone_exec_verb(
knot_zone_contents_t *zone = args->zone;
/*
- * 1) Store domain names to dname table.
- * TODO: make optional!
- */
- assert(zone->dname_table != NULL);
-
- int ret = knot_zone_contents_dnames_from_node_to_table(
- zone->dname_table, node);
- if (ret != KNOT_EOK) {
- dbg_xfrin("Failed to add dnames from adjusted node to "
- "table: %s\n", knot_strerror(ret));
- args->err = ret;
- return;
- }
-
- /*
- * 2) Do other adjusting (flags, closest enclosers, wildcard children,
+ * Do other adjusting (flags, closest enclosers, wildcard children,
* etc.).
*/
- ret = knot_zone_contents_adjust_node(node, zone);
- if (ret != KNOT_EOK) {
- dbg_xfrin("Failed to adjust node: %s\n", knot_strerror(ret));
- args->err = ret;
- return;
- }
+ args->err = knot_zone_contents_adjust_node(node, args->lookup_tree, zone);
}
/*----------------------------------------------------------------------------*/
static void knot_zone_contents_adjust_node_in_tree_ptr(
- knot_zone_tree_node_t *tnode, void *data)
+ knot_node_t **tnode, void *data)
{
assert(data != NULL);
assert(tnode != NULL);
- assert(tnode->node != NULL);
knot_zone_adjust_arg_t *args = (knot_zone_adjust_arg_t *)data;
- knot_node_t *node = tnode->node;
+ knot_node_t *node = *tnode;
dbg_zone_exec_detail(
if (knot_node_parent(node)) {
@@ -736,18 +540,17 @@ static void knot_zone_contents_adjust_node_in_tree_ptr(
* \param data Zone the node belongs to.
*/
static void knot_zone_contents_adjust_nsec3_node_in_tree(
- knot_zone_tree_node_t *tnode, void *data)
+ knot_node_t **tnode, void *data)
{
assert(data != NULL);
assert(tnode != NULL);
- assert(tnode->node != NULL);
+ knot_node_t *node = *tnode;
knot_zone_adjust_arg_t *args = (knot_zone_adjust_arg_t *)data;
- knot_node_t *node = tnode->node;
if (args->err != KNOT_EOK) {
dbg_xfrin_detail("Error during adjusting: %s, skipping node.\n",
- knot_strerror(args->err));
+ knot_strerror(args->err));
return;
}
@@ -757,32 +560,24 @@ static void knot_zone_contents_adjust_nsec3_node_in_tree(
}
/*
- * Store domain names to dname table.
+ * We assume, that NSEC3 nodes have none DNAMEs in their RDATA and
+ * that node owners are all unique. \todo Harmful?
*/
+
knot_zone_contents_t *zone = args->zone;
assert(zone != NULL);
-
- int ret = knot_zone_contents_dnames_from_node_to_table(
- zone->dname_table, node);
- if (ret != KNOT_EOK) {
- dbg_xfrin("Failed to add dnames from adjusted node to "
- "table: %s\n", knot_strerror(ret));
- args->err = ret;
- return;
- }
}
/*----------------------------------------------------------------------------*/
static void knot_zone_contents_adjust_nsec3_node_in_tree_ptr(
- knot_zone_tree_node_t *tnode, void *data)
+ knot_node_t **tnode, void *data)
{
assert(data != NULL);
assert(tnode != NULL);
- assert(tnode->node != NULL);
knot_zone_adjust_arg_t *args = (knot_zone_adjust_arg_t *)data;
- knot_node_t *node = tnode->node;
+ knot_node_t *node = *tnode;
// set previous node
knot_node_set_previous(node, args->previous_node);
@@ -796,23 +591,8 @@ static void knot_zone_contents_adjust_nsec3_node_in_tree_ptr(
}
/*----------------------------------------------------------------------------*/
-/*!
- * \brief Creates a NSEC3 hashed name for the given domain name.
- *
- * \note The zone's NSEC3PARAM record must be parsed prior to calling this
- * function (see knot_zone_load_nsec3param()).
- *
- * \param zone Zone from which to take the NSEC3 parameters.
- * \param name Domain name to hash.
- * \param nsec3_name Hashed name.
- *
- * \retval KNOT_EOK
- * \retval KNOT_ENSEC3PAR
- * \retval KNOT_ECRYPTO
- * \retval KNOT_ERROR if an error occured while creating a new domain name
- * from the hash or concatenating it with the zone name.
- */
-static int knot_zone_contents_nsec3_name(const knot_zone_contents_t *zone,
+
+int knot_zone_contents_nsec3_name(const knot_zone_contents_t *zone,
const knot_dname_t *name,
knot_dname_t **nsec3_name)
{
@@ -842,8 +622,8 @@ dbg_zone_exec_verb(
);
int res = knot_nsec3_sha1(nsec3_params, knot_dname_name(name),
- knot_dname_size(name), &hashed_name,
- &hash_size);
+ knot_dname_size(name), &hashed_name,
+ &hash_size);
if (res != 0) {
char *n = knot_dname_to_str(name);
@@ -856,29 +636,31 @@ dbg_zone_exec_verb(
dbg_zone_hex((char *)hashed_name, hash_size);
dbg_zone("\n");
- char *name_b32 = NULL;
- int32_t b32_ret = base32hex_encode_alloc(hashed_name, hash_size,
- (uint8_t **)(&name_b32));
+ uint8_t *name_b32 = NULL;
+ size_t size = base32hex_encode_alloc(hashed_name, hash_size,
+ &name_b32);
- if (b32_ret <= 0) {
+ if (size == 0) {
char *n = knot_dname_to_str(name);
dbg_zone("Error while encoding hashed name %s to base32.\n", n);
free(n);
- if (name_b32 != NULL) {
- free(name_b32);
- }
+ free(name_b32);
return KNOT_ECRYPTO;
}
- size_t size = b32_ret;
-
assert(name_b32 != NULL);
free(hashed_name);
- dbg_zone_verb("Base32-encoded hash: %s\n", name_b32);
+dbg_zone_exec_verb(
+ /* name_b32 is not 0-terminated. */
+ char b32_string[hash_size + 1];
+ memset(b32_string, 0, hash_size + 1);
+ memcpy(b32_string, name_b32, hash_size);
+ dbg_zone_verb("Base32-encoded hash: %s\n", b32_string);
+);
/* Will be returned to caller, make sure it is released after use. */
- *nsec3_name = knot_dname_new_from_str(name_b32, size, NULL);
+ *nsec3_name = knot_dname_new_from_str((char *)name_b32, size, NULL);
free(name_b32);
@@ -886,13 +668,14 @@ dbg_zone_exec_verb(
dbg_zone("Error while creating domain name for hashed name.\n");
return KNOT_ERROR;
}
+ knot_dname_to_lower(*nsec3_name);
assert(zone->apex->owner != NULL);
knot_dname_t *ret = knot_dname_cat(*nsec3_name, zone->apex->owner);
if (ret == NULL) {
dbg_zone("Error while creating NSEC3 domain name for "
- "hashed name.\n");
+ "hashed name.\n");
knot_dname_release(*nsec3_name);
return KNOT_ERROR;
}
@@ -932,7 +715,7 @@ static int knot_zone_contents_find_in_tree(knot_zone_tree_t *tree,
knot_node_t *found = NULL, *prev = NULL;
int exact_match = knot_zone_tree_get_less_or_equal(tree, name, &found,
- &prev);
+ &prev);
assert(exact_match >= 0);
*node = found;
@@ -943,201 +726,29 @@ static int knot_zone_contents_find_in_tree(knot_zone_tree_t *tree,
/*----------------------------------------------------------------------------*/
-static void knot_zone_contents_node_to_hash(knot_zone_tree_node_t *tnode,
- void *data)
-{
- assert(tnode != NULL && tnode->node != NULL
- && tnode->node->owner != NULL && data != NULL);
-
- knot_node_t *node = tnode->node;
-
- knot_zone_contents_t *zone = (knot_zone_contents_t *)data;
- /*
- * By the original approach, only authoritative nodes and delegation
- * points should be added to the hash table, but currently, all nodes
- * are being added when the zone is created (don't know why actually:),
- * so we will do no distinction here neither.
- */
-
-#ifdef USE_HASH_TABLE
- // add the node also to the hash table if authoritative, or deleg. point
- if (zone->table != NULL
- && ck_insert_item(zone->table,
- (const char *)node->owner->name,
- node->owner->size, (void *)node) != 0) {
- dbg_zone("Error inserting node into hash table!\n");
- }
-#endif
-}
-
-/*----------------------------------------------------------------------------*/
-/* CNAME chain checking */
-/*----------------------------------------------------------------------------*/
-
-typedef struct cname_chain {
- const knot_node_t *node;
- struct cname_chain *next;
-} cname_chain_t;
-
-/*----------------------------------------------------------------------------*/
-
-static int cname_chain_add(cname_chain_t **last, const knot_node_t *node)
-{
- assert(last != NULL);
-
- cname_chain_t *new_cname =
- (cname_chain_t *)malloc(sizeof(cname_chain_t));
- CHECK_ALLOC_LOG(new_cname, KNOT_ENOMEM);
-
- new_cname->node = node;
- new_cname->next = NULL;
-
- if (*last != NULL) {
- (*last)->next = new_cname;
- } else {
- *last = new_cname;
- }
-
- return KNOT_EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-
-static int cname_chain_contains(cname_chain_t *chain, const knot_node_t *node)
-{
- cname_chain_t *act = chain;
- while (act != NULL) {
- if (act->node == node) {
- return 1;
- }
- act = act->next;
- }
-
- return 0;
-}
-
-/*----------------------------------------------------------------------------*/
-
-static void cname_chain_free(cname_chain_t *chain)
-{
- cname_chain_t *act = chain;
-
- while (act != NULL) {
- chain = chain->next;
- free(act);
- act = chain;
- }
-}
-
-/*----------------------------------------------------------------------------*/
-
-typedef struct loop_check_data {
- knot_zone_contents_t *zone;
- int err;
-} loop_check_data_t;
-
-/*----------------------------------------------------------------------------*/
-
-static void knot_zone_contents_check_loops_in_tree(knot_zone_tree_node_t *tnode,
- void *data)
+static int knot_zc_nsec3_parameters_match(const knot_rrset_t *rrset,
+ const knot_nsec3_params_t *params,
+ size_t rdata_pos)
{
- assert(tnode != NULL);
- assert(tnode->node != NULL);
- assert(data != NULL);
-
- loop_check_data_t *args = (loop_check_data_t *)data;
- const knot_node_t *node = tnode->node;
-
- assert(args->zone != NULL);
-
- if (args->err != KNOT_EOK) {
- dbg_xfrin_detail("Error during CNAME loop checking, skipping "
- "node.\n");
- return;
- }
-
- // if there is CNAME in the node
- const knot_rrset_t *cname = knot_node_rrset(node, KNOT_RRTYPE_CNAME);
- cname_chain_t *chain = NULL;
- cname_chain_t **act_cname = &chain;
- int ret = 0;
-
- while (cname != NULL && !cname_chain_contains(chain, node)) {
- ret = cname_chain_add(act_cname, node);
- if (ret != KNOT_EOK) {
- cname_chain_free(chain);
- args->err = ret;
- return;
- }
- act_cname = &(*act_cname)->next;
-
- // follow the CNAME chain, including wildcards and
- // remember the nodes passed through
- const knot_dname_t *next_name = knot_rdata_cname_name(
- knot_rrset_rdata(cname));
- assert(next_name != NULL);
- const knot_node_t *next_node = knot_dname_node(next_name);
- if (next_node == NULL) {
- // try to find the name in the zone
- const knot_node_t *ce = NULL;
- ret = knot_zone_contents_find_dname_hash(
- args->zone, next_name,
- &next_node, &ce);
-
- if (ret != KNOT_ZONE_NAME_FOUND
- && ce != NULL) {
- // try to find wildcard child
- assert(knot_dname_is_subdomain(next_name,
- knot_node_owner(ce)));
- next_node = knot_node_wildcard_child(ce);
- }
-
- assert(next_node == NULL || knot_dname_compare(
- knot_node_owner(next_node), next_name) == 0
- || knot_dname_is_wildcard(knot_node_owner(next_node)));
- }
-
- if (next_node == NULL) {
- // no CNAME node to follow
- cname = NULL;
- } else {
- node = next_node;
- cname = knot_node_rrset(node, KNOT_RRTYPE_CNAME);
- }
- }
-
- if (cname != NULL) {
- // this means the node is in the chain already
- args->err = KNOT_ECNAME;
- }
-
- cname_chain_free(chain);
-}
-
-/*----------------------------------------------------------------------------*/
+ assert(rrset != NULL && params != NULL);
-static int knot_zc_nsec3_parameters_match(const knot_rdata_t *rdata,
- const knot_nsec3_params_t *params)
-{
- assert(rdata != NULL && params != NULL);
-
dbg_zone_detail("RDATA algo: %u, iterations: %u, salt length: %u, salt:"
- " %.*s\n",
- knot_rdata_nsec3_algorithm(rdata),
- knot_rdata_nsec3_iterations(rdata),
- knot_rdata_nsec3_salt_length(rdata),
- knot_rdata_nsec3_salt_length(rdata),
- knot_rdata_nsec3_salt(rdata));
+ " %.*s\n",
+ knot_rrset_rdata_nsec3_algorithm(rrset, rdata_pos),
+ knot_rrset_rdata_nsec3_iterations(rrset, rdata_pos),
+ knot_rrset_rdata_nsec3_salt_length(rrset, rdata_pos),
+ knot_rrset_rdata_nsec3_salt_length(rrset, rdata_pos),
+ knot_rrset_rdata_nsec3_salt(rrset, rdata_pos));
dbg_zone_detail("NSEC3PARAM algo: %u, iterations: %u, salt length: %u, "
- "salt: %.*s\n", params->algorithm, params->iterations,
- params->salt_length, params->salt_length, params->salt);
-
- return (knot_rdata_nsec3_algorithm(rdata) == params->algorithm
- && knot_rdata_nsec3_iterations(rdata) == params->iterations
- && knot_rdata_nsec3_salt_length(rdata) == params->salt_length
- && strncmp((const char *)knot_rdata_nsec3_salt(rdata),
- (const char *)params->salt, params->salt_length)
- == 0);
+ "salt: %.*s\n", params->algorithm, params->iterations,
+ params->salt_length, params->salt_length, params->salt);
+
+ return (knot_rrset_rdata_nsec3_algorithm(rrset, rdata_pos) == params->algorithm
+ && knot_rrset_rdata_nsec3_iterations(rrset, rdata_pos) == params->iterations
+ && knot_rrset_rdata_nsec3_salt_length(rrset, rdata_pos) == params->salt_length
+ && strncmp((const char *)knot_rrset_rdata_nsec3_salt(rrset, rdata_pos),
+ (const char *)params->salt, params->salt_length)
+ == 0);
}
/*----------------------------------------------------------------------------*/
@@ -1145,13 +756,10 @@ static int knot_zc_nsec3_parameters_match(const knot_rdata_t *rdata,
/*----------------------------------------------------------------------------*/
knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex,
- uint node_count,
- int use_domain_table,
struct knot_zone *zone)
{
- dbg_zone("Creating contents for %u nodes.\n", node_count);
knot_zone_contents_t *contents = (knot_zone_contents_t *)
- calloc(1, sizeof(knot_zone_contents_t));
+ calloc(1, sizeof(knot_zone_contents_t));
if (contents == NULL) {
ERR_ALLOC_FAILED;
return NULL;
@@ -1163,32 +771,19 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex,
contents->node_count = 1;
dbg_zone_verb("Creating tree for normal nodes.\n");
- contents->nodes = malloc(sizeof(knot_zone_tree_t));
+ contents->nodes = knot_zone_tree_create();
if (contents->nodes == NULL) {
ERR_ALLOC_FAILED;
goto cleanup;
}
dbg_zone_verb("Creating tree for NSEC3 nodes.\n");
- contents->nsec3_nodes = malloc(sizeof(knot_zone_tree_t));
+ contents->nsec3_nodes = knot_zone_tree_create();
if (contents->nsec3_nodes == NULL) {
ERR_ALLOC_FAILED;
goto cleanup;
}
- if (use_domain_table) {
- dbg_zone_verb("Creating domain name table.\n");
- contents->dname_table = knot_dname_table_new();
- if (contents->dname_table == NULL) {
- ERR_ALLOC_FAILED;
- goto cleanup;
- }
- } else {
- contents->dname_table = NULL;
- }
-
- //contents->node_count = node_count;
-
/* Initialize NSEC3 params */
dbg_zone_verb("Initializing NSEC3 parameters.\n");
contents->nsec3_params.algorithm = 0;
@@ -1197,57 +792,16 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex,
contents->nsec3_params.salt_length = 0;
contents->nsec3_params.salt = NULL;
- dbg_zone_verb("Initializing zone trees.\n");
- if (knot_zone_tree_init(contents->nodes) != KNOT_EOK
- || knot_zone_tree_init(contents->nsec3_nodes) != KNOT_EOK) {
- goto cleanup;
- }
-
dbg_zone_verb("Inserting apex into the zone tree.\n");
if (knot_zone_tree_insert(contents->nodes, apex) != KNOT_EOK) {
dbg_zone("Failed to insert apex to the zone tree.\n");
goto cleanup;
}
-#ifdef USE_HASH_TABLE
- if (node_count > 0) {
- dbg_zone_verb("Creating hash table.\n");
- contents->table = ck_create_table(node_count);
- if (contents->table == NULL) {
- goto cleanup;
- }
-
- // insert the apex into the hash table
- dbg_zone_verb("Inserting apex into the hash table.\n");
- if (ck_insert_item(contents->table,
- (const char *)knot_dname_name(
- knot_node_owner(apex)),
- knot_dname_size(knot_node_owner(apex)),
- (void *)apex) != 0) {
- ck_destroy_table(&contents->table, NULL, 0);
- goto cleanup;
- }
- } else {
- contents->table = NULL;
- }
-#endif
-
- // insert names from the apex to the domain table
- if (use_domain_table) {
- dbg_zone_verb("Inserting names from apex to table.\n");
- int rc = knot_zone_contents_dnames_from_node_to_table(
- contents->dname_table, apex);
- if (rc != KNOT_EOK) {
- ck_destroy_table(&contents->table, NULL, 0);
- goto cleanup;
- }
- }
-
return contents;
cleanup:
dbg_zone_verb("Cleaning up.\n");
- free(contents->dname_table);
free(contents->nodes);
free(contents->nsec3_nodes);
free(contents);
@@ -1259,7 +813,7 @@ cleanup:
int knot_zone_contents_gen_is_old(const knot_zone_contents_t *contents)
{
return ((contents->flags & KNOT_ZONE_FLAGS_GEN_MASK)
- == KNOT_ZONE_FLAGS_GEN_OLD);
+ == KNOT_ZONE_FLAGS_GEN_OLD);
}
/*----------------------------------------------------------------------------*/
@@ -1267,7 +821,7 @@ int knot_zone_contents_gen_is_old(const knot_zone_contents_t *contents)
int knot_zone_contents_gen_is_new(const knot_zone_contents_t *contents)
{
return ((contents->flags & KNOT_ZONE_FLAGS_GEN_MASK)
- == KNOT_ZONE_FLAGS_GEN_NEW);
+ == KNOT_ZONE_FLAGS_GEN_NEW);
}
/*----------------------------------------------------------------------------*/
@@ -1275,7 +829,7 @@ int knot_zone_contents_gen_is_new(const knot_zone_contents_t *contents)
int knot_zone_contents_gen_is_finished(const knot_zone_contents_t *contents)
{
return ((contents->flags & KNOT_ZONE_FLAGS_GEN_MASK)
- == KNOT_ZONE_FLAGS_GEN_FIN);
+ == KNOT_ZONE_FLAGS_GEN_FIN);
}
/*----------------------------------------------------------------------------*/
@@ -1307,7 +861,7 @@ void knot_zone_contents_set_gen_new_finished(knot_zone_contents_t *contents)
int knot_zone_contents_any_disabled(const knot_zone_contents_t *contents)
{
return ((contents->flags & KNOT_ZONE_FLAGS_ANY_MASK)
- == KNOT_ZONE_FLAGS_ANY);
+ == KNOT_ZONE_FLAGS_ANY);
}
/*----------------------------------------------------------------------------*/
@@ -1334,14 +888,14 @@ uint16_t knot_zone_contents_class(const knot_zone_contents_t *contents)
}
return knot_rrset_class(knot_node_rrset(contents->apex,
- KNOT_RRTYPE_SOA));
+ KNOT_RRTYPE_SOA));
}
/*----------------------------------------------------------------------------*/
int knot_zone_contents_add_node(knot_zone_contents_t *zone,
knot_node_t *node, int create_parents,
- uint8_t flags, int use_domain_table)
+ uint8_t flags)
{
if (zone == NULL || node == NULL) {
return KNOT_EINVAL;
@@ -1359,37 +913,12 @@ dbg_zone_exec_detail(
return ret;
}
- if (use_domain_table) {
- ret = knot_zone_contents_dnames_from_node_to_table(
- zone->dname_table, node);
- if (ret != KNOT_EOK) {
- dbg_zone("Failed to add dnames into table.\n");
- return ret;
- }
- }
-
ret = knot_zone_tree_insert(zone->nodes, node);
if (ret != KNOT_EOK) {
dbg_zone("Failed to insert node into zone tree.\n");
return ret;
}
-#ifdef USE_HASH_TABLE
- // add the node also to the hash table if authoritative, or deleg. point
- if (zone->table != NULL
- && ck_insert_item(zone->table,
- (const char *)node->owner->name,
- node->owner->size, (void *)node) != 0) {
- dbg_zone("Error inserting node into hash table!\n");
- knot_zone_tree_node_t *removed;
- (void)knot_zone_tree_remove(zone->nodes, knot_node_owner(node),
- &removed);
- assert(removed->node == node);
- return KNOT_EHASH;
- }
-#endif
- assert(knot_zone_contents_find_node(zone, node->owner));
-
knot_node_set_zone(node, zone->zone);
++zone->node_count;
@@ -1404,11 +933,11 @@ dbg_zone_exec_detail(
knot_dname_left_chop(knot_node_owner(node));
if(chopped == NULL) {
/* Root domain and root domain only. */
- assert(node->owner && node->owner->labels &&
+ assert(node->owner && node->owner->labels &&
node->owner->labels[0] == 0);
return KNOT_EOK;
}
-
+
if (knot_dname_compare(knot_node_owner(zone->apex), chopped) == 0) {
dbg_zone_detail("Zone apex is the parent.\n");
knot_node_set_parent(node, zone->apex);
@@ -1425,7 +954,7 @@ dbg_zone_exec_detail(
chopped != NULL) {
/* Adding new dname to zone + add to table. */
dbg_zone_detail("Creating new node.\n");
-
+
assert(chopped);
next_node = knot_node_new(chopped, NULL, flags);
if (next_node == NULL) {
@@ -1433,17 +962,13 @@ dbg_zone_exec_detail(
knot_dname_free(&chopped);
return KNOT_ENOMEM;
}
-
- if (use_domain_table) {
- ret =
- knot_zone_contents_dnames_from_node_to_table(
- zone->dname_table, next_node);
- if (ret != KNOT_EOK) {
- knot_node_free(&next_node);
- knot_dname_release(chopped);
- return ret;
- }
- }
+ //TODO possible leak
+// ret = knot_zone_contents_solve_node_dnames(zone,
+// next_node);
+// if (ret != KNOT_EOK) {
+// knot_node_free(&next_node);
+// knot_dname_release(chopped);
+// }
if (next_node->owner != chopped) {
/* Node owner was in RDATA */
@@ -1459,39 +984,16 @@ dbg_zone_exec_detail(
dbg_zone_detail("Inserting new node to zone tree.\n");
ret = knot_zone_tree_insert(zone->nodes,
- next_node);
+ next_node);
if (ret != KNOT_EOK) {
dbg_zone("Failed to insert new node "
- "to zone tree.\n");
+ "to zone tree.\n");
/*! \todo Delete the node?? */
/* Directly discard. */
knot_dname_release(chopped);
return ret;
}
-#ifdef USE_HASH_TABLE
-dbg_zone_exec_detail(
- char *name = knot_dname_to_str(
- knot_node_owner(next_node));
- dbg_zone_detail("Adding new node with owner %s to "
- "hash table.\n", name);
- free(name);
-);
-
- if (zone->table != NULL
- && ck_insert_item(zone->table,
- (const char *)knot_dname_name(
- knot_node_owner(next_node)),
- knot_dname_size(knot_node_owner(next_node)),
- (void *)next_node) != 0) {
- dbg_zone("Error inserting node into "
- "hash table!\n");
- /*! \todo Delete the node?? */
- /* Directly discard. */
- knot_dname_release(chopped);
- return KNOT_EHASH;
- }
-#endif
// set parent
knot_node_set_parent(node, next_node);
@@ -1536,8 +1038,7 @@ dbg_zone_exec_detail(
int knot_zone_contents_add_rrset(knot_zone_contents_t *zone,
knot_rrset_t *rrset, knot_node_t **node,
- knot_rrset_dupl_handling_t dupl,
- int use_domain_table)
+ knot_rrset_dupl_handling_t dupl)
{
if (zone == NULL || rrset == NULL || zone->apex == NULL
|| zone->apex->owner == NULL || node == NULL) {
@@ -1546,22 +1047,22 @@ int knot_zone_contents_add_rrset(knot_zone_contents_t *zone,
dbg_zone_exec_detail(
char *name = knot_dname_to_str(knot_rrset_owner(rrset));
- dbg_zone_detail("Adding RRSet to zone contents: %s, type %s\n",
- name, knot_rrtype_to_string(knot_rrset_type(rrset)));
+ dbg_zone_detail("Adding RRSet to zone contents: %s, type %d\n",
+ name, knot_rrset_type(rrset));
free(name);
);
// check if the RRSet belongs to the zone
if (knot_dname_compare(knot_rrset_owner(rrset),
- zone->apex->owner) != 0
+ zone->apex->owner) != 0
&& !knot_dname_is_subdomain(knot_rrset_owner(rrset),
- zone->apex->owner)) {
+ zone->apex->owner)) {
return KNOT_EBADZONE;
}
if ((*node) == NULL
&& (*node = knot_zone_contents_get_node(zone,
- knot_rrset_owner(rrset))) == NULL) {
+ knot_rrset_owner(rrset))) == NULL) {
return KNOT_ENONODE;
}
@@ -1572,9 +1073,9 @@ dbg_zone_exec_detail(
/*! \todo REMOVE RRSET */
if (dupl == KNOT_RRSET_DUPL_MERGE) {
- rc = knot_node_add_rrset_no_dupl(*node, rrset);
+ rc = knot_node_add_rrset(*node, rrset);
} else {
- rc = knot_node_add_rrset(*node, rrset, 0);
+ rc = knot_node_add_rrset_no_merge(*node, rrset);
}
if (rc < 0) {
@@ -1584,40 +1085,17 @@ dbg_zone_exec_detail(
int ret = rc;
- if (use_domain_table) {
- dbg_zone_detail("Saving RRSet to table.\n");
- rc = knot_zone_contents_dnames_from_rrset_to_table(
- zone->dname_table, rrset, 0, (*node)->owner);
- if (rc != KNOT_EOK) {
- dbg_zone("Error saving domain names from "
- "RRSIGs to the domain name table.\n "
- "The zone may be in an inconsistent state.\n");
- // WARNING: the zone is not in consistent state now -
- // there may be domain names in it that are not inserted
- // into the domain table
- return rc;
- }
- }
-
- // replace RRSet's owner with the node's owner (that is already in the
- // table)
- /*! \todo Do even if domain table is not used?? */
- if (ret == KNOT_EOK && rrset->owner != (*node)->owner) {
- knot_rrset_set_owner(rrset, (*node)->owner);
- }
-
- dbg_zone_detail("RRSet OK.\n");
+ dbg_zone_detail("RRSet OK (%d).\n", ret);
return ret;
}
/*----------------------------------------------------------------------------*/
int knot_zone_contents_add_rrsigs(knot_zone_contents_t *zone,
- knot_rrset_t *rrsigs,
- knot_rrset_t **rrset,
- knot_node_t **node,
- knot_rrset_dupl_handling_t dupl,
- int use_domain_table)
+ knot_rrset_t *rrsigs,
+ knot_rrset_t **rrset,
+ knot_node_t **node,
+ knot_rrset_dupl_handling_t dupl)
{
dbg_zone_verb("Adding RRSIGs to zone contents.\n");
@@ -1625,11 +1103,11 @@ int knot_zone_contents_add_rrsigs(knot_zone_contents_t *zone,
|| zone->apex == NULL || zone->apex->owner == NULL) {
dbg_zone_exec(
dbg_zone("Parameters: zone=%p, rrsigs=%p, rrset=%p, "
- "node=%p\n", zone, rrsigs, rrset, node);
+ "node=%p\n", zone, rrsigs, rrset, node);
if (zone != NULL) {
dbg_zone("zone->apex=%p\n", zone->apex);
if (zone->apex != NULL) {
- dbg_zone("zone->apex->owner=%p\n",
+ dbg_zone("zone->apex->owner=%p\n",
zone->apex->owner);
}
}
@@ -1640,16 +1118,16 @@ dbg_zone_exec(
// check if the RRSet belongs to the zone
if (*rrset != NULL
&& knot_dname_compare(knot_rrset_owner(*rrset),
- zone->apex->owner) != 0
+ zone->apex->owner) != 0
&& !knot_dname_is_subdomain(knot_rrset_owner(*rrset),
- zone->apex->owner)) {
+ zone->apex->owner)) {
return KNOT_EBADZONE;
}
// check if the RRSIGs belong to the RRSet
if (*rrset != NULL
&& (knot_dname_compare(knot_rrset_owner(rrsigs),
- knot_rrset_owner(*rrset)) != 0)) {
+ knot_rrset_owner(*rrset)) != 0)) {
dbg_zone("RRSIGs do not belong to the given RRSet.\n");
return KNOT_EINVAL;
}
@@ -1659,15 +1137,14 @@ dbg_zone_exec(
// even no node given
// find proper node
knot_node_t *(*get_node)(const knot_zone_contents_t *,
- const knot_dname_t *)
- = (knot_rdata_rrsig_type_covered(
- knot_rrset_rdata(rrsigs)) == KNOT_RRTYPE_NSEC3)
+ const knot_dname_t *)
+ = (knot_rrset_rdata_rrsig_type_covered(rrsigs) == KNOT_RRTYPE_NSEC3)
? knot_zone_contents_get_nsec3_node
: knot_zone_contents_get_node;
if (*node == NULL
&& (*node = get_node(
- zone, knot_rrset_owner(rrsigs))) == NULL) {
+ zone, knot_rrset_owner(rrsigs))) == NULL) {
dbg_zone("Failed to find node for RRSIGs.\n");
return KNOT_ENONODE;
}
@@ -1676,13 +1153,10 @@ dbg_zone_exec(
// find the RRSet in the node
// take only the first RDATA from the RRSIGs
- dbg_zone_detail("Finding RRSet for type %s\n",
- knot_rrtype_to_string(
- knot_rdata_rrsig_type_covered(
- knot_rrset_rdata(rrsigs))));
+ dbg_zone_detail("Finding RRSet for type %d\n",
+ knot_rrset_rdata_rrsig_type_covered(rrsigs));
*rrset = knot_node_get_rrset(
- *node, knot_rdata_rrsig_type_covered(
- knot_rrset_rdata(rrsigs)));
+ *node, knot_rrset_rdata_rrsig_type_covered(rrsigs));
if (*rrset == NULL) {
dbg_zone("Failed to find RRSet for RRSIGs.\n");
return KNOT_ENORRSET;
@@ -1704,28 +1178,6 @@ dbg_zone_exec(
ret = 1;
}
- // add all domain names from the RRSet to domain name table
- if (use_domain_table) {
- dbg_zone_detail("Saving RRSIG RRSet to table.\n");
- rc = knot_zone_contents_dnames_from_rrset_to_table(
- zone->dname_table, (*rrset)->rrsigs, 0, (*rrset)->owner);
- if (rc != KNOT_EOK) {
- dbg_zone("Error saving domain names from "
- "RRSIGs to the domain name table.\n "
- "The zone may be in an inconsistent state.\n");
- // WARNING: the zone is not in consistent state now -
- // there may be domain names in it that are not inserted
- // into the domain table
- return rc;
- }
- }
-
- // replace RRSet's owner with the node's owner (that is already in the
- // table)
- if ((*rrset)->owner != (*rrset)->rrsigs->owner) {
- knot_rrset_set_owner((*rrset)->rrsigs, (*rrset)->owner);
- }
-
dbg_zone_detail("RRSIGs OK\n");
return ret;
}
@@ -1734,7 +1186,7 @@ dbg_zone_exec(
int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *zone,
knot_node_t *node, int create_parents,
- uint8_t flags, int use_domain_table)
+ uint8_t flags)
{
UNUSED(create_parents);
UNUSED(flags);
@@ -1750,25 +1202,13 @@ int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *zone,
}
// how to know if this is successfull??
-// TREE_INSERT(zone->nsec3_nodes, knot_node, avl, node);
ret = knot_zone_tree_insert(zone->nsec3_nodes, node);
if (ret != KNOT_EOK) {
dbg_zone("Failed to insert node into NSEC3 tree: %s.\n",
- knot_strerror(ret));
+ knot_strerror(ret));
return ret;
}
- if (use_domain_table) {
- ret = knot_zone_contents_dnames_from_node_to_table(
- zone->dname_table, node);
- if (ret != KNOT_EOK) {
- /*! \todo Remove the node from the tree. */
- dbg_zone("Failed to add dnames into table: %s.\n",
- knot_strerror(ret));
- return ret;
- }
- }
-
// no parents to be created, the only parent is the zone apex
// set the apex as the parent of the node
knot_node_set_parent(node, zone->apex);
@@ -1786,8 +1226,7 @@ int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *zone,
int knot_zone_contents_add_nsec3_rrset(knot_zone_contents_t *zone,
knot_rrset_t *rrset,
knot_node_t **node,
- knot_rrset_dupl_handling_t dupl,
- int use_domain_table)
+ knot_rrset_dupl_handling_t dupl)
{
if (zone == NULL || rrset == NULL || zone->apex == NULL
|| zone->apex->owner == NULL || node == NULL) {
@@ -1796,28 +1235,26 @@ int knot_zone_contents_add_nsec3_rrset(knot_zone_contents_t *zone,
// check if the RRSet belongs to the zone
if (knot_dname_compare(knot_rrset_owner(rrset),
- zone->apex->owner) != 0
+ zone->apex->owner) != 0
&& !knot_dname_is_subdomain(knot_rrset_owner(rrset),
- zone->apex->owner)) {
+ zone->apex->owner)) {
return KNOT_EBADZONE;
}
if ((*node) == NULL
&& (*node = knot_zone_contents_get_nsec3_node(
- zone, knot_rrset_owner(rrset))) == NULL) {
+ zone, knot_rrset_owner(rrset))) == NULL) {
return KNOT_ENONODE;
}
assert(*node != NULL);
-
- // 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_no_dupl(*node, rrset);
+ rc = knot_node_add_rrset(*node, rrset);
} else {
- rc = knot_node_add_rrset(*node, rrset, 0);
+ rc = knot_node_add_rrset_no_merge(*node, rrset);
}
if (rc < 0) {
@@ -1826,37 +1263,14 @@ int knot_zone_contents_add_nsec3_rrset(knot_zone_contents_t *zone,
int ret = rc;
- if (use_domain_table) {
- dbg_zone_detail("Saving NSEC3 RRSet to table.\n");
- rc = knot_zone_contents_dnames_from_rrset_to_table(
- zone->dname_table, rrset, 0, (*node)->owner);
- if (rc != KNOT_EOK) {
- dbg_zone("Error saving domain names from "
- "RRSIGs to the domain name table.\n "
- "The zone may be in an inconsistent state.\n");
- // WARNING: the zone is not in consistent state now -
- // there may be domain names in it that are not inserted
- // into the domain table
- return rc;
- }
- }
-
- // replace RRSet's owner with the node's owner (that is already in the
- // table)
- /*! \todo Do even if domain table is not used? */
- if (rrset->owner != (*node)->owner) {
- knot_rrset_set_owner(rrset, (*node)->owner);
- }
-
dbg_zone_detail("NSEC3 OK\n");
return ret;
}
/*----------------------------------------------------------------------------*/
-int knot_zone_contents_remove_node(knot_zone_contents_t *contents,
- const knot_node_t *node, knot_zone_tree_node_t **removed_tree,
- ck_hash_table_item_t **removed_hash)
+int knot_zone_contents_remove_node(knot_zone_contents_t *contents,
+ const knot_node_t *node, knot_node_t **removed_tree)
{
if (contents == NULL || node == NULL) {
return KNOT_EINVAL;
@@ -1870,15 +1284,6 @@ dbg_zone_exec_verb(
free(name);
);
- // 1) remove the node from hash table
- *removed_hash = NULL;
- *removed_hash = ck_remove_item(contents->table,
- (const char *)knot_dname_name(owner),
- knot_dname_size(owner));
- if (*removed_hash == NULL) {
- return KNOT_ENONODE;
- }
-
// 2) remove the node from the zone tree
*removed_tree = NULL;
int ret = knot_zone_tree_remove(contents->nodes, owner, removed_tree);
@@ -1891,8 +1296,8 @@ dbg_zone_exec_verb(
/*----------------------------------------------------------------------------*/
-int knot_zone_contents_remove_nsec3_node(knot_zone_contents_t *contents,
- const knot_node_t *node, knot_zone_tree_node_t **removed)
+int knot_zone_contents_remove_nsec3_node(knot_zone_contents_t *contents,
+ const knot_node_t *node, knot_node_t **removed)
{
if (contents == NULL || node == NULL) {
return KNOT_EINVAL;
@@ -1912,56 +1317,6 @@ int knot_zone_contents_remove_nsec3_node(knot_zone_contents_t *contents,
/*----------------------------------------------------------------------------*/
-int knot_zone_contents_create_and_fill_hash_table(
- knot_zone_contents_t *zone)
-{
- if (zone == NULL || zone->apex == NULL || zone->apex->owner == NULL) {
- return KNOT_EINVAL;
- }
- /*
- * 1) Create hash table.
- */
-#ifdef USE_HASH_TABLE
- if (zone->node_count > 0) {
- zone->table = ck_create_table(zone->node_count);
- if (zone->table == NULL) {
- return KNOT_ENOMEM;
- }
-
- // insert the apex into the hash table
- if (ck_insert_item(zone->table,
- (const char *)zone->apex->owner->name,
- zone->apex->owner->size,
- (void *)zone->apex) != 0) {
- return KNOT_EHASH;
- }
- } else {
- zone->table = NULL;
- return KNOT_EOK; // OK?
- }
-
- /*
- * 2) Fill in the hash table.
- *
- * In this point, the nodes in the zone must be adjusted, so that only
- * relevant nodes (authoritative and delegation points are inserted.
- *
- * TODO: how to know if this was successful??
- */
- /*! \todo Replace by zone tree. */
- int ret = knot_zone_tree_forward_apply_inorder(zone->nodes,
- knot_zone_contents_node_to_hash, zone);
- if (ret != KNOT_EOK) {
- dbg_zone("Failed to insert nodes to hash table.\n");
- return ret;
- }
-
-#endif
- return KNOT_EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-
knot_node_t *knot_zone_contents_get_node(const knot_zone_contents_t *zone,
const knot_dname_t *name)
{
@@ -1993,7 +1348,7 @@ knot_node_t *knot_zone_contents_get_nsec3_node(
if (ret != KNOT_EOK) {
dbg_zone("Failed to find NSEC3 name in the zone tree."
- "\n");
+ "\n");
return NULL;
}
@@ -2026,7 +1381,7 @@ dbg_zone_exec_verb(
char *name_str = knot_dname_to_str(name);
char *zone_str = knot_dname_to_str(zone->apex->owner);
dbg_zone_verb("Searching for name %s in zone %s...\n",
- name_str, zone_str);
+ name_str, zone_str);
free(name_str);
free(zone_str);
);
@@ -2046,19 +1401,19 @@ dbg_zone_exec_verb(
knot_node_t *found = NULL, *prev = NULL;
int exact_match = knot_zone_contents_find_in_tree(zone->nodes, name,
- &found, &prev);
+ &found, &prev);
assert(exact_match >= 0);
*node = found;
*previous = prev;
dbg_zone_exec_detail(
char *name_str = (*node) ? knot_dname_to_str((*node)->owner)
- : "(nil)";
+ : "(nil)";
char *name_str2 = (*previous != NULL)
- ? knot_dname_to_str((*previous)->owner)
- : "(nil)";
+ ? knot_dname_to_str((*previous)->owner)
+ : "(nil)";
dbg_zone_detail("Search function returned %d, node %s (%p) and prev: %s (%p)\n",
- exact_match, name_str, *node, name_str2, *previous);
+ exact_match, name_str, *node, name_str2, *previous);
if (*node) {
free(name_str);
@@ -2118,7 +1473,7 @@ knot_node_t *knot_zone_contents_get_previous(
knot_node_t *found = NULL, *prev = NULL;
int exact_match = knot_zone_contents_find_in_tree(zone->nodes, name,
- &found, &prev);
+ &found, &prev);
assert(exact_match >= 0);
assert(prev != NULL);
@@ -2145,7 +1500,7 @@ knot_node_t *knot_zone_contents_get_previous_nsec3(
knot_node_t *found = NULL, *prev = NULL;
int exact_match = knot_zone_contents_find_in_tree(zone->nsec3_nodes,
- name, &found, &prev);
+ name, &found, &prev);
assert(exact_match >= 0);
assert(prev != NULL);
@@ -2162,99 +1517,6 @@ const knot_node_t *knot_zone_contents_find_previous_nsec3(
/*----------------------------------------------------------------------------*/
-static void knot_zone_contents_left_chop(char *name, size_t *size)
-{
- short label_size = (unsigned char)name[0];
-
- memmove(name, name + label_size + 1, *size -label_size - 1);
- *size = *size - label_size - 1;
-}
-
-/*----------------------------------------------------------------------------*/
-#ifdef USE_HASH_TABLE
-int knot_zone_contents_find_dname_hash(const knot_zone_contents_t *zone,
- const knot_dname_t *name,
- const knot_node_t **node,
- const knot_node_t **closest_encloser)
-{
- if (zone == NULL || name == NULL || node == NULL
- || closest_encloser == NULL) {
- return KNOT_EINVAL;
- }
-
-dbg_zone_exec_verb(
- char *name_str = knot_dname_to_str(name);
- char *zone_str = knot_dname_to_str(zone->apex->owner);
- dbg_zone_verb("Searching for name %s in zone %s...\n",
- name_str, zone_str);
- free(name_str);
- free(zone_str);
-);
-
- if (knot_dname_compare(name, zone->apex->owner) == 0) {
- *node = zone->apex;
- *closest_encloser = *node;
- return KNOT_ZONE_NAME_FOUND;
- }
-
- if (!knot_dname_is_subdomain(name, zone->apex->owner)) {
- *node = NULL;
- *closest_encloser = NULL;
- return KNOT_EBADZONE;
- }
-
- // temporary name used for hashing
- char name_tmp[KNOT_MAX_DNAME_LENGTH];
- size_t name_size = name->size;
- if (knot_dname_to_lower_copy(name, name_tmp, KNOT_MAX_DNAME_LENGTH)
- != KNOT_EOK) {
- return KNOT_ERROR;
- }
-
- assert(zone->table != NULL);
- const ck_hash_table_item_t *item = ck_find_item(zone->table,
- name_tmp, name_size);
-
- if (item != NULL) {
- *node = (const knot_node_t *)item->value;
- *closest_encloser = *node;
-
- dbg_zone_detail("Found node in hash table: %p (owner %p, "
- "labels: %d)\n", *node, (*node)->owner,
- knot_dname_label_count((*node)->owner));
- assert(*node != NULL);
- assert(*closest_encloser != NULL);
- return KNOT_ZONE_NAME_FOUND;
- }
-
- *node = NULL;
-
- // chop leftmost labels until some node is found
- // copy the name for chopping
-
- dbg_zone_detail("Finding closest encloser..\nStarting with: %.*s\n",
- (int)name_size, name_tmp);
-
- while (item == NULL) {
- knot_zone_contents_left_chop(name_tmp, &name_size);
-dbg_zone_exec_detail(
- dbg_zone_detail("Chopped leftmost label: %.*s\n",
- (int)name_size, name_tmp);
-);
- // not satisfied in root zone!!
- assert(name_size > 0);
-
- item = ck_find_item(zone->table, name_tmp, name_size);
- }
-
- assert(item != NULL);
- *closest_encloser = (const knot_node_t *)item->value;
-
- return KNOT_ZONE_NAME_NOT_FOUND;
-}
-#endif
-/*----------------------------------------------------------------------------*/
-
const knot_node_t *knot_zone_contents_find_nsec3_node(
const knot_zone_contents_t *zone, const knot_dname_t *name)
{
@@ -2281,7 +1543,7 @@ int knot_zone_contents_find_nsec3_for_name(const knot_zone_contents_t *zone,
}
// check if the NSEC3 tree is not empty
- if (zone->nsec3_nodes->th_root == NULL) {
+ if (knot_zone_tree_weight(zone->nsec3_nodes) == 0) {
dbg_zone("NSEC3 tree is empty.\n");
knot_dname_release(nsec3_name);
return KNOT_ENSEC3CHAIN;
@@ -2341,39 +1603,40 @@ dbg_zone_exec_detail(
}
dbg_zone_verb("find_nsec3_for_name() returning %d\n", exact_match);
-
- /* The previous may be from wrong NSEC3 chain. Search for previous
- * from the right chain. Check iterations, hash algorithm and salt
+
+ /* The previous may be from wrong NSEC3 chain. Search for previous
+ * from the right chain. Check iterations, hash algorithm and salt
* values and compare them to the ones from NSEC3PARAM.
*/
- const knot_rrset_t *nsec3_rrset = knot_node_rrset(*nsec3_previous,
- KNOT_RRTYPE_NSEC3);
- const knot_rdata_t *nsec3_rdata = (nsec3_rrset != NULL)
- ? knot_rrset_rdata(nsec3_rrset)
- : NULL;
+ const knot_rrset_t *nsec3_rrset = knot_node_rrset(*nsec3_previous,
+ KNOT_RRTYPE_NSEC3);
+ assert(nsec3_rrset);
const knot_node_t *original_prev = *nsec3_previous;
-
- while (nsec3_rdata != NULL
- && !knot_zc_nsec3_parameters_match(nsec3_rdata,
- &zone->nsec3_params)) {
- /* Try other RDATA if there are some. In case of name collision
- * the node would contain records from both NSEC3 chains.
- */
- if ((nsec3_rdata = knot_rrset_rdata_next(
- nsec3_rrset, nsec3_rdata)) != NULL) {
- continue;
+
+ int match = 0;
+
+ while (nsec3_rrset && !match) {
+ for (uint16_t i = 0;
+ i < knot_rrset_rdata_rr_count(nsec3_rrset) && !match;
+ i++) {
+ if (knot_zc_nsec3_parameters_match(nsec3_rrset,
+ &zone->nsec3_params,
+ i)) {
+ /* Matching NSEC3PARAM match at position nr.: i. */
+ match = 1;
+ }
}
-
- /* If there is none, try previous node. */
-
+
+ if (match) {
+ break;
+ }
+
+ /* This RRSET was not a match, try the one from previous node. */
*nsec3_previous = knot_node_previous(*nsec3_previous);
- nsec3_rrset = knot_node_rrset(*nsec3_previous,
- KNOT_RRTYPE_NSEC3);
- nsec3_rdata = (nsec3_rrset != NULL)
- ? knot_rrset_rdata(nsec3_rrset)
- : NULL;
-dbg_zone_exec_detail(
- char *name = (*nsec3_previous)
+ nsec3_rrset = knot_node_rrset(*nsec3_previous,
+ KNOT_RRTYPE_NSEC3);
+ dbg_zone_exec_detail(
+ char *name = (*nsec3_previous)
? knot_dname_to_str(
knot_node_owner(*nsec3_previous))
: "none";
@@ -2383,7 +1646,7 @@ dbg_zone_exec_detail(
free(name);
}
);
- if (*nsec3_previous == original_prev || nsec3_rdata == NULL) {
+ if (*nsec3_previous == original_prev || nsec3_rrset == NULL) {
// cycle
*nsec3_previous = NULL;
break;
@@ -2420,43 +1683,63 @@ knot_node_t *knot_zone_contents_get_apex(const knot_zone_contents_t *zone)
/*----------------------------------------------------------------------------*/
-int knot_zone_contents_adjust(knot_zone_contents_t *zone)
+int knot_zone_contents_adjust(knot_zone_contents_t *zone,
+ knot_node_t **first_nsec3_node,
+ knot_node_t **last_nsec3_node, int dupl_check)
{
if (zone == NULL) {
return KNOT_EINVAL;
}
+ /* Heal zone indexes. */
+ hattrie_build_index(zone->nodes);
+ hattrie_build_index(zone->nsec3_nodes);
+
// load NSEC3PARAM (needed on adjusting function)
knot_zone_contents_load_nsec3param(zone);
+ hattrie_t *lookup_tree = NULL;
+ if (dupl_check) {
+ lookup_tree = hattrie_create();
+ if (lookup_tree == NULL) {
+ dbg_zone("Failed to create out of zone lookup structure.\n");
+ return KNOT_ERROR;
+ }
+ }
+
knot_zone_adjust_arg_t adjust_arg;
adjust_arg.zone = zone;
adjust_arg.first_node = NULL;
adjust_arg.previous_node = NULL;
+ adjust_arg.lookup_tree = lookup_tree;
adjust_arg.err = KNOT_EOK;
/*
* First of all we must set node.prev pointers, as these are used in
* the search functions.
- *
- * We must also set flags, as these are required to set the prev
- * pointers well.
*/
dbg_zone("Setting 'prev' pointers to NSEC3 nodes.\n");
- int ret = knot_zone_tree_forward_apply_inorder(zone->nsec3_nodes,
- knot_zone_contents_adjust_nsec3_node_in_tree_ptr, &adjust_arg);
+ int ret = knot_zone_tree_apply_inorder(zone->nsec3_nodes,
+ knot_zone_contents_adjust_nsec3_node_in_tree_ptr, &adjust_arg);
assert(ret == KNOT_EOK);
if (adjust_arg.err != KNOT_EOK) {
dbg_zone("Failed to set 'prev' pointers to NSEC3 nodes: %s\n",
- knot_strerror(adjust_arg.err));
+ knot_strerror(adjust_arg.err));
+ hattrie_free(lookup_tree);
return adjust_arg.err;
}
// set the last node as previous of the first node
if (adjust_arg.first_node) {
knot_node_set_previous(adjust_arg.first_node,
- adjust_arg.previous_node);
+ adjust_arg.previous_node);
+ }
+ if (first_nsec3_node) {
+ *first_nsec3_node = adjust_arg.first_node;
+ }
+ if (last_nsec3_node) {
+ *last_nsec3_node = adjust_arg.previous_node;
}
dbg_zone("Done.\n");
@@ -2464,13 +1747,14 @@ int knot_zone_contents_adjust(knot_zone_contents_t *zone)
adjust_arg.previous_node = NULL;
dbg_zone("Setting 'prev' pointers to normal nodes.\n");
- ret = knot_zone_tree_forward_apply_inorder(zone->nodes,
- knot_zone_contents_adjust_node_in_tree_ptr, &adjust_arg);
+ ret = knot_zone_tree_apply_inorder(zone->nodes,
+ knot_zone_contents_adjust_node_in_tree_ptr, &adjust_arg);
assert(ret == KNOT_EOK);
if (adjust_arg.err != KNOT_EOK) {
dbg_zone("Failed to set 'prev' pointers to normal nodes: %s\n",
- knot_strerror(adjust_arg.err));
+ knot_strerror(adjust_arg.err));
+ hattrie_free(lookup_tree);
return adjust_arg.err;
}
@@ -2486,60 +1770,35 @@ int knot_zone_contents_adjust(knot_zone_contents_t *zone)
*/
dbg_zone("Adjusting NSEC3 nodes.\n");
- ret = knot_zone_tree_forward_apply_inorder(zone->nsec3_nodes,
- knot_zone_contents_adjust_nsec3_node_in_tree, &adjust_arg);
+ ret = knot_zone_tree_apply_inorder(zone->nsec3_nodes,
+ knot_zone_contents_adjust_nsec3_node_in_tree, &adjust_arg);
assert(ret == KNOT_EOK);
if (adjust_arg.err != KNOT_EOK) {
dbg_zone("Failed to adjust NSEC3 nodes: %s\n",
- knot_strerror(adjust_arg.err));
+ knot_strerror(adjust_arg.err));
+ hattrie_free(lookup_tree);
return adjust_arg.err;
}
dbg_zone("Adjusting normal nodes.\n");
- ret = knot_zone_tree_forward_apply_inorder(zone->nodes,
- knot_zone_contents_adjust_node_in_tree,
- &adjust_arg);
+ ret = knot_zone_tree_apply_inorder(zone->nodes,
+ knot_zone_contents_adjust_node_in_tree,
+ &adjust_arg);
assert(ret == KNOT_EOK);
if (adjust_arg.err != KNOT_EOK) {
dbg_zone("Failed to adjust normal nodes: %s\n",
- knot_strerror(adjust_arg.err));
+ knot_strerror(adjust_arg.err));
+ hattrie_free(lookup_tree);
return adjust_arg.err;
}
dbg_zone("Done.\n");
- return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-
-int knot_zone_contents_check_loops(knot_zone_contents_t *zone)
-{
- if (zone == NULL) {
- return KNOT_EINVAL;
- }
-
- dbg_zone("Checking CNAME and wildcard loops.\n");
-
- loop_check_data_t data;
- data.err = KNOT_EOK;
- data.zone = zone;
-
- assert(zone->nodes != NULL);
- knot_zone_tree_forward_apply_inorder(zone->nodes,
- knot_zone_contents_check_loops_in_tree,
- (void *)&data);
-
- if (data.err != KNOT_EOK) {
- dbg_zone("Found CNAME loop in data. Aborting transfer.\n");
- return data.err;
- }
+ hattrie_free(lookup_tree);
- dbg_zone("Done\n");
-
- return KNOT_EOK;
+ return ret;
}
/*----------------------------------------------------------------------------*/
@@ -2551,11 +1810,15 @@ int knot_zone_contents_load_nsec3param(knot_zone_contents_t *zone)
}
const knot_rrset_t *rrset = knot_node_rrset(zone->apex,
- KNOT_RRTYPE_NSEC3PARAM);
+ KNOT_RRTYPE_NSEC3PARAM);
if (rrset != NULL) {
int r = knot_nsec3_params_from_wire(&zone->nsec3_params, rrset);
- assert(r == KNOT_EOK);
+ if (r != KNOT_EOK) {
+ dbg_zone("Failed to load NSEC3PARAM (%s).\n",
+ knot_strerror(r));
+ return r;
+ }
} else {
memset(&zone->nsec3_params, 0, sizeof(knot_nsec3_params_t));
}
@@ -2572,7 +1835,7 @@ int knot_zone_contents_nsec3_enabled(const knot_zone_contents_t *zone)
}
return (zone->nsec3_params.algorithm != 0
- && zone->nsec3_nodes->th_root != NULL);
+ && knot_zone_tree_weight(zone->nsec3_nodes) != 0);
}
/*----------------------------------------------------------------------------*/
@@ -2593,24 +1856,6 @@ const knot_nsec3_params_t *knot_zone_contents_nsec3params(
/*----------------------------------------------------------------------------*/
-int knot_zone_contents_tree_apply_postorder(knot_zone_contents_t *zone,
- void (*function)(knot_node_t *node, void *data),
- void *data)
-{
- if (zone == NULL) {
- return KNOT_EINVAL;
- }
-
- knot_zone_tree_func_t f;
- f.func = function;
- f.data = data;
-
- return knot_zone_tree_forward_apply_postorder(zone->nodes,
- knot_zone_tree_apply, &f);
-}
-
-/*----------------------------------------------------------------------------*/
-
int knot_zone_contents_tree_apply_inorder(knot_zone_contents_t *zone,
void (*function)(knot_node_t *node, void *data),
void *data)
@@ -2623,8 +1868,8 @@ int knot_zone_contents_tree_apply_inorder(knot_zone_contents_t *zone,
f.func = function;
f.data = data;
- return knot_zone_tree_forward_apply_inorder(zone->nodes,
- knot_zone_tree_apply, &f);
+ return knot_zone_tree_apply_inorder(zone->nodes,
+ tree_apply_cb, &f);
}
/*----------------------------------------------------------------------------*/
@@ -2641,26 +1886,8 @@ int knot_zone_contents_tree_apply_inorder_reverse(
f.func = function;
f.data = data;
- return knot_zone_tree_reverse_apply_inorder(zone->nodes,
- knot_zone_tree_apply, &f);
-}
-
-/*----------------------------------------------------------------------------*/
-
-int knot_zone_contents_nsec3_apply_postorder(knot_zone_contents_t *zone,
- void (*function)(knot_node_t *node, void *data),
- void *data)
-{
- if (zone == NULL) {
- return KNOT_EINVAL;
- }
-
- knot_zone_tree_func_t f;
- f.func = function;
- f.data = data;
-
- return knot_zone_tree_forward_apply_postorder(
- zone->nsec3_nodes, knot_zone_tree_apply, &f);
+ return knot_zone_tree_apply_recursive(zone->nodes,
+ tree_apply_cb, &f);
}
/*----------------------------------------------------------------------------*/
@@ -2677,8 +1904,8 @@ int knot_zone_contents_nsec3_apply_inorder(knot_zone_contents_t *zone,
f.func = function;
f.data = data;
- return knot_zone_tree_forward_apply_inorder(
- zone->nsec3_nodes, knot_zone_tree_apply, &f);
+ return knot_zone_tree_apply_inorder(
+ zone->nsec3_nodes, tree_apply_cb, &f);
}
/*----------------------------------------------------------------------------*/
@@ -2695,8 +1922,8 @@ int knot_zone_contents_nsec3_apply_inorder_reverse(
f.func = function;
f.data = data;
- return knot_zone_tree_reverse_apply_inorder(
- zone->nsec3_nodes, knot_zone_tree_apply, &f);
+ return knot_zone_tree_apply_recursive(
+ zone->nsec3_nodes, tree_apply_cb, &f);
}
/*----------------------------------------------------------------------------*/
@@ -2717,31 +1944,6 @@ knot_zone_tree_t *knot_zone_contents_get_nsec3_nodes(
/*----------------------------------------------------------------------------*/
-ck_hash_table_t *knot_zone_contents_get_hash_table(
- knot_zone_contents_t *contents)
-{
- return contents->table;
-}
-
-/*----------------------------------------------------------------------------*/
-
-int knot_zone_contents_dname_table_apply(knot_zone_contents_t *contents,
- void (*function)(knot_dname_t *,
- void *),
- void *data)
-{
- if (contents == NULL || function == NULL) {
- return KNOT_EINVAL;
- }
-
- knot_dname_table_tree_inorder_apply(contents->dname_table,
- function, data);
-
- return KNOT_EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-
int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from,
knot_zone_contents_t **to)
{
@@ -2757,7 +1959,7 @@ int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from,
int ret = KNOT_EOK;
knot_zone_contents_t *contents = (knot_zone_contents_t *)calloc(
- 1, sizeof(knot_zone_contents_t));
+ 1, sizeof(knot_zone_contents_t));
if (contents == NULL) {
ERR_ALLOC_FAILED;
return KNOT_ENOMEM;
@@ -2765,35 +1967,6 @@ int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from,
contents->apex = from->apex;
- contents->nodes = malloc(sizeof(knot_zone_tree_t));
- if (contents->nodes == NULL) {
- ERR_ALLOC_FAILED;
- ret = KNOT_ENOMEM;
- goto cleanup;
- }
-
- contents->nsec3_nodes = malloc(sizeof(knot_zone_tree_t));
- if (contents->nsec3_nodes == NULL) {
- ERR_ALLOC_FAILED;
- ret = KNOT_ENOMEM;
- goto cleanup;
- }
-
- if (from->dname_table != NULL) {
- contents->dname_table = knot_dname_table_new();
- if (contents->dname_table == NULL) {
- ERR_ALLOC_FAILED;
- ret = KNOT_ENOMEM;
- goto cleanup;
- }
- if ((ret = knot_dname_table_shallow_copy(from->dname_table,
- contents->dname_table)) != KNOT_EOK) {
- goto cleanup;
- }
- } else {
- contents->dname_table = NULL;
- }
-
contents->node_count = from->node_count;
contents->flags = from->flags;
@@ -2804,25 +1977,12 @@ int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from,
sizeof(knot_nsec3_params_t));
if ((ret = knot_zone_tree_shallow_copy(from->nodes,
- contents->nodes)) != KNOT_EOK
+ &contents->nodes)) != KNOT_EOK
|| (ret = knot_zone_tree_shallow_copy(from->nsec3_nodes,
- contents->nsec3_nodes)) != KNOT_EOK) {
+ &contents->nsec3_nodes)) != KNOT_EOK) {
goto cleanup;
}
-#ifdef USE_HASH_TABLE
- if (from->table != NULL) {
-// ret = ck_copy_table(from->table, &contents->table);
- ret = ck_shallow_copy(from->table, &contents->table);
- if (ret != 0) {
- dbg_zone_verb("knot_zone_contents_shallow_copy: "
- "hash table copied\n");
- ret = KNOT_ERROR;
- goto cleanup;
- }
- }
-#endif
-
dbg_zone("knot_zone_contents_shallow_copy: finished OK\n");
*to = contents;
@@ -2831,7 +1991,6 @@ int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from,
cleanup:
knot_zone_tree_free(&contents->nodes);
knot_zone_tree_free(&contents->nsec3_nodes);
- free(contents->dname_table);
free(contents);
return ret;
}
@@ -2853,7 +2012,7 @@ int knot_zone_contents_shallow_copy2(const knot_zone_contents_t *from,
int ret = KNOT_EOK;
knot_zone_contents_t *contents = (knot_zone_contents_t *)calloc(
- 1, sizeof(knot_zone_contents_t));
+ 1, sizeof(knot_zone_contents_t));
if (contents == NULL) {
ERR_ALLOC_FAILED;
return KNOT_ENOMEM;
@@ -2861,35 +2020,6 @@ int knot_zone_contents_shallow_copy2(const knot_zone_contents_t *from,
//contents->apex = from->apex;
- contents->nodes = malloc(sizeof(knot_zone_tree_t));
- if (contents->nodes == NULL) {
- ERR_ALLOC_FAILED;
- ret = KNOT_ENOMEM;
- goto cleanup;
- }
-
- contents->nsec3_nodes = malloc(sizeof(knot_zone_tree_t));
- if (contents->nsec3_nodes == NULL) {
- ERR_ALLOC_FAILED;
- ret = KNOT_ENOMEM;
- goto cleanup;
- }
-
- if (from->dname_table != NULL) {
- contents->dname_table = knot_dname_table_new();
- if (contents->dname_table == NULL) {
- ERR_ALLOC_FAILED;
- ret = KNOT_ENOMEM;
- goto cleanup;
- }
- if ((ret = knot_dname_table_shallow_copy(from->dname_table,
- contents->dname_table)) != KNOT_EOK) {
- goto cleanup;
- }
- } else {
- contents->dname_table = NULL;
- }
-
contents->node_count = from->node_count;
contents->flags = from->flags;
// set the 'new' flag
@@ -2898,23 +2028,12 @@ int knot_zone_contents_shallow_copy2(const knot_zone_contents_t *from,
contents->zone = from->zone;
if ((ret = knot_zone_tree_deep_copy(from->nodes,
- contents->nodes)) != KNOT_EOK
+ &contents->nodes)) != KNOT_EOK
|| (ret = knot_zone_tree_deep_copy(from->nsec3_nodes,
- contents->nsec3_nodes)) != KNOT_EOK) {
+ &contents->nsec3_nodes)) != KNOT_EOK) {
goto cleanup;
}
-#ifdef USE_HASH_TABLE
- if (from->table != NULL) {
- ret = ck_deep_copy(from->table, &contents->table);
- if (ret != 0) {
- dbg_zone_verb("knot_zone_contents_shallow_copy: "
- "hash table copied\n");
- ret = KNOT_ERROR;
- goto cleanup;
- }
- }
-#endif
contents->apex = knot_node_get_new_node(from->apex);
dbg_zone("knot_zone_contents_shallow_copy: finished OK\n");
@@ -2925,7 +2044,6 @@ int knot_zone_contents_shallow_copy2(const knot_zone_contents_t *from,
cleanup:
knot_zone_tree_free(&contents->nodes);
knot_zone_tree_free(&contents->nsec3_nodes);
- free(contents->dname_table);
free(contents);
return ret;
}
@@ -2942,14 +2060,7 @@ void knot_zone_contents_free(knot_zone_contents_t **contents)
knot_zone_tree_free(&(*contents)->nodes);
knot_zone_tree_free(&(*contents)->nsec3_nodes);
-#ifdef USE_HASH_TABLE
- if ((*contents)->table != NULL) {
- ck_destroy_table(&(*contents)->table, NULL, 0);
- }
-#endif
knot_nsec3_params_free(&(*contents)->nsec3_params);
-
- knot_dname_table_free(&(*contents)->dname_table);
free(*contents);
*contents = NULL;
@@ -2957,43 +2068,28 @@ void knot_zone_contents_free(knot_zone_contents_t **contents)
/*----------------------------------------------------------------------------*/
-void knot_zone_contents_deep_free(knot_zone_contents_t **contents,
- int destroy_dname_table)
+void knot_zone_contents_deep_free(knot_zone_contents_t **contents)
{
if (contents == NULL || *contents == NULL) {
return;
}
if ((*contents) != NULL) {
-
-#ifdef USE_HASH_TABLE
- if ((*contents)->table != NULL) {
- ck_destroy_table(&(*contents)->table, NULL, 0);
- }
-#endif
/* has to go through zone twice, rdata may contain references to
node owners earlier in the zone which may be already freed */
/* NSEC3 tree is deleted first as it may contain references to
the normal tree. */
- knot_zone_tree_reverse_apply_postorder(
+ knot_zone_tree_apply_recursive(
(*contents)->nsec3_nodes,
knot_zone_contents_destroy_node_rrsets_from_tree,
(void*)1);
- knot_zone_tree_reverse_apply_postorder(
- (*contents)->nsec3_nodes,
- knot_zone_contents_destroy_node_owner_from_tree, 0);
-
- knot_zone_tree_reverse_apply_postorder(
+ knot_zone_tree_apply_recursive(
(*contents)->nodes,
knot_zone_contents_destroy_node_rrsets_from_tree,
(void*)1);
- knot_zone_tree_reverse_apply_postorder(
- (*contents)->nodes,
- knot_zone_contents_destroy_node_owner_from_tree, 0);
-
// free the zone tree, but only the structure
// (nodes are already destroyed)
dbg_zone("Destroying zone tree.\n");
@@ -3002,16 +2098,6 @@ void knot_zone_contents_deep_free(knot_zone_contents_t **contents,
knot_zone_tree_free(&(*contents)->nsec3_nodes);
knot_nsec3_params_free(&(*contents)->nsec3_params);
-
- if (destroy_dname_table) {
- /*
- * Hack, used in zcompile - destroys the table using
- * dname_free() instead of dname_retain().
- */
- knot_dname_table_destroy(&(*contents)->dname_table);
- } else {
- knot_dname_table_deep_free(&(*contents)->dname_table);
- }
}
free((*contents));
@@ -3040,7 +2126,7 @@ static void knot_zc_integrity_check_previous(const knot_node_t *node,
// first, check if the previous and next pointers are set properly
if (check_data->previous != NULL) {
char *name_prev = knot_dname_to_str(
- knot_node_owner(check_data->previous));
+ knot_node_owner(check_data->previous));
if (knot_node_previous(node) != check_data->previous) {
char *name2 = knot_dname_to_str(knot_node_owner(
@@ -3066,8 +2152,8 @@ static void knot_zc_integrity_check_flags(const knot_node_t *node,
if (node == knot_zone_contents_apex(check_data->contents)) {
if (!knot_node_is_auth(node)) {
fprintf(stderr, "Wrong flags: node %s, flags: %u. "
- "Should be non-authoritative.\n", name,
- node->flags);
+ "Should be non-authoritative.\n", name,
+ node->flags);
++check_data->errors;
}
return;
@@ -3076,12 +2162,12 @@ static void knot_zc_integrity_check_flags(const knot_node_t *node,
// check the flags
if (check_data->deleg_point != NULL
&& knot_dname_is_subdomain(knot_node_owner(node),
- knot_node_owner(check_data->deleg_point))) {
+ knot_node_owner(check_data->deleg_point))) {
// this is a non-authoritative node
if (!knot_node_is_non_auth(node)) {
fprintf(stderr, "Wrong flags: node %s, flags: %u. "
- "Should be non-authoritative.\n", name,
- node->flags);
+ "Should be non-authoritative.\n", name,
+ node->flags);
++check_data->errors;
}
} else {
@@ -3089,8 +2175,8 @@ static void knot_zc_integrity_check_flags(const knot_node_t *node,
// this is a delegation point
if (!knot_node_is_deleg_point(node)) {
fprintf(stderr, "Wrong flags: node %s, flags: "
- "%u. Should be deleg. point.\n", name,
- node->flags);
+ "%u. Should be deleg. point.\n", name,
+ node->flags);
++check_data->errors;
}
check_data->deleg_point = node;
@@ -3098,8 +2184,8 @@ static void knot_zc_integrity_check_flags(const knot_node_t *node,
// this is an authoritative node
if (!knot_node_is_auth(node)) {
fprintf(stderr, "Wrong flags: node %s, flags: "
- "%u. Should be authoritative.\n", name,
- node->flags);
+ "%u. Should be authoritative.\n", name,
+ node->flags);
++check_data->errors;
}
check_data->deleg_point = NULL;
@@ -3139,11 +2225,11 @@ static void knot_zc_integrity_check_parent(const knot_node_t *node,
const knot_node_t *parent = knot_node_parent(node);
if (parent != check_data->parent) {
char *name2 = (parent != NULL)
- ? knot_dname_to_str(
- knot_node_owner(parent))
- : "none";
+ ? knot_dname_to_str(
+ knot_node_owner(parent))
+ : "none";
fprintf(stderr, "Wrong parent: node %s, parent %s. "
- " Should be %s\n", name, name2, pname);
+ " Should be %s\n", name, name2, pname);
if (parent != NULL) {
free(name2);
}
@@ -3157,14 +2243,14 @@ static void knot_zc_integrity_check_parent(const knot_node_t *node,
&& knot_node_wildcard_child(check_data->parent)
!= node) {
char *wc = (knot_node_wildcard_child(
- check_data->parent) == NULL)
+ check_data->parent) == NULL)
? strdup("none")
: knot_dname_to_str(knot_node_owner(
- knot_node_wildcard_child(
- check_data->parent)));
+ knot_node_wildcard_child(
+ check_data->parent)));
fprintf(stderr, "Wrong wildcard child: node %s,"
- " wildcard child: %s. Should be %s\n",
- pname, wc, name);
+ " wildcard child: %s. Should be %s\n",
+ pname, wc, name);
if (knot_node_wildcard_child(
check_data->parent) != NULL) {
}
@@ -3181,24 +2267,6 @@ static void knot_zc_integrity_check_parent(const knot_node_t *node,
/*----------------------------------------------------------------------------*/
-static void knot_zc_integrity_check_rrset_count(const knot_node_t *node,
- check_data_t *check_data,
- const char *name)
-{
- // count RRSets
- int real_count = knot_node_count_rrsets(node);
- int count = knot_node_rrset_count(node);
-
- if (count != real_count) {
- fprintf(stderr, "Wrong RRSet count: node %s, count %d. "
- "Should be %d\n", name, count, real_count);
-
- ++check_data->errors;
- }
-}
-
-/*----------------------------------------------------------------------------*/
-
typedef struct find_dname_data {
const knot_dname_t *to_find;
const knot_dname_t *found;
@@ -3206,132 +2274,25 @@ typedef struct find_dname_data {
/*----------------------------------------------------------------------------*/
-void find_in_dname_table(knot_dname_t *dname, void *data)
-{
- assert(dname != NULL);
- assert(data != NULL);
-
- find_dname_data_t *fdata = (find_dname_data_t *)data;
-
- if (fdata->found != NULL) {
- return;
- }
-
- if (knot_dname_compare(dname, fdata->to_find) == 0) {
- fdata->found = dname;
- }
-}
-
-/*----------------------------------------------------------------------------*/
-
-static int knot_zc_integrity_check_find_dname(const knot_zone_contents_t *zone,
- const knot_dname_t *to_find,
- const char *node_name)
-{
- int ret = 0;
- if (!zone || !to_find || !node_name) {
- return KNOT_EINVAL;
- }
-
- knot_dname_t *found = knot_dname_table_find_dname(zone->dname_table,
- (knot_dname_t *)to_find);
-
- char *to_find_name = knot_dname_to_str(to_find);
-
- if (!found || found != to_find) {
- fprintf(stderr, "Dname not stored in dname table: "
- "node %s, name %s, found some dname: %s\n", node_name,
- to_find_name, (found != NULL) ? "yes" : "no");
- fprintf(stderr, "Dname to find: %p, found dname: %p\n",
- found, to_find);
- ret = 1;
- }
-
- free(to_find_name);
-
- knot_dname_release(found);
-
- return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-
static void knot_zc_integrity_check_owner(const knot_node_t *node,
check_data_t *check_data,
const char *name)
{
// check node stored in owner
const knot_node_t *owner_node =
- knot_dname_node(knot_node_owner(node));
+ knot_dname_node(knot_node_owner(node));
if (owner_node != node) {
char *name2 = (owner_node != NULL)
- ? knot_dname_to_str(knot_node_owner(owner_node))
- : "none";
+ ? knot_dname_to_str(knot_node_owner(owner_node))
+ : "none";
fprintf(stderr, "Wrong owner's node: node %s, owner's node %s"
- "\n", name, name2);
+ "\n", name, name2);
if (owner_node != NULL) {
free(name2);
}
++check_data->errors;
}
-
- // check if the owner is stored in dname table
- check_data->errors += knot_zc_integrity_check_find_dname(
- check_data->contents, knot_node_owner(node), name);
-}
-
-/*----------------------------------------------------------------------------*/
-
-static void knot_zc_integrity_check_dnames_in_rrset(const knot_rrset_t *rrset,
- check_data_t *check_data,
- const char *name)
-{
- // check owner of the RRSet
- check_data->errors += knot_zc_integrity_check_find_dname(
- check_data->contents,
- knot_rrset_owner(rrset), name);
-
- knot_rrtype_descriptor_t *desc = knot_rrtype_descriptor_by_type(
- knot_rrset_type(rrset));
-
- assert(desc != NULL);
-
- const knot_rdata_t *rdata = knot_rrset_rdata(rrset);
- while (rdata != NULL) {
- for (int i = 0; i < knot_rdata_item_count(rdata); ++i) {
- if (desc->wireformat[i]
- == KNOT_RDATA_WF_COMPRESSED_DNAME
- || desc->wireformat[i]
- == KNOT_RDATA_WF_UNCOMPRESSED_DNAME
- || desc->wireformat[i]
- == KNOT_RDATA_WF_LITERAL_DNAME) {
- knot_rdata_item_t *item = knot_rdata_get_item(
- rdata, i);
- check_data->errors +=
- knot_zc_integrity_check_find_dname(
- check_data->contents, item->dname, name);
- }
- }
- rdata = knot_rrset_rdata_next(rrset, rdata);
- }
-}
-
-/*----------------------------------------------------------------------------*/
-
-static void knot_zc_integrity_check_dnames(const knot_node_t *node,
- check_data_t *check_data,
- const char *name)
-{
- // check all dnames in all RRSets - both owners and in RDATA
- const knot_rrset_t **rrsets = knot_node_rrsets(node);
- if (rrsets != NULL) {
- for (int i = 0; i < knot_node_rrset_count(node); ++i) {
- knot_zc_integrity_check_dnames_in_rrset(rrsets[i],
- check_data, name);
- }
- }
- free(rrsets);
}
/*----------------------------------------------------------------------------*/
@@ -3356,15 +2317,9 @@ static void knot_zc_integrity_check_node(knot_node_t *node, void *data)
// & wildcard child
knot_zc_integrity_check_parent(node, check_data, name);
- // check RRSet count
- knot_zc_integrity_check_rrset_count(node, check_data, name);
-
// check owner
knot_zc_integrity_check_owner(node, check_data, name);
- // check dnames
- knot_zc_integrity_check_dnames(node, check_data, name);
-
/*! \todo Check NSEC3 node. */
free(name);
@@ -3390,74 +2345,70 @@ static void knot_zc_integrity_check_nsec3(knot_node_t *node, void *data)
// check if the node is child of the zone apex
if (node->parent != check_data->parent) {
fprintf(stderr, "NSEC3 node's parent is not apex. Node: %s.\n",
- name);
+ name);
++check_data->errors;
}
- // check RRSet count
- knot_zc_integrity_check_rrset_count(node, check_data, name);
-
// check owner
knot_zc_integrity_check_owner(node, check_data, name);
- // check dnames
- knot_zc_integrity_check_dnames(node, check_data, name);
-
free(name);
}
/*----------------------------------------------------------------------------*/
-void reset_child_count(knot_zone_tree_node_t *tree_node, void *data)
+void reset_child_count(knot_node_t **tnode, void *data)
{
- assert(tree_node != NULL);
+ assert(tnode != NULL);
assert(data != NULL);
+ knot_node_t *node = *tnode;
knot_node_t **apex_copy = (knot_node_t **)data;
if (*apex_copy == NULL) {
- *apex_copy = tree_node->node;
+ *apex_copy = node;
}
- if (tree_node->node != NULL) {
- tree_node->node->children = 0;
+ if (tnode != NULL) {
+ node->children = 0;
}
}
/*----------------------------------------------------------------------------*/
-void count_children(knot_zone_tree_node_t *tree_node, void *data)
+void count_children(knot_node_t **tnode, void *data)
{
UNUSED(data);
- if (tree_node->node != NULL && tree_node->node->parent != NULL) {
- assert(tree_node->node->parent->new_node != NULL);
+ knot_node_t *node = *tnode;
+ if (node != NULL && node->parent != NULL) {
+ assert(node->parent->new_node != NULL);
// fix parent pointer
- tree_node->node->parent = tree_node->node->parent->new_node;
- ++tree_node->node->parent->children;
+ node->parent = node->parent->new_node;
+ ++node->parent->children;
}
}
/*----------------------------------------------------------------------------*/
-void check_child_count(knot_zone_tree_node_t *tree_node, void *data)
+void check_child_count(knot_node_t **tnode, void *data)
{
- assert(tree_node != NULL);
+ assert(tnode != NULL);
assert(data != NULL);
check_data_t *check_data = (check_data_t *)data;
- knot_node_t *node = tree_node->node;
+ knot_node_t *node = *tnode;
// find corresponding node in the given contents
const knot_node_t *found = NULL;
found = knot_zone_contents_find_node(check_data->contents,
- knot_node_owner(node));
+ knot_node_owner(node));
assert(found != NULL);
if (knot_node_children(node) != knot_node_children(found)) {
char *name = knot_dname_to_str(knot_node_owner(node));
fprintf(stderr, "Wrong children count: node (%p) %s, count %u. "
- "Should be %u (%p)\n", found, name,
- knot_node_children(found),
- knot_node_children(node), node);
+ "Should be %u (%p)\n", found, name,
+ knot_node_children(found),
+ knot_node_children(node), node);
free(name);
++check_data->errors;
@@ -3466,26 +2417,25 @@ void check_child_count(knot_zone_tree_node_t *tree_node, void *data)
/*----------------------------------------------------------------------------*/
-static void reset_new_nodes(knot_zone_tree_node_t *tree_node, void *data)
+static void reset_new_nodes(knot_node_t **tnode, void *data)
{
- assert(tree_node != NULL);
+ assert(tnode != NULL);
UNUSED(data);
- knot_node_t *node = tree_node->node;
+ knot_node_t *node = *tnode;
knot_node_set_new_node(node, NULL);
}
/*----------------------------------------------------------------------------*/
-static void count_nsec3_nodes(knot_zone_tree_node_t *tree_node, void *data)
+static void count_nsec3_nodes(knot_node_t **tnode, void *data)
{
- assert(tree_node != NULL);
- assert(tree_node->node != NULL);
+ assert(tnode != NULL);
assert(data != NULL);
knot_node_t *apex = (knot_node_t *)data;
assert(apex != NULL);
-
+
apex->children += 1;
}
@@ -3496,44 +2446,40 @@ int knot_zc_integrity_check_child_count(check_data_t *data)
int errors = 0;
// do shallow copy of the node tree
- knot_zone_tree_t *nodes_copy = (knot_zone_tree_t *)
- malloc(sizeof(knot_zone_tree_t));
+ knot_zone_tree_t *nodes_copy = NULL;
+
+ int ret = knot_zone_tree_deep_copy(data->contents->nodes, &nodes_copy);
+ assert(ret == KNOT_EOK);
if (nodes_copy == NULL) {
return 1;
}
- knot_zone_tree_init(nodes_copy);
-
- int ret = knot_zone_tree_deep_copy(data->contents->nodes, nodes_copy);
- assert(ret == KNOT_EOK);
-
-
// set children count of all nodes to 0
// in the same walkthrough find the apex
knot_node_t *apex_copy = NULL;
- knot_zone_tree_forward_apply_inorder(nodes_copy, reset_child_count,
- (void *)&apex_copy);
+ knot_zone_tree_apply_inorder(nodes_copy, reset_child_count,
+ (void *)&apex_copy);
assert(apex_copy != NULL);
// now count children of all nodes, presuming the parent pointers are ok
- knot_zone_tree_forward_apply_inorder(nodes_copy, count_children, NULL);
+ knot_zone_tree_apply_inorder(nodes_copy, count_children, NULL);
// add count of NSEC3 nodes to the apex' children count
fprintf(stderr, "Children count of new apex before NSEC3: %d\n",
- data->contents->apex->new_node->children);
- knot_zone_tree_forward_apply_inorder(data->contents->nsec3_nodes,
- count_nsec3_nodes,
- (void *)apex_copy);
+ data->contents->apex->new_node->children);
+ knot_zone_tree_apply_inorder(data->contents->nsec3_nodes,
+ count_nsec3_nodes,
+ (void *)apex_copy);
// now compare the children counts
// iterate over the old zone and search for nodes in the copy
- knot_zone_tree_forward_apply_inorder(nodes_copy, check_child_count,
- (void *)data);
+ knot_zone_tree_apply_inorder(nodes_copy, check_child_count,
+ (void *)data);
// cleanup old zone tree - reset pointers to new node to NULL
- knot_zone_tree_forward_apply_inorder(data->contents->nodes,
- reset_new_nodes, NULL);
+ knot_zone_tree_apply_inorder(data->contents->nodes,
+ reset_new_nodes, NULL);
// destroy the shallow copy
knot_zone_tree_deep_free(&nodes_copy);
@@ -3570,8 +2516,8 @@ int knot_zone_contents_integrity_check(const knot_zone_contents_t *contents)
data.contents = contents;
int ret = knot_zone_contents_tree_apply_inorder(
- (knot_zone_contents_t *)contents,
- knot_zc_integrity_check_node, (void *)&data);
+ (knot_zone_contents_t *)contents,
+ knot_zc_integrity_check_node, (void *)&data);
assert(ret == KNOT_EOK);
// if OK, we can continue with checking children count
@@ -3585,10 +2531,74 @@ int knot_zone_contents_integrity_check(const knot_zone_contents_t *contents)
data.children = 0;
data.parent = contents->apex;
ret = knot_zone_contents_nsec3_apply_inorder(
- (knot_zone_contents_t *)contents,
- knot_zc_integrity_check_nsec3, (void *)&data);
+ (knot_zone_contents_t *)contents,
+ knot_zc_integrity_check_nsec3, (void *)&data);
assert(ret == KNOT_EOK);
return data.errors;
}
+struct dname_lookup_data {
+ const knot_dname_t *dname;
+ const knot_dname_t *found_dname;
+ int stopped;
+};
+
+static void find_dname_in_rdata(knot_node_t **tnode, void *data)
+{
+ struct dname_lookup_data *in_data = (struct dname_lookup_data *)data;
+ if (in_data->stopped) {
+ return;
+ }
+
+ /* For all RRSets in node. */
+ const knot_rrset_t **rrsets = knot_node_rrsets_no_copy(*tnode);
+ if (rrsets == NULL) {
+ return;
+ }
+
+ for (uint16_t i = 0; i < (*tnode)->rrset_count; i++) {
+ knot_dname_t **dname = NULL;
+ while ((dname = knot_rrset_get_next_dname(rrsets[i], dname))) {
+ if (*dname == in_data->dname) {
+ in_data->found_dname = *dname;
+ in_data->stopped = 1;
+ return;
+ } else if (knot_dname_compare(*dname,
+ in_data->dname) == 0) {
+ in_data->found_dname = *dname;
+ in_data->stopped = 1;
+ return;
+ }
+ }
+ }
+
+ assert(in_data->stopped == 0);
+}
+
+const knot_dname_t *knot_zone_contents_find_dname_in_rdata(
+ const knot_zone_contents_t *zone,
+ const knot_dname_t *dname)
+{
+ struct dname_lookup_data data;
+ data.stopped = 0;
+ data.dname = dname;
+ data.found_dname = NULL;
+ knot_zone_tree_apply_inorder(zone->nodes,
+ find_dname_in_rdata, &data);
+ if (data.stopped) {
+ /* Dname found. */
+ return data.found_dname;
+ } else {
+ assert(data.found_dname == NULL);
+ return NULL;
+ }
+}
+
+unsigned knot_zone_serial(const knot_zone_contents_t *zone)
+{
+ if (!zone) return 0;
+ const knot_rrset_t *soa = NULL;
+ soa = knot_node_rrset(knot_zone_contents_apex(zone), KNOT_RRTYPE_SOA);
+ return knot_rrset_rdata_soa_serial(soa);
+}