Commit a7abf624 authored by Lubos Slovak's avatar Lubos Slovak

Changes to node, zone-contents + IXFR adding node

- node_new() sets flags to node.
- fixed node_set_previous() - properly connects the node to
  the chain of nodes.
- Modified calls to node_new() in all parts of the program.
- zone_contents_add_node() sets flags to created parents,
  checks if created nodes are not wildcard children,
  properly sets the last node's parent.
- Fixed zone_contents_add_nsec3_node() (parent setting).
- zone_contents_get_previous() + find/get_previous_nsec3() added.

- Adding new node during IXFR zone update implemented.

refs #1034 @2h
parent 43a5dc12
......@@ -11,19 +11,6 @@
#include "common/tree.h"
#include "dnslib/debug.h"
/*----------------------------------------------------------------------------*/
/*! \brief Flags used to mark nodes with some property. */
enum {
/*! \brief Node is a delegation point (i.e. marking a zone cut). */
DNSLIB_NODE_FLAGS_DELEG = (uint8_t)0x01,
/*! \brief Node is not authoritative (i.e. below a zone cut). */
DNSLIB_NODE_FLAGS_NONAUTH = (uint8_t)0x02,
/*! \brief Node is old and will be removed (during update). */
DNSLIB_NODE_FLAGS_OLD = (uint8_t)0x80,
/*! \brief Node is new and should not be used while zoen is old. */
DNSLIB_NODE_FLAGS_NEW = (uint8_t)0x40
};
/*----------------------------------------------------------------------------*/
/* Non-API functions */
/*----------------------------------------------------------------------------*/
......@@ -162,7 +149,8 @@ static int compare_rrset_types(void *key1, void *key2)
/* API functions */
/*----------------------------------------------------------------------------*/
dnslib_node_t *dnslib_node_new(dnslib_dname_t *owner, dnslib_node_t *parent)
dnslib_node_t *dnslib_node_new(dnslib_dname_t *owner, dnslib_node_t *parent,
uint8_t flags)
{
dnslib_node_t *ret = (dnslib_node_t *)calloc(1, sizeof(dnslib_node_t));
if (ret == NULL) {
......@@ -173,6 +161,7 @@ dnslib_node_t *dnslib_node_new(dnslib_dname_t *owner, dnslib_node_t *parent)
ret->owner = owner;
ret->parent = parent;
ret->rrsets = skip_create_list(compare_rrset_types);
ret->flags = flags;
// ret->avl.avl_left = NULL;
// ret->avl.avl_right = NULL;
......@@ -313,6 +302,12 @@ void dnslib_node_set_previous(dnslib_node_t *node, dnslib_node_t *prev)
{
node->prev = prev;
if (prev != NULL) {
// set the prev pointer of the next node to the given node
if (prev->next != NULL) {
assert(prev->next->prev == prev);
prev->next->prev = node;
}
node->next = prev->next;
prev->next = node;
}
}
......
......@@ -74,6 +74,19 @@ struct dnslib_node {
typedef struct dnslib_node dnslib_node_t;
/*----------------------------------------------------------------------------*/
/*! \brief Flags used to mark nodes with some property. */
typedef enum {
/*! \brief Node is a delegation point (i.e. marking a zone cut). */
DNSLIB_NODE_FLAGS_DELEG = (uint8_t)0x01,
/*! \brief Node is not authoritative (i.e. below a zone cut). */
DNSLIB_NODE_FLAGS_NONAUTH = (uint8_t)0x02,
/*! \brief Node is old and will be removed (during update). */
DNSLIB_NODE_FLAGS_OLD = (uint8_t)0x80,
/*! \brief Node is new and should not be used while zoen is old. */
DNSLIB_NODE_FLAGS_NEW = (uint8_t)0x40
} dnslib_node_flags_t;
/*----------------------------------------------------------------------------*/
/*!
* \brief Creates and initializes new node structure.
......@@ -83,7 +96,8 @@ typedef struct dnslib_node dnslib_node_t;
*
* \return Newly created node or NULL if an error occured.
*/
dnslib_node_t *dnslib_node_new(dnslib_dname_t *owner, dnslib_node_t *parent);
dnslib_node_t *dnslib_node_new(dnslib_dname_t *owner, dnslib_node_t *parent,
uint8_t flags);
/*!
* \brief Adds an RRSet to the node.
......
......@@ -52,7 +52,7 @@ static int test_node_create()
int errors = 0;
for (int i = 0; i < TEST_NODES && !errors; i++) {
tmp = dnslib_node_new(&test_nodes[i].owner,
test_nodes[i].parent);
test_nodes[i].parent, 0);
if (tmp == NULL ||
tmp->owner != &test_nodes[i].owner ||
tmp->parent != test_nodes[i].parent ||
......@@ -73,7 +73,7 @@ static int test_node_add_rrset()
for (int i = 0; i < TEST_NODES && !errors; i++) {
/* create node from test_node structure */
tmp = dnslib_node_new(&test_nodes[i].owner,
test_nodes[i].parent);
test_nodes[i].parent, 0);
rrset = &rrsets[i];
if (dnslib_node_add_rrset(tmp, rrset, 0) < 0) {
errors++;
......@@ -134,7 +134,7 @@ static int test_node_get_rrset()
for (int i = 0; i < TEST_NODES && !errors; i++) {
tmp = dnslib_node_new(&test_nodes[i].owner,
test_nodes[i].parent);
test_nodes[i].parent, 0);
nodes[i] = tmp;
for (int j = 0; j < RRSETS; j++) {
dnslib_node_add_rrset(tmp, &rrsets[j], 0);
......@@ -166,7 +166,7 @@ static int test_node_get_parent()
for (int i = 0; i < TEST_NODES && !errors; i++) {
tmp = dnslib_node_new(&test_nodes[i].owner,
test_nodes[i].parent);
test_nodes[i].parent, 0);
nodes[i] = tmp;
rrset = &rrsets[i];
dnslib_node_add_rrset(tmp, rrset, 0);
......@@ -189,7 +189,7 @@ static int test_node_sorting()
dnslib_rrset_t *rrset;
int errors = 0;
tmp = dnslib_node_new(&test_nodes[0].owner, test_nodes[0].parent);
tmp = dnslib_node_new(&test_nodes[0].owner, test_nodes[0].parent, 0);
/* Will add rrsets to node. */
......@@ -226,7 +226,7 @@ static int test_node_delete()
for (int i = 0; i < TEST_NODES; i++) {
tmp_node = dnslib_node_new(&test_nodes[i].owner,
test_nodes[i].parent);
test_nodes[i].parent, 0);
dnslib_node_free(&tmp_node, 0, 0);
......@@ -238,14 +238,14 @@ static int test_node_delete()
static int test_node_set_parent()
{
dnslib_node_t *tmp_parent = dnslib_node_new(NULL, NULL);
dnslib_node_t *tmp_parent = dnslib_node_new(NULL, NULL, 0);
int errors = 0;
dnslib_node_t *tmp_node;
for (int i = 0; i < TEST_NODES; i++) {
tmp_node = dnslib_node_new(&test_nodes[i].owner,
test_nodes[i].parent);
test_nodes[i].parent, 0);
dnslib_node_set_parent(tmp_node, tmp_parent);
......@@ -267,7 +267,7 @@ static int test_node_free_rrsets()
for (int i = 0; i < TEST_NODES; i++) {
tmp_node = dnslib_node_new(&test_nodes[i].owner,
test_nodes[i].parent);
test_nodes[i].parent, 0);
dnslib_node_free_rrsets(tmp_node, 0);
......
......@@ -67,7 +67,7 @@ static int test_zone_create(dnslib_zone_t **zone)
// assert(dname);
dnslib_node_t *node = dnslib_node_new(&test_apex.owner,
test_apex.parent);
test_apex.parent, 0);
if (node == NULL) {
diag("zone: Could not create zone apex.");
return 0;
......@@ -105,7 +105,7 @@ static int test_zone_add_node(dnslib_zone_t *zone, int nsec3)
for (int i = 0; i < TEST_NODES_GOOD; ++i) {
dnslib_node_t *node = dnslib_node_new(&test_nodes_good[i].owner,
test_nodes_good[i].parent);
test_nodes_good[i].parent, 0);
if (node == NULL) {
diag("zone: Could not create node.");
return 0;
......@@ -125,7 +125,7 @@ static int test_zone_add_node(dnslib_zone_t *zone, int nsec3)
for (int i = 0; i < TEST_NODES_BAD; ++i) {
dnslib_node_t *node = dnslib_node_new(&test_nodes_bad[i].owner,
test_nodes_bad[i].parent);
test_nodes_bad[i].parent, 0);
if (node == NULL) {
diag("zone: Could not create node.");
return 0;
......@@ -177,7 +177,7 @@ static int test_zone_add_node(dnslib_zone_t *zone, int nsec3)
if (!nsec3) {
//note("Inserting Apex again...\n");
node = dnslib_node_new(&test_apex.owner, test_apex.parent);
node = dnslib_node_new(&test_apex.owner, test_apex.parent, 0);
if (node == NULL) {
diag("zone: Could not create node.");
return 0;
......
......@@ -511,10 +511,10 @@ DEBUG_DNSLIB_ZONE(
* \retval 0 if the domain name was not found. \a node may hold any (or none)
* node. \a previous is set properly.
*/
static int dnslib_zone_contents_find_in_tree(const dnslib_zone_contents_t *zone,
static int dnslib_zone_contents_find_in_tree(dnslib_zone_tree_t *tree,
const dnslib_dname_t *name,
const dnslib_node_t **node,
const dnslib_node_t **previous)
dnslib_node_t **node,
dnslib_node_t **previous)
{
assert(zone != NULL);
assert(name != NULL);
......@@ -525,7 +525,7 @@ static int dnslib_zone_contents_find_in_tree(const dnslib_zone_contents_t *zone,
// dnslib_node_t *found2 = NULL, *prev2 = NULL;
int exact_match = dnslib_zone_tree_get_less_or_equal(
zone->nodes, name, &found, &prev);
tree, name, &found, &prev);
*node = found;
......@@ -839,7 +839,7 @@ void dnslib_zone_contents_switch_generation(dnslib_zone_contents_t *zone)
int dnslib_zone_contents_add_node(dnslib_zone_contents_t *zone,
dnslib_node_t *node, int create_parents,
int use_domain_table)
uint8_t flags, int use_domain_table)
{
if (zone == NULL || node == NULL) {
return DNSLIB_EBADARG;
......@@ -902,7 +902,7 @@ DEBUG_DNSLIB_ZONE(
= dnslib_zone_contents_get_node(zone, chopped)) == NULL) {
/* Adding new dname to zone + add to table. */
debug_dnslib_zone("Creating new node.\n");
next_node = dnslib_node_new(chopped, NULL);
next_node = dnslib_node_new(chopped, NULL, flags);
if (next_node == NULL) {
dnslib_dname_free(&chopped);
return DNSLIB_ENOMEM;
......@@ -915,7 +915,6 @@ DEBUG_DNSLIB_ZONE(
return ret;
}
}
node->parent = next_node;
if (next_node->owner != chopped) {
assert(0);
......@@ -935,6 +934,7 @@ DEBUG_DNSLIB_ZONE(
if (ret != DNSLIB_EOK) {
debug_dnslib_zone("Failed to insert new node "
"to zone tree.\n");
/*! \todo Delete the node?? */
dnslib_dname_free(&chopped);
return ret;
}
......@@ -953,14 +953,29 @@ DEBUG_DNSLIB_ZONE(
next_node->owner->size, (void *)next_node) != 0) {
debug_dnslib_zone("Error inserting node into "
"hash table!\n");
/*! \todo Delete the node?? */
dnslib_dname_free(&chopped);
return DNSLIB_EHASH;
}
// set parent
node->parent = next_node;
// check if the node is not wildcard child of the parent
if (dnslib_dname_is_wildcard(
dnslib_node_owner(node))) {
dnslib_node_set_wildcard_child(next_node, node);
}
#endif
debug_dnslib_zone("Next parent.\n");
node = next_node;
node = next_node;
chopped = dnslib_dname_left_chop(chopped);
}
// set the found parent (in the zone) as the parent of the last
// inserted node
assert(node->parent == NULL);
node->parent = next_node;
debug_dnslib_zone("Created all parents.\n");
}
dnslib_dname_free(&chopped);
......@@ -1173,6 +1188,12 @@ int dnslib_zone_contents_add_nsec3_node(dnslib_zone_contents_t *zone,
}
}
// no parents to be created, the only parent is the zone apex
// set the apex as the parent of the node
node->parent = zone->apex;
// cannot be wildcard child, so nothing to be done
return DNSLIB_EOK;
}
......@@ -1444,8 +1465,34 @@ DEBUG_DNSLIB_ZONE(
/*----------------------------------------------------------------------------*/
dnslib_node_t *dnslib_zone_contents_get_previous(
const dnslib_zone_contents_t *zone, const dnslib_dname_t *name)
{
if (zone == NULL || name == NULL) {
return NULL;
}
const dnslib_node_t *found = NULL, *prev = NULL;
(void)dnslib_zone_contents_find_in_tree(zone->nodes, name, &found,
&prev);
assert(prev != NULL);
return prev;
}
/*----------------------------------------------------------------------------*/
const dnslib_node_t *dnslib_zone_contents_find_previous(
const dnslib_zone_contents_t *zone, const dnslib_dname_t *name)
{
return dnslib_zone_contents_get_previous(zone, name);
}
/*----------------------------------------------------------------------------*/
dnslib_node_t *dnslib_zone_contents_get_previous_nsec3(
const dnslib_zone_contents_t *zone, const dnslib_dname_t *name)
{
if (zone == NULL || name == NULL) {
return NULL;
......@@ -1453,12 +1500,21 @@ const dnslib_node_t *dnslib_zone_contents_find_previous(
const dnslib_node_t *found = NULL, *prev = NULL;
(void)dnslib_zone_contents_find_in_tree(zone, name, &found, &prev);
(void)dnslib_zone_contents_find_in_tree(zone->nsec3_nodes, name, &found,
prev);
assert(prev != NULL);
return prev;
}
/*----------------------------------------------------------------------------*/
const dnslib_node_t *dnslib_zone_contents_find_previous_nsec3(
const dnslib_zone_contents_t *zone, const dnslib_dname_t *name)
{
return dnslib_zone_contents_get_previous(zone, name);
}
/*----------------------------------------------------------------------------*/
#ifdef USE_HASH_TABLE
int dnslib_zone_contents_find_dname_hash(const dnslib_zone_contents_t *zone,
......
......@@ -81,8 +81,8 @@ void dnslib_zone_contents_switch_generation(dnslib_zone_contents_t *contents);
* \retval DNSLIB_EHASH
*/
int dnslib_zone_contents_add_node(dnslib_zone_contents_t *contents,
dnslib_node_t *node,
int create_parents, int use_domain_table);
dnslib_node_t *node, int create_parents,
uint8_t flags, int use_domain_table);
/*!
* \brief Adds a RRSet to the given zone.
......@@ -222,6 +222,15 @@ int dnslib_zone_contents_find_dname(const dnslib_zone_contents_t *contents,
const dnslib_node_t *dnslib_zone_contents_find_previous(
const dnslib_zone_contents_t *contents, const dnslib_dname_t *name);
dnslib_node_t *dnslib_zone_contents_get_previous(
const dnslib_zone_contents_t *contents, const dnslib_dname_t *name);
const dnslib_node_t *dnslib_zone_contents_find_previous_nsec3(
const dnslib_zone_contents_t *contents, const dnslib_dname_t *name);
dnslib_node_t *dnslib_zone_contents_get_previous_nsec3(
const dnslib_zone_contents_t *contents, const dnslib_dname_t *name);
#ifdef USE_HASH_TABLE
/*!
* \brief Tries to find domain name in the given zone using the hash table.
......
......@@ -832,7 +832,7 @@ static dnslib_dname_t **create_dname_array(FILE *f, uint max_id)
return NULL;
}
if (read_dname->id < max_id) {
read_dname->node = dnslib_node_new(read_dname, NULL);
read_dname->node = dnslib_node_new(read_dname, NULL, 0);
if (read_dname->node == NULL) {
ERR_ALLOC_FAILED;
cleanup_id_array(array, 0, i);
......
......@@ -195,7 +195,7 @@ int dnslib_zone_tree_get(dnslib_zone_tree_t *tree, const dnslib_dname_t *owner,
// create dummy data node to use for lookup
dnslib_node_t *tmp_data = dnslib_node_new(
(dnslib_dname_t *)owner, NULL);
(dnslib_dname_t *)owner, NULL, 0);
if (tmp_data == NULL) {
free(tmp);
return DNSLIB_ENOMEM;
......@@ -254,7 +254,7 @@ int dnslib_zone_tree_get_less_or_equal(dnslib_zone_tree_t *tree,
// create dummy data node to use for lookup
dnslib_node_t *tmp_data = dnslib_node_new(
(dnslib_dname_t *)owner, NULL);
(dnslib_dname_t *)owner, NULL, 0);
if (tmp_data == NULL) {
free(tmp);
return DNSLIB_ENOMEM;
......@@ -306,7 +306,7 @@ int dnslib_zone_tree_remove(dnslib_zone_tree_t *tree,
// create dummy data node to use for lookup
dnslib_node_t *tmp_data = dnslib_node_new(
(dnslib_dname_t *)owner, NULL);
(dnslib_dname_t *)owner, NULL, 0);
if (tmp_data == NULL) {
free(tmp);
return DNSLIB_ENOMEM;
......
......@@ -335,7 +335,7 @@ DEBUG_XFR(
return KNOT_EMALF;
}
node = dnslib_node_new(rr->owner, NULL);
node = dnslib_node_new(rr->owner, NULL, 0);
if (node == NULL) {
debug_xfr("Failed to create new node.\n");
dnslib_packet_free(&packet);
......@@ -475,7 +475,7 @@ DEBUG_XFR(
if (node == NULL) {
// a new node for the RR is required but it is not
// in the zone
node = dnslib_node_new(rr->owner, NULL);
node = dnslib_node_new(rr->owner, NULL, 0);
if (node == NULL) {
debug_xfr("Failed to create new node.\n");
dnslib_packet_free(&packet);
......@@ -1684,6 +1684,45 @@ static dnslib_node_t *xfrin_add_new_node(dnslib_zone_contents_t *contents,
{
/*! \todo Implement. */
return NULL;
dnslib_node_t *node = dnslib_node_new(dnslib_rrset_get_owner(rrset),
NULL, DNSLIB_NODE_FLAGS_NEW);
if (node == NULL) {
debug_xfr("Failed to create a new node.\n");
return NULL;
}
int ret = 0;
// insert the node into zone structures and create parents if
// necessary
if (dnslib_rrset_type(rrset) == DNSLIB_RRTYPE_NSEC3) {
ret = dnslib_zone_contents_add_nsec3_node(contents, node, 1, 1);
} else {
ret = dnslib_zone_contents_add_node(contents, node, 1,
DNSLIB_NODE_FLAGS_NEW, 1);
}
if (ret != DNSLIB_EOK) {
debug_xfr("Failed to add new node to zone contents.\n");
return NULL;
}
// find previous node and connect the new one to it
dnslib_node_t *prev = NULL;
if (dnslib_rrset_type(rrset) == DNSLIB_RRTYPE_NSEC3) {
prev = dnslib_zone_contents_get_previous_nsec3(contents,
dnslib_rrset_owner(rrset));
} else {
prev = dnslib_zone_contents_get_previous(contents,
dnslib_rrset_owner(rrset));
}
// fix prev and next pointers
if (prev != NULL) {
dnslib_node_set_previous(node, prev);
}
return node;
}
/*----------------------------------------------------------------------------*/
......
......@@ -1532,7 +1532,7 @@ static dnslib_node_t *create_node(dnslib_zone_t *zone,
const dnslib_dname_t *owner))
{
dnslib_node_t *node =
dnslib_node_new(current_rrset->owner, NULL);
dnslib_node_new(current_rrset->owner, NULL, 0);
if (node_add_func(zone, node, 1, 1) != 0) {
return NULL;
}
......@@ -1816,7 +1816,7 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
dnslib_dname_t *dname =
dnslib_dname_new_from_str(name, strlen(name), NULL);
dnslib_node_t *origin_node = dnslib_node_new(dname, NULL);
dnslib_node_t *origin_node = dnslib_node_new(dname, NULL, 0);
//assert(origin_node->next == NULL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment