diff options
author | Ondřej Surý <ondrej@sury.org> | 2012-08-31 16:26:55 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2012-08-31 16:26:55 +0200 |
commit | 9a7b8a090ba4fa50fc023bdea04e83602a2ad0bb (patch) | |
tree | c7fec3e97f0b5e116f35272799d69d802267851f /src/libknot/zone/zone-contents.c | |
parent | 4355eafde2b6a80d2b8feaba30b6a884aff070d9 (diff) | |
download | knot-9a7b8a090ba4fa50fc023bdea04e83602a2ad0bb.tar.gz |
Imported Upstream version 1.1.0upstream/1.1.0
Diffstat (limited to 'src/libknot/zone/zone-contents.c')
-rwxr-xr-x[-rw-r--r--] | src/libknot/zone/zone-contents.c | 1038 |
1 files changed, 530 insertions, 508 deletions
diff --git a/src/libknot/zone/zone-contents.c b/src/libknot/zone/zone-contents.c index 19268c4..7e453a5 100644..100755 --- a/src/libknot/zone/zone-contents.c +++ b/src/libknot/zone/zone-contents.c @@ -20,6 +20,8 @@ #include "util/error.h" #include "util/debug.h" #include "common/base32hex.h" +/*! \todo XXX TODO FIXME remove once testing is done. */ +#include "zcompile/zcompile.h" #include "consts.h" /*----------------------------------------------------------------------------*/ @@ -42,7 +44,7 @@ typedef struct { const uint8_t KNOT_ZONE_FLAGS_GEN_OLD = 0; /* xxxxxx00 */ const uint8_t KNOT_ZONE_FLAGS_GEN_NEW = 1 << 0; /* xxxxxx01 */ -const uint8_t KNOT_ZONE_FLAGS_GEN_FIN = 1 << 2; /* xxxxxx10 */ +const uint8_t KNOT_ZONE_FLAGS_GEN_FIN = 1 << 1; /* xxxxxx10 */ const uint8_t KNOT_ZONE_FLAGS_GEN_MASK = 3; /* 00000011 */ const uint8_t KNOT_ZONE_FLAGS_ANY_MASK = 4; /* 00000100 */ const uint8_t KNOT_ZONE_FLAGS_ANY = 4; /* 00000100 */ @@ -91,8 +93,8 @@ 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); ); @@ -137,7 +139,7 @@ static void knot_zone_contents_destroy_node_owner_from_tree( UNUSED(data); /*!< \todo change completely! */ - knot_node_free(&tnode->node, 0); + knot_node_free(&tnode->node); } /*----------------------------------------------------------------------------*/ @@ -159,11 +161,8 @@ static int knot_zone_contents_dnames_from_rdata_to_table( == KNOT_RDATA_WF_UNCOMPRESSED_DNAME || d->wireformat[j] == KNOT_RDATA_WF_LITERAL_DNAME) { -// printf("Saving dname from rdata to dname table: " -// "%p.\n", knot_rdata_get_item(rdata, j)->dname); rc = knot_dname_table_add_dname_check(table, &knot_rdata_get_item(rdata, j)->dname); -// printf("Returned: %d\n", rc); if (rc < 0) { dbg_zone("Error: %s\n", knot_strerror(rc)); return rc; @@ -171,7 +170,7 @@ static int knot_zone_contents_dnames_from_rdata_to_table( } } - dbg_zone("RDATA OK.\n"); + dbg_zone_detail("RDATA OK.\n"); return KNOT_EOK; } @@ -187,7 +186,7 @@ static int knot_zone_contents_dnames_from_rrset_to_table( // discard the old owner and replace it with the new knot_rrset_set_owner(rrset, owner); } - dbg_zone("RRSet owner: %p\n", 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)); @@ -197,10 +196,6 @@ static int knot_zone_contents_dnames_from_rrset_to_table( return KNOT_EOK; } // for each RDATA in RRSet -// char *name = knot_dname_to_str(rrset->owner); -// char *type = knot_rrtype_to_string(rrset->type); -// printf("Storing dnames from RDATA from RRSet %s, %s\n", name, type); -// free(name); knot_rdata_t *rdata = knot_rrset_get_rdata(rrset); while (rdata != NULL) { int rc = knot_zone_contents_dnames_from_rdata_to_table(table, @@ -227,10 +222,10 @@ static int knot_zone_contents_dnames_from_node_to_table( // insert owner char *name = knot_dname_to_str(node->owner); - dbg_zone("Node owner before inserting to dname table: %p.\n", - node->owner); - dbg_zone("Node owner before inserting to dname table: %s.\n", - name); + 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); @@ -239,17 +234,18 @@ static int knot_zone_contents_dnames_from_node_to_table( return rc; } int replace_owner = (rc > 0); - dbg_zone("Node owner after inserting to dname table: %p.\n", - node->owner); + +dbg_zone_exec_detail( name = knot_dname_to_str(node->owner); - dbg_zone("Node owner after inserting to dname table: %s.\n", - name); + 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("Inserting RRSets from node to table.\n"); + 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) { @@ -264,27 +260,46 @@ static int knot_zone_contents_dnames_from_node_to_table( } /*----------------------------------------------------------------------------*/ -/*! - * \brief Finds and sets wildcard child for given node's owner. - * - * \param zone Current zone. - * \param node Node to be used. - */ -//static void find_and_set_wildcard_child(knot_zone_contents_t *zone, -// knot_node_t *node) -//{ -// knot_dname_t *chopped = knot_dname_left_chop(node->owner); -// assert(chopped); -// knot_node_t *wildcard_parent; -// wildcard_parent = -// knot_zone_contents_get_node(zone, chopped); -// knot_dname_free(&chopped); +static const knot_node_t *knot_zone_contents_find_wildcard_child( + knot_zone_contents_t *zone, const knot_node_t *closest_encloser) +{ + assert(zone != NULL); + assert(closest_encloser != NULL); + + knot_dname_t *tmp = knot_dname_new_from_str("*", 1, NULL); + CHECK_ALLOC(tmp, NULL); -// assert(wildcard_parent); /* it *has* to be there */ + knot_dname_t *wildcard = knot_dname_cat(tmp, knot_node_owner( + closest_encloser)); + if (wildcard == NULL) { + free(tmp); + return NULL; + } -// knot_node_set_wildcard_child(wildcard_parent, node); -//} + assert(wildcard == tmp); + +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); + 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); + + knot_dname_free(&wildcard); + + if (ret != KNOT_ZONE_NAME_FOUND) { + return NULL; + } else { + return found; + } +} /*----------------------------------------------------------------------------*/ /*! @@ -303,54 +318,79 @@ static int knot_zone_contents_dnames_from_node_to_table( * \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) -//{ -// return; -// 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; -// const knot_node_t *n = NULL; -// const knot_node_t *closest_encloser = NULL; -// const knot_node_t *prev = NULL; - -// if (knot_dname_is_wildcard(dname)) { -// find_and_set_wildcard_child(zone, node); -// } - -// int ret = knot_zone_contents_find_dname(zone, dname, &n, -// &closest_encloser, &prev); - -// // n = knot_zone_find_node(zone, dname); - -// if (ret == KNOT_EBADARG || ret == KNOT_EBADZONE) { -// // TODO: do some cleanup if needed -// return; -// } - -// assert(ret != KNOT_ZONE_NAME_FOUND -// || n == closest_encloser); - -// if (ret != KNOT_ZONE_NAME_FOUND -// && (closest_encloser != NULL)) { -// dbg_zone("Saving closest encloser to RDATA.\n"); -// // save pointer to the closest encloser -// knot_rdata_item_t *item = -// knot_rdata_get_item(rdata, pos); -// assert(item->dname != NULL); -// assert(item->dname->node == NULL); -// //skip_insert(list, (void *)item->dname, -// // (void *)closest_encloser->owner, NULL); -// item->dname->node = closest_encloser->owner->node; -// } -// } -//} +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 node either set or the name " + "does not belong to the zone (%p).\n", + knot_dname_node(dname)); + return; + } + + const knot_node_t *n = NULL; + const knot_node_t *closest_encloser = NULL; + const knot_node_t *prev = NULL; + + int ret = knot_zone_contents_find_dname(zone, dname, &n, + &closest_encloser, &prev); + + if (ret == KNOT_EBADARG || 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; + } + + 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 + * right away. + * Having the closest encloser saved in the dname + * would disrupt the query processing algorithms + * anyway. + */ + + dbg_zone_verb("Trying to find wildcard child.\n"); + + n = knot_zone_contents_find_wildcard_child(zone, + 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)); + char *name2 = knot_dname_to_str(dname); + dbg_zone_detail("Set wildcard node %s " + "to RDATA dname %s.\n", + name, name2); + free(name); + free(name2); + ); + } + } + } +} /*----------------------------------------------------------------------------*/ /*! @@ -364,65 +404,64 @@ static int knot_zone_contents_dnames_from_node_to_table( * \param rrset RRSet to adjust RDATA in. * \param zone Zone to which the RRSet belongs. */ -//static void knot_zone_contents_adjust_rdata_in_rrset(knot_rrset_t *rrset, -// knot_zone_contents_t *zone, -// knot_node_t *node) -//{ -// uint16_t type = knot_rrset_type(rrset); +static void knot_zone_contents_adjust_rdata_in_rrset(knot_rrset_t *rrset, + 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_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; + knot_rdata_t *rdata_first = knot_rrset_get_rdata(rrset); + knot_rdata_t *rdata = rdata_first; -// if (rdata == NULL) { -// return; -// } + if (rdata == NULL) { + return; + } -// while (rdata->next != rdata_first) { -// 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("Adjusting domain name at " -// "position %d of RDATA of record with owner " -// "%s and type %s.\n", -// i, rrset->owner->name, -// knot_rrtype_to_string(type)); - -// knot_zone_contents_adjust_rdata_item(rdata, -// zone, -// node, -// i); -// } -// } -// rdata = rdata->next; -// } + while (rdata->next != rdata_first) { + 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("Adjusting domain name at " + "position %d of RDATA of record with owner " + "%s and type %s.\n", + i, rrset->owner->name, + knot_rrtype_to_string(type)); + + knot_zone_contents_adjust_rdata_item(rdata, + zone, node, + i); + } + } + rdata = rdata->next; + } -// 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("Adjusting domain name at " -// "position %d of RDATA of record with owner " -// "%s and type %s.\n", -// i, rrset->owner->name, -// knot_rrtype_to_string(type)); - -// knot_zone_contents_adjust_rdata_item(rdata, zone, -// node, i); -// } -// } + 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("Adjusting domain name at " + "position %d of RDATA of record with owner " + "%s and type %s.\n", + i, rrset->owner->name, + knot_rrtype_to_string(type)); + + knot_zone_contents_adjust_rdata_item(rdata, zone, node, + i); + } + } -//} +} /*----------------------------------------------------------------------------*/ /*! @@ -435,32 +474,29 @@ static int knot_zone_contents_dnames_from_node_to_table( * \param node Zone node to adjust the RRSets in. * \param zone Zone to which the node belongs. */ -//static void knot_zone_contents_adjust_rrsets(knot_node_t *node, -// knot_zone_contents_t *zone) -//{ -// //return; -// knot_rrset_t **rrsets = knot_node_get_rrsets(node); -// short count = knot_node_rrset_count(node); - -// assert(count == 0 || rrsets != NULL); - -// for (int r = 0; r < count; ++r) { -// assert(rrsets[r] != NULL); -// dbg_zone("Adjusting next RRSet.\n"); -// knot_zone_contents_adjust_rdata_in_rrset(rrsets[r], zone, -// node); -// knot_rrset_t *rrsigs = rrsets[r]->rrsigs; -// if (rrsigs != NULL) { -// dbg_zone("Adjusting next RRSIGs.\n"); -// knot_zone_contents_adjust_rdata_in_rrset(rrsigs, -// zone, -// node); -// } -// } - -// free(rrsets); -//} +static void knot_zone_contents_adjust_rrsets(knot_node_t *node, + knot_zone_contents_t *zone) +{ + knot_rrset_t **rrsets = knot_node_get_rrsets(node); + short count = knot_node_rrset_count(node); + + assert(count == 0 || rrsets != NULL); + + for (int r = 0; r < count; ++r) { + assert(rrsets[r] != NULL); + dbg_zone("Adjusting next RRSet.\n"); + knot_zone_contents_adjust_rdata_in_rrset(rrsets[r], zone, + node); + knot_rrset_t *rrsigs = rrsets[r]->rrsigs; + if (rrsigs != NULL) { + dbg_zone("Adjusting next RRSIGs.\n"); + knot_zone_contents_adjust_rdata_in_rrset(rrsigs, zone, + node); + } + } + free(rrsets); +} /*----------------------------------------------------------------------------*/ /*! * \brief Adjusts zone node for faster query processing. @@ -481,35 +517,24 @@ static int knot_zone_contents_dnames_from_node_to_table( static void knot_zone_contents_adjust_node(knot_node_t *node, knot_zone_contents_t *zone) { - -dbg_zone_exec( - char *name = knot_dname_to_str(node->owner); - dbg_zone("----- Adjusting node %s -----\n", name); - free(name); -); - // adjust domain names in RDATA - /*! - * \note This is unnecessary, as the code in adjust_rdata_item() is not - * reachable anyway. However, it's not clear why we disabled the - * code, so this would need further investigation. - */ - //knot_zone_contents_adjust_rrsets(node, zone); + /*! \note Enabled again after a LONG time. Should test thoroughly. */ + knot_zone_contents_adjust_rrsets(node, zone); -dbg_zone_exec( +dbg_zone_exec_detail( if (knot_node_parent(node)) { char *name = knot_dname_to_str(knot_node_owner( knot_node_parent(node))); - dbg_zone("Parent: %s\n", name); - dbg_zone("Parent is delegation point: %s\n", + dbg_zone_detail("Parent: %s\n", name); + dbg_zone_detail("Parent is delegation point: %s\n", knot_node_is_deleg_point(knot_node_parent(node)) ? "yes" : "no"); - dbg_zone("Parent is non-authoritative: %s\n", + dbg_zone_detail("Parent is non-authoritative: %s\n", knot_node_is_non_auth(knot_node_parent(node)) ? "yes" : "no"); free(name); } else { - dbg_zone("No parent!\n"); + dbg_zone_detail("No parent!\n"); } ); // delegation point / non-authoritative node @@ -539,17 +564,19 @@ dbg_zone_exec( 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; } knot_node_set_nsec3_node(node, (knot_node_t *)nsec3); - dbg_zone("Set flags to the node: \n"); - dbg_zone("Delegation point: %s\n", - knot_node_is_deleg_point(node) ? "yes" : "no"); - dbg_zone("Non-authoritative: %s\n", - knot_node_is_non_auth(node) ? "yes" : "no"); + dbg_zone_detail("Set flags to the node: \n"); + dbg_zone_detail("Delegation point: %s\n", + knot_node_is_deleg_point(node) ? "yes" : "no"); + dbg_zone_detail("Non-authoritative: %s\n", + knot_node_is_non_auth(node) ? "yes" : "no"); } /*----------------------------------------------------------------------------*/ @@ -578,19 +605,16 @@ static void knot_zone_contents_adjust_node_in_tree( return; } - /* - * 1) Set previous node pointer. - */ - knot_node_set_previous(node, args->previous_node); +dbg_zone_exec_verb( + char *name = knot_dname_to_str(node->owner); + dbg_zone_verb("----- Adjusting node %s -----\n", name); + free(name); +); - if (args->first_node == NULL) { - args->first_node = node; - } knot_zone_contents_t *zone = args->zone; /* - * 2) Store domain names to dname table. - * + * 1) Store domain names to dname table. * TODO: make optional! */ assert(zone->dname_table != NULL); @@ -605,13 +629,35 @@ static void knot_zone_contents_adjust_node_in_tree( } /* - * 3) Do other adjusting (flags, closest enclosers, wildcard children, + * 2) Do other adjusting (flags, closest enclosers, wildcard children, * etc.). */ knot_zone_contents_adjust_node(node, zone); +} + +/*----------------------------------------------------------------------------*/ + +static void knot_zone_contents_adjust_node_in_tree_ptr( + knot_zone_tree_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; /* - * 4) Store previous node depending on the type of this node. + * 1) Set previous node pointer. + */ + knot_node_set_previous(node, args->previous_node); + + if (args->first_node == NULL) { + args->first_node = node; + } + + /* + * 2) Store previous node depending on the type of this node. */ if (!knot_node_is_non_auth(node) && knot_node_rrset_count(node) > 0) { @@ -639,8 +685,11 @@ static void knot_zone_contents_adjust_nsec3_node_in_tree( knot_zone_adjust_arg_t *args = (knot_zone_adjust_arg_t *)data; knot_node_t *node = tnode->node; - // set previous node - knot_node_set_previous(node, args->previous_node); + if (args->err != KNOT_EOK) { + dbg_xfrin_detail("Error during adjusting: %s, skipping node.\n", + knot_strerror(args->err)); + return; + } // assure that owner has proper node if (knot_dname_node(knot_node_owner(node)) == NULL) { @@ -661,6 +710,22 @@ static void knot_zone_contents_adjust_nsec3_node_in_tree( args->err = ret; return; } +} + +/*----------------------------------------------------------------------------*/ + +static void knot_zone_contents_adjust_nsec3_node_in_tree_ptr( + knot_zone_tree_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; + + // set previous node + knot_node_set_previous(node, args->previous_node); // here is nothing to consider, all nodes are the same args->previous_node = node; @@ -710,9 +775,9 @@ dbg_zone_exec( uint8_t *hashed_name = NULL; size_t hash_size = 0; -dbg_zone_exec( +dbg_zone_exec_verb( char *n = knot_dname_to_str(name); - dbg_zone("Hashing name %s.\n", n); + dbg_zone_verb("Hashing name %s.\n", n); free(n); ); @@ -737,8 +802,7 @@ dbg_zone_exec( if (size == 0) { char *n = knot_dname_to_str(name); - dbg_zone("Error while encoding hashed name %s to " - "base32.\n", n); + dbg_zone("Error while encoding hashed name %s to base32.\n", n); free(n); if (name_b32 != NULL) { free(name_b32); @@ -749,7 +813,7 @@ dbg_zone_exec( assert(name_b32 != NULL); free(hashed_name); - dbg_zone("Base32-encoded hash: %s\n", name_b32); + dbg_zone_verb("Base32-encoded hash: %s\n", name_b32); /* Will be returned to caller, make sure it is released after use. */ *nsec3_name = knot_dname_new_from_str(name_b32, size, NULL); @@ -757,8 +821,7 @@ dbg_zone_exec( free(name_b32); if (*nsec3_name == NULL) { - dbg_zone("Error while creating domain name for hashed" - " name.\n"); + dbg_zone("Error while creating domain name for hashed name.\n"); return KNOT_ERROR; } @@ -767,7 +830,7 @@ dbg_zone_exec( 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; } @@ -805,31 +868,14 @@ static int knot_zone_contents_find_in_tree(knot_zone_tree_t *tree, assert(previous != NULL); knot_node_t *found = NULL, *prev = NULL; -// knot_node_t *found2 = NULL, *prev2 = NULL; int exact_match = knot_zone_tree_get_less_or_equal(tree, name, &found, &prev); -// assert(prev != NULL); assert(exact_match >= 0); *node = found; *previous = prev; -// if (prev == NULL) { -// // either the returned node is the root of the tree, or it is -// // the leftmost node in the tree; in both cases node was found -// // set the previous node of the found node -// assert(exact_match); -// assert(found != NULL); -// *previous = knot_node_get_previous(found, 1); -// } else { -// // otherwise check if the previous node is not an empty -// // non-terminal -// *previous = (knot_node_rrset_count(prev) == 0) -// ? knot_node_get_previous(prev, 1) -// : prev; -// } - return exact_match; } @@ -852,7 +898,6 @@ static void knot_zone_contents_node_to_hash(knot_zone_tree_node_t *tnode, */ #ifdef USE_HASH_TABLE - //assert(zone->table != NULL); // add the node also to the hash table if authoritative, or deleg. point if (zone->table != NULL && ck_insert_item(zone->table, @@ -977,23 +1022,6 @@ static void knot_zone_contents_check_loops_in_tree(knot_zone_tree_node_t *tnode, args->zone, next_name, &next_node, &ce); -// char *name1 = knot_dname_to_str(next_name); -// char *name2 = (next_node != NULL) -// ? knot_dname_to_str(knot_node_owner(next_node)) -// : "none"; -// char *name3 = (ce != NULL) -// ? knot_dname_to_str(knot_node_owner(ce)) -// : "none"; -// printf("Searched: %s, found: %p (%s), %p (%s); ret: %d" -// ".\n", name1, next_node, name2, ce, name3, ret); -// free(name1); -// if (next_node != NULL) { -// free(name2); -// } -// if (ce != NULL) { -// free(name3); -// } - if (ret != KNOT_ZONE_NAME_FOUND && ce != NULL) { // try to find wildcard child @@ -1025,6 +1053,32 @@ static void knot_zone_contents_check_loops_in_tree(knot_zone_tree_node_t *tnode, } /*----------------------------------------------------------------------------*/ + +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)); + 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); +} + +/*----------------------------------------------------------------------------*/ /* API functions */ /*----------------------------------------------------------------------------*/ @@ -1041,22 +1095,19 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, return NULL; } -// printf("created cont: %p (%s)\n", -// contents, knot_dname_to_str(apex->owner)); - contents->apex = apex; contents->zone = zone; - knot_node_set_zone(apex, zone); + knot_node_set_zone(apex, contents->zone); contents->node_count = 1; - dbg_zone("Creating tree for normal nodes.\n"); + dbg_zone_verb("Creating tree for normal nodes.\n"); contents->nodes = malloc(sizeof(knot_zone_tree_t)); if (contents->nodes == NULL) { ERR_ALLOC_FAILED; goto cleanup; } - dbg_zone("Creating tree for NSEC3 nodes.\n"); + dbg_zone_verb("Creating tree for NSEC3 nodes.\n"); contents->nsec3_nodes = malloc(sizeof(knot_zone_tree_t)); if (contents->nsec3_nodes == NULL) { ERR_ALLOC_FAILED; @@ -1064,7 +1115,7 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, } if (use_domain_table) { - dbg_zone("Creating domain name table.\n"); + dbg_zone_verb("Creating domain name table.\n"); contents->dname_table = knot_dname_table_new(); if (contents->dname_table == NULL) { ERR_ALLOC_FAILED; @@ -1077,20 +1128,20 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, //contents->node_count = node_count; /* Initialize NSEC3 params */ - dbg_zone("Initializing NSEC3 parameters.\n"); + dbg_zone_verb("Initializing NSEC3 parameters.\n"); contents->nsec3_params.algorithm = 0; contents->nsec3_params.flags = 0; contents->nsec3_params.iterations = 0; contents->nsec3_params.salt_length = 0; contents->nsec3_params.salt = NULL; - dbg_zone("Initializing zone trees.\n"); + 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("Inserting apex into the zone tree.\n"); + 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; @@ -1098,14 +1149,14 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, #ifdef USE_HASH_TABLE if (node_count > 0) { - dbg_zone("Creating hash table.\n"); + 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("Inserting apex into the hash table.\n"); + 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)), @@ -1121,7 +1172,7 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, // insert names from the apex to the domain table if (use_domain_table) { - dbg_zone("Inserting names from apex to table.\n"); + 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) { @@ -1133,7 +1184,7 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, return contents; cleanup: - dbg_zone("Cleaning up.\n"); + dbg_zone_verb("Cleaning up.\n"); free(contents->dname_table); free(contents->nodes); free(contents->nsec3_nodes); @@ -1234,6 +1285,12 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, return KNOT_EBADARG; } +dbg_zone_exec_detail( + char *name = knot_dname_to_str(knot_node_owner(node)); + dbg_zone_detail("Adding node to zone: %s.\n", name); + free(name); +); + int ret = 0; if ((ret = knot_zone_contents_check_node(zone, node)) != 0) { dbg_zone("Node check failed.\n"); @@ -1257,10 +1314,6 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, } #ifdef USE_HASH_TABLE -// char *name = knot_dname_to_str(node->owner); -// dbg_zone("Adding node with owner %s to hash table.\n", name); -// free(name); - //assert(zone->table != NULL); // add the node also to the hash table if authoritative, or deleg. point if (zone->table != NULL && ck_insert_item(zone->table, @@ -1281,7 +1334,7 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, return KNOT_EOK; } - dbg_zone("Creating parents of the node.\n"); + dbg_zone_detail("Creating parents of the node.\n"); knot_dname_t *chopped = knot_dname_left_chop(knot_node_owner(node)); @@ -1293,7 +1346,7 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, } if (knot_dname_compare(knot_node_owner(zone->apex), chopped) == 0) { - dbg_zone("Zone apex is the parent.\n"); + dbg_zone_detail("Zone apex is the parent.\n"); knot_node_set_parent(node, zone->apex); // check if the node is not wildcard child of the parent @@ -1307,7 +1360,7 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, = knot_zone_contents_get_node(zone, chopped)) == NULL && chopped != NULL) { /* Adding new dname to zone + add to table. */ - dbg_zone("Creating new node.\n"); + dbg_zone_detail("Creating new node.\n"); assert(chopped); next_node = knot_node_new(chopped, NULL, flags); @@ -1322,7 +1375,7 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, knot_zone_contents_dnames_from_node_to_table( zone->dname_table, next_node); if (ret != KNOT_EOK) { - knot_node_free(&next_node, 0); + knot_node_free(&next_node); knot_dname_release(chopped); return ret; } @@ -1339,14 +1392,13 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, == NULL); assert(knot_node_owner(next_node) == chopped); - dbg_zone("Inserting new node to zone tree.\n"); -// TREE_INSERT(zone->tree, knot_node, avl, next_node); + dbg_zone_detail("Inserting new node to zone tree.\n"); ret = knot_zone_tree_insert(zone->nodes, 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); @@ -1354,11 +1406,11 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, } #ifdef USE_HASH_TABLE -dbg_zone_exec( +dbg_zone_exec_detail( char *name = knot_dname_to_str( knot_node_owner(next_node)); - dbg_zone("Adding new node with owner %s to " - "hash table.\n", name); + dbg_zone_detail("Adding new node with owner %s to " + "hash table.\n", name); free(name); ); @@ -1369,7 +1421,7 @@ dbg_zone_exec( knot_dname_size(knot_node_owner(next_node)), (void *)next_node) != 0) { dbg_zone("Error inserting node into " - "hash table!\n"); + "hash table!\n"); /*! \todo Delete the node?? */ /* Directly discard. */ knot_dname_release(chopped); @@ -1390,7 +1442,7 @@ dbg_zone_exec( ++zone->node_count; - dbg_zone("Next parent.\n"); + dbg_zone_detail("Next parent.\n"); node = next_node; knot_dname_t *chopped_last = chopped; chopped = knot_dname_left_chop(chopped); @@ -1406,7 +1458,7 @@ dbg_zone_exec( assert(knot_node_parent(node) == NULL); knot_node_set_parent(node, next_node); - dbg_zone("Created all parents.\n"); + dbg_zone_detail("Created all parents.\n"); } /* Directly discard. */ @@ -1419,15 +1471,22 @@ dbg_zone_exec( /*----------------------------------------------------------------------------*/ 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_t *rrset, knot_node_t **node, + knot_rrset_dupl_handling_t dupl, + int use_domain_table) { if (zone == NULL || rrset == NULL || zone->apex == NULL || zone->apex->owner == NULL || node == NULL) { return KNOT_EBADARG; } +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))); + free(name); +); + // check if the RRSet belongs to the zone if (knot_dname_compare(knot_rrset_owner(rrset), zone->apex->owner) != 0 @@ -1448,8 +1507,12 @@ int knot_zone_contents_add_rrset(knot_zone_contents_t *zone, int rc; /*! \todo REMOVE RRSET */ - rc = knot_node_add_rrset(*node, rrset, - dupl == KNOT_RRSET_DUPL_MERGE); + if (dupl == KNOT_RRSET_DUPL_MERGE) { + rc = knot_node_add_rrset_no_dupl(*node, rrset); + } else { + rc = knot_node_add_rrset(*node, rrset, 0); + } + if (rc < 0) { dbg_zone("Failed to add RRSet to node.\n"); return rc; @@ -1458,14 +1521,13 @@ int knot_zone_contents_add_rrset(knot_zone_contents_t *zone, int ret = rc; if (use_domain_table) { - dbg_zone("Saving RRSet to table.\n"); + 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"); + "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 @@ -1480,7 +1542,7 @@ int knot_zone_contents_add_rrset(knot_zone_contents_t *zone, knot_rrset_set_owner(rrset, (*node)->owner); } - dbg_zone("RRSet OK.\n"); + dbg_zone_detail("RRSet OK.\n"); return ret; } @@ -1493,11 +1555,13 @@ int knot_zone_contents_add_rrsigs(knot_zone_contents_t *zone, knot_rrset_dupl_handling_t dupl, int use_domain_table) { + dbg_zone_verb("Adding RRSIGs to zone contents.\n"); + if (zone == NULL || rrsigs == NULL || rrset == NULL || node == NULL || 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) { @@ -1522,7 +1586,7 @@ dbg_zone_exec( if (*rrset != NULL && (knot_dname_compare(knot_rrset_owner(rrsigs), knot_rrset_owner(*rrset)) != 0)) { - dbg_zone("RRSIGs does not belong to the given RRSet.\n"); + dbg_zone("RRSIGs do not belong to the given RRSet.\n"); return KNOT_EBADARG; } @@ -1548,8 +1612,8 @@ dbg_zone_exec( // find the RRSet in the node // take only the first RDATA from the RRSIGs - dbg_zone("Finding RRSet for type %s\n", - knot_rrtype_to_string( + dbg_zone_detail("Finding RRSet for type %s\n", + knot_rrtype_to_string( knot_rdata_rrsig_type_covered( knot_rrset_rdata(rrsigs)))); *rrset = knot_node_get_rrset( @@ -1563,28 +1627,28 @@ dbg_zone_exec( assert(*rrset != NULL); - // add all domain names from the RRSet to domain name table int rc; int ret = KNOT_EOK; rc = knot_rrset_add_rrsigs(*rrset, rrsigs, dupl); if (rc < 0) { - dbg_dname("Failed to add RRSIGs to RRSet.\n"); + dbg_zone("Failed to add RRSIGs to RRSet.\n"); return rc; } else if (rc > 0) { - assert(dupl == KNOT_RRSET_DUPL_MERGE); + assert(dupl == KNOT_RRSET_DUPL_MERGE || + dupl == KNOT_RRSET_DUPL_SKIP); ret = 1; } + // add all domain names from the RRSet to domain name table if (use_domain_table) { - dbg_zone("Saving RRSIG RRSet to table.\n"); + dbg_zone_detail("Saving RRSIG RRSet to table.\n"); rc = knot_zone_contents_dnames_from_rrset_to_table( - zone->dname_table, rrsigs, 0, (*rrset)->owner); + 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"); + "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 @@ -1598,7 +1662,7 @@ dbg_zone_exec( knot_rrset_set_owner((*rrset)->rrsigs, (*rrset)->owner); } - dbg_zone("RRSIGs OK\n"); + dbg_zone_detail("RRSIGs OK\n"); return ret; } @@ -1617,6 +1681,7 @@ int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *zone, int ret = 0; if ((ret = knot_zone_contents_check_node(zone, node)) != 0) { + dbg_zone("Failed node check: %s\n", knot_strerror(ret)); return ret; } @@ -1624,6 +1689,8 @@ int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *zone, // 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)); return ret; } @@ -1632,7 +1699,8 @@ int knot_zone_contents_add_nsec3_node(knot_zone_contents_t *zone, zone->dname_table, node); if (ret != KNOT_EOK) { /*! \todo Remove the node from the tree. */ - dbg_zone("Failed to add dnames into table.\n"); + dbg_zone("Failed to add dnames into table: %s.\n", + knot_strerror(ret)); return ret; } } @@ -1682,8 +1750,12 @@ int knot_zone_contents_add_nsec3_rrset(knot_zone_contents_t *zone, int rc; /*! \todo REMOVE RRSET */ - rc = knot_node_add_rrset(*node, rrset, - dupl == KNOT_RRSET_DUPL_MERGE); + if (dupl == KNOT_RRSET_DUPL_MERGE) { + rc = knot_node_add_rrset_no_dupl(*node, rrset); + } else { + rc = knot_node_add_rrset(*node, rrset, 0); + } + if (rc < 0) { return rc; } @@ -1691,14 +1763,13 @@ int knot_zone_contents_add_nsec3_rrset(knot_zone_contents_t *zone, int ret = rc; if (use_domain_table) { - dbg_zone("Saving NSEC3 RRSet to table.\n"); + 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"); + "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 @@ -1713,7 +1784,7 @@ int knot_zone_contents_add_nsec3_rrset(knot_zone_contents_t *zone, knot_rrset_set_owner(rrset, (*node)->owner); } - dbg_zone("NSEC3 OK\n"); + dbg_zone_detail("NSEC3 OK\n"); return ret; } @@ -1740,9 +1811,6 @@ dbg_zone_exec_verb( *removed_hash = ck_remove_item(contents->table, (const char *)knot_dname_name(owner), knot_dname_size(owner)); -// int ret = ck_detete_item(contents->table, -// (const char *)knot_dname_name(owner), -// knot_dname_size(owner), NULL, 0); if (*removed_hash == NULL) { return KNOT_ENONODE; } @@ -1837,11 +1905,6 @@ knot_node_t *knot_zone_contents_get_node(const knot_zone_contents_t *zone, return NULL; } - // create dummy node to use for lookup -// knot_node_t *tmp = knot_node_new((knot_dname_t *)name, NULL); -// knot_node_t *n = TREE_FIND(zone->tree, knot_node, avl, tmp); -// knot_node_free(&tmp, 0); - knot_node_t *n; int ret = knot_zone_tree_get(zone->nodes, name, &n); if (ret != KNOT_EOK) { @@ -1861,10 +1924,6 @@ knot_node_t *knot_zone_contents_get_nsec3_node( return NULL; } - // create dummy node to use for lookup -// knot_node_t *tmp = knot_node_new((knot_dname_t *)name, NULL); -// knot_node_t *n = TREE_FIND(zone->nsec3_nodes, knot_node, avl, tmp); -// knot_node_free(&tmp, 0); knot_node_t *n; int ret = knot_zone_tree_get(zone->nsec3_nodes, name, &n); @@ -1899,11 +1958,11 @@ int knot_zone_contents_find_dname(const knot_zone_contents_t *zone, return KNOT_EBADARG; } -dbg_zone_exec( +dbg_zone_exec_verb( char *name_str = knot_dname_to_str(name); char *zone_str = knot_dname_to_str(zone->apex->owner); - dbg_zone("Searching for name %s in zone %s...\n", - name_str, zone_str); + dbg_zone_verb("Searching for name %s in zone %s...\n", + name_str, zone_str); free(name_str); free(zone_str); ); @@ -1928,14 +1987,14 @@ dbg_zone_exec( *node = found; *previous = prev; -dbg_zone_exec( +dbg_zone_exec_detail( char *name_str = (*node) ? knot_dname_to_str((*node)->owner) : "(nil)"; char *name_str2 = (*previous != NULL) ? knot_dname_to_str((*previous)->owner) : "(nil)"; - dbg_zone("Search function returned %d, node %s and prev: %s\n", - exact_match, name_str, name_str2); +dbg_zone_detail("Search function returned %d, node %s (%p) and prev: %s (%p)\n", + exact_match, name_str, *node, name_str2, *previous); if (*node) { free(name_str); @@ -1944,19 +2003,23 @@ dbg_zone_exec( free(name_str2); } ); - - *closest_encloser = *node; - // there must be at least one node with domain name less or equal to // the searched name if the name belongs to the zone (the root) - if (*node == NULL) { + if (*node == NULL && *previous == NULL) { return KNOT_EBADZONE; } - // TODO: this could be replaced by saving pointer to closest encloser - // in node + /* This function was quite out of date. The find_in_tree() function + * may return NULL in the 'found' field, so we cannot search for the + * closest encloser from this node. + */ + + if (exact_match) { + *closest_encloser = *node; + } else { + *closest_encloser = *previous; + assert(*closest_encloser != NULL); - if (!exact_match) { int matched_labels = knot_dname_matched_labels( knot_node_owner((*closest_encloser)), name); while (matched_labels < knot_dname_label_count( @@ -1968,11 +2031,11 @@ dbg_zone_exec( } dbg_zone_exec( char *n = knot_dname_to_str(knot_node_owner((*closest_encloser))); - dbg_zone("Closest encloser: %s\n", n); + dbg_zone_detail("Closest encloser: %s\n", n); free(n); ); - dbg_zone("find_dname() returning %d\n", exact_match); + dbg_zone_verb("find_dname() returning %d\n", exact_match); return (exact_match) ? KNOT_ZONE_NAME_FOUND @@ -2055,11 +2118,11 @@ int knot_zone_contents_find_dname_hash(const knot_zone_contents_t *zone, return KNOT_EBADARG; } -dbg_zone_exec( +dbg_zone_exec_verb( char *name_str = knot_dname_to_str(name); char *zone_str = knot_dname_to_str(zone->apex->owner); - dbg_zone("Searching for name %s in zone %s...\n", - name_str, zone_str); + dbg_zone_verb("Searching for name %s in zone %s...\n", + name_str, zone_str); free(name_str); free(zone_str); ); @@ -2092,9 +2155,9 @@ dbg_zone_exec( *node = (const knot_node_t *)item->value; *closest_encloser = *node; - dbg_zone("Found node in hash table: %p (owner %p, " - "labels: %d)\n", *node, (*node)->owner, - knot_dname_label_count((*node)->owner)); + 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; @@ -2104,34 +2167,22 @@ dbg_zone_exec( // chop leftmost labels until some node is found // copy the name for chopping - /* Local allocation, will be discarded. */ - //knot_dname_t *name_copy = knot_dname_deep_copy(name); -dbg_zone_exec( - //char *n = knot_dname_to_str(name_copy); - dbg_zone("Finding closest encloser..\nStarting with: %.*s\n", - (int)name_size, name_tmp); - //free(n); -); + + dbg_zone_detail("Finding closest encloser..\nStarting with: %.*s\n", + (int)name_size, name_tmp); while (item == NULL) { - //knot_dname_left_chop_no_copy(name_copy); knot_zone_contents_left_chop(name_tmp, &name_size); -dbg_zone_exec( - //char *n = knot_dname_to_str(name_copy); - dbg_zone("Chopped leftmost label: %.*s\n", - (int)name_size, name_tmp); - //free(n); +dbg_zone_exec_detail( + dbg_zone_detail("Chopped leftmost label: %.*s\n", + (int)name_size, name_tmp); ); // not satisfied in root zone!! - //assert(name_copy->label_count > 0); assert(name_size > 0); item = ck_find_item(zone->table, name_tmp, name_size); } - /* Directly discard. */ - //knot_dname_free(&name_copy); - assert(item != NULL); *closest_encloser = (const knot_node_t *)item->value; @@ -2165,9 +2216,16 @@ int knot_zone_contents_find_nsec3_for_name(const knot_zone_contents_t *zone, return ret; } -dbg_zone_exec( + // check if the NSEC3 tree is not empty + if (zone->nsec3_nodes->th_root == NULL) { + dbg_zone("NSEC3 tree is empty.\n"); + knot_dname_release(nsec3_name); + return KNOT_ENSEC3CHAIN; + } + +dbg_zone_exec_verb( char *n = knot_dname_to_str(nsec3_name); - dbg_zone("NSEC3 node name: %s.\n", n); + dbg_zone_verb("NSEC3 node name: %s.\n", n); free(n); ); @@ -2180,26 +2238,33 @@ dbg_zone_exec( knot_dname_release(nsec3_name); -dbg_zone_exec( +dbg_zone_exec_detail( if (found) { char *n = knot_dname_to_str(found->owner); - dbg_zone("Found NSEC3 node: %s.\n", n); + dbg_zone_detail("Found NSEC3 node: %s.\n", n); free(n); } else { - dbg_zone("Found no NSEC3 node.\n"); + dbg_zone_detail("Found no NSEC3 node.\n"); } if (prev) { assert(prev->owner); char *n = knot_dname_to_str(prev->owner); - dbg_zone("Found previous NSEC3 node: %s.\n", n); + dbg_zone_detail("Found previous NSEC3 node: %s.\n", n); free(n); } else { - dbg_zone("Found no previous NSEC3 node.\n"); + dbg_zone_detail("Found no previous NSEC3 node.\n"); } ); *nsec3_node = found; + // This check cannot be used now, the function returns proper return + // value if the node was not found +// if (*nsec3_node == NULL) { +// // there is no NSEC3 node even if there should be +// return KNOT_ENSEC3CHAIN; +// } + if (prev == NULL) { // either the returned node is the root of the tree, or it is // the leftmost node in the tree; in both cases node was found @@ -2211,7 +2276,55 @@ dbg_zone_exec( *nsec3_previous = prev; } - dbg_zone("find_nsec3_for_name() returning %d\n", exact_match); + 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 + * 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_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; + } + + /* If there is none, try 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) + ? knot_dname_to_str( + knot_node_owner(*nsec3_previous)) + : "none"; + dbg_zone_detail("Previous node: %s, checking parameters...\n", + name); + if (*nsec3_previous) { + free(name); + } +); + if (*nsec3_previous == original_prev || nsec3_rdata == NULL) { + // cycle + *nsec3_previous = NULL; + break; + } + } return (exact_match) ? KNOT_ZONE_NAME_FOUND @@ -2257,23 +2370,18 @@ int knot_zone_contents_adjust(knot_zone_contents_t *zone) adjust_arg.first_node = NULL; adjust_arg.previous_node = NULL; adjust_arg.err = KNOT_EOK; -// adjust_arg.check_ver = check_ver; /* - * Adjust the NSEC3 nodes first. - * There are independent on the normal nodes, but the normal nodes are - * dependent on them. + * First of all we must set node.prev pointers, as these are used in + * the search functions. */ - - dbg_zone("Adjusting NSEC3 nodes.\n"); - int ret = knot_zone_tree_forward_apply_inorder( - zone->nsec3_nodes, - knot_zone_contents_adjust_nsec3_node_in_tree, - &adjust_arg); + 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); assert(ret == KNOT_EOK); if (adjust_arg.err != KNOT_EOK) { - dbg_zone("Failed to adjust NSEC3 nodes: %s\n", + dbg_zone("Failed to set 'prev' pointers to NSEC3 nodes: %s\n", knot_strerror(adjust_arg.err)); return adjust_arg.err; } @@ -2281,13 +2389,46 @@ int knot_zone_contents_adjust(knot_zone_contents_t *zone) // 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); } dbg_zone("Done.\n"); adjust_arg.first_node = NULL; 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); + 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)); + return adjust_arg.err; + } + + // set the last node as previous of the first node + assert(zone->apex == adjust_arg.first_node); + knot_node_set_previous(zone->apex, adjust_arg.previous_node); + dbg_zone("Done.\n"); + + /* + * Adjust the NSEC3 nodes first. + * There are independent on the normal nodes, but the normal nodes are + * dependent on them. + */ + + 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); + assert(ret == KNOT_EOK); + + if (adjust_arg.err != KNOT_EOK) { + dbg_zone("Failed to adjust NSEC3 nodes: %s\n", + knot_strerror(adjust_arg.err)); + 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, @@ -2300,9 +2441,6 @@ int knot_zone_contents_adjust(knot_zone_contents_t *zone) return adjust_arg.err; } - assert(zone->apex == adjust_arg.first_node); - knot_node_set_previous(zone->apex, adjust_arg.previous_node); - dbg_zone("Done.\n"); return ret; @@ -2339,58 +2477,6 @@ int knot_zone_contents_check_loops(knot_zone_contents_t *zone) /*----------------------------------------------------------------------------*/ -int knot_zone_contents_adjust_old(knot_zone_contents_t *zone) -{ - if (zone == NULL) { - return KNOT_EBADARG; - } - - // load NSEC3PARAM (needed on adjusting function) - knot_zone_contents_load_nsec3param(zone); - - knot_zone_adjust_arg_t adjust_arg; - adjust_arg.zone = zone; - adjust_arg.first_node = NULL; - adjust_arg.previous_node = NULL; -// adjust_arg.check_ver = check_ver; - adjust_arg.err = KNOT_EOK; - - dbg_zone("Adjusting normal nodes.\n"); - int ret = knot_zone_tree_forward_apply_inorder(zone->nodes, - knot_zone_contents_adjust_node_in_tree, - &adjust_arg); - if (ret != KNOT_EOK) { - return ret; - } - if (adjust_arg.err != KNOT_EOK) { - dbg_zone("Failed node adjusting: %s\n", - knot_strerror(adjust_arg.err)); - return adjust_arg.err; - } - - dbg_zone("Done.\n"); - - assert(zone->apex == adjust_arg.first_node); - knot_node_set_previous(zone->apex, adjust_arg.previous_node); - - adjust_arg.first_node = NULL; - adjust_arg.previous_node = NULL; - - 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); - - dbg_zone("Done.\n"); - if (adjust_arg.first_node) { - knot_node_set_previous(adjust_arg.first_node, - adjust_arg.previous_node); - } - - return ret; -} - -/*----------------------------------------------------------------------------*/ - int knot_zone_contents_load_nsec3param(knot_zone_contents_t *zone) { if (zone == NULL || zone->apex == NULL) { @@ -2418,8 +2504,8 @@ int knot_zone_contents_nsec3_enabled(const knot_zone_contents_t *zone) return KNOT_EBADARG; } - //return (zone->nsec3_params.algorithm != 0); - return (zone->nsec3_nodes->th_root != NULL); + return (zone->nsec3_params.algorithm != 0 + && zone->nsec3_nodes->th_root != NULL); } /*----------------------------------------------------------------------------*/ @@ -2662,16 +2748,15 @@ int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from, // ret = ck_copy_table(from->table, &contents->table); ret = ck_shallow_copy(from->table, &contents->table); if (ret != 0) { - dbg_zone("knot_zone_contents_shallow_copy: " - "hash table copied\n"); + 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"); + dbg_zone("knot_zone_contents_shallow_copy: finished OK\n"); *to = contents; return KNOT_EOK; @@ -2740,13 +2825,11 @@ int knot_zone_contents_shallow_copy2(const knot_zone_contents_t *from, contents->node_count = from->node_count; contents->flags = from->flags; + // set the 'new' flag + knot_zone_contents_set_gen_new(contents); contents->zone = from->zone; -// /* Initialize NSEC3 params */ -// memcpy(&contents->nsec3_params, &from->nsec3_params, -// sizeof(knot_nsec3_params_t)); - if ((ret = knot_zone_tree_deep_copy(from->nodes, contents->nodes)) != KNOT_EOK || (ret = knot_zone_tree_deep_copy(from->nsec3_nodes, @@ -2758,8 +2841,8 @@ int knot_zone_contents_shallow_copy2(const knot_zone_contents_t *from, if (from->table != NULL) { ret = ck_deep_copy(from->table, &contents->table); if (ret != 0) { - dbg_zone("knot_zone_contents_shallow_copy: " - "hash table copied\n"); + dbg_zone_verb("knot_zone_contents_shallow_copy: " + "hash table copied\n"); ret = KNOT_ERROR; goto cleanup; } @@ -2903,16 +2986,6 @@ static void knot_zc_integrity_check_previous(const knot_node_t *node, ++check_data->errors; } -// if (knot_node_next(check_data->previous) != node) { -// char *name2 = knot_dname_to_str(knot_node_owner( -// knot_node_next(check_data->previous))); -// fprintf(stderr, "Wrong next node: node %s, next %s. " -// "Should be %s.\n", name_prev, name2 ,name); -// free(name2); - -// ++check_data->errors; -// } - free(name_prev); } } @@ -2995,11 +3068,6 @@ static void knot_zc_integrity_check_parent(const knot_node_t *node, && knot_dname_matched_labels(node_owner, parent_owner) == knot_dname_label_count(parent_owner)) { -// // increase the parent's children count -// fprintf(stderr, "Parent: %s, node: %s. Increasing children count.\n", -// pname, name); -// ++check_data->children; - // check the parent pointer const knot_node_t *parent = knot_node_parent(node); if (parent != check_data->parent) { @@ -3038,22 +3106,6 @@ static void knot_zc_integrity_check_parent(const knot_node_t *node, ++check_data->errors; } } - } else { - // not a direct child, check children count -// if (check_data->parent -// && knot_node_children(check_data->parent) -// != check_data->children) { -// fprintf(stderr, "Wrong children count: node %s, count: " -// "%u. Should be: %u\n", pname, -// knot_node_children(check_data->parent), -// check_data->children); - -// ++check_data->errors; -// } - - // reset the children count - //check_data->parent = node; -// check_data->children = 0; } free(pname); @@ -3110,15 +3162,6 @@ static int knot_zc_integrity_check_find_dname(const knot_zone_contents_t *zone, const char *node_name) { int ret = 0; - -// find_dname_data_t data_find; -// data_find.found = NULL; -// data_find.to_find = to_find; - -// int res = knot_zone_contents_dname_table_apply( -// (knot_zone_contents_t *)zone, -// find_in_dname_table, (void *)&data_find); -// assert(res == KNOT_EOK); knot_dname_t *found = knot_dname_table_find_dname(zone->dname_table, (knot_dname_t *)to_find); @@ -3364,27 +3407,12 @@ static void reset_new_nodes(knot_zone_tree_node_t *tree_node, void *data) /*----------------------------------------------------------------------------*/ -/*!< \todo remove debug code. */ -//static void print_child_count(knot_node_t *node, void *data) -//{ -// UNUSED(data); -// assert(node != NULL); - -// char *name = knot_dname_to_str(knot_node_owner(node)); -// fprintf(stderr, "Node: %s, children count: %d\n", name, -// knot_node_children(node)); -// free(name); -//} - -/*----------------------------------------------------------------------------*/ - static void count_nsec3_nodes(knot_zone_tree_node_t *tree_node, void *data) { assert(tree_node != NULL); assert(tree_node->node != NULL); assert(data != NULL); -// int *count = (int *)data; knot_node_t *apex = (knot_node_t *)data; assert(apex != NULL); @@ -3406,10 +3434,6 @@ int knot_zc_integrity_check_child_count(check_data_t *data) knot_zone_tree_init(nodes_copy); -// int ret = knot_zone_contents_tree_apply_inorder(data->contents, -// print_child_count, -// NULL); - int ret = knot_zone_tree_deep_copy(data->contents->nodes, nodes_copy); assert(ret == KNOT_EOK); @@ -3425,9 +3449,8 @@ int knot_zc_integrity_check_child_count(check_data_t *data) knot_zone_tree_forward_apply_inorder(nodes_copy, count_children, NULL); // add count of NSEC3 nodes to the apex' children count -// int nsec3_nodes = 0; - dbg_zone("Children count of new apex before NSEC3: %d\n", - data->contents->apex->new_node->children); + 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); @@ -3435,7 +3458,6 @@ int knot_zc_integrity_check_child_count(check_data_t *data) // now compare the children counts // iterate over the old zone and search for nodes in the copy -// data->children = nsec3_nodes; knot_zone_tree_forward_apply_inorder(nodes_copy, check_child_count, (void *)data); |