diff --git a/src/knot/nameserver/internet.c b/src/knot/nameserver/internet.c index fbffd55513fccecc28bcb13bc4d087a094b81fdc..9101641ba4f9822213d41d636e8bdac4d6d81b15 100644 --- a/src/knot/nameserver/internet.c +++ b/src/knot/nameserver/internet.c @@ -451,10 +451,17 @@ static int name_not_found(knot_pkt_t *pkt, struct query_data *qdata) dbg_ns("%s(%p, %p)\n", __func__, pkt, qdata); /* Name is covered by wildcard. */ - const knot_node_t *wildcard_node = knot_node_wildcard_child(qdata->encloser); - if (wildcard_node) { + if (knot_node_has_wildcard_child(qdata->encloser)) { dbg_ns("%s: name %p covered by wildcard\n", __func__, qdata->name); + + /* Find wildcard child in the zone. */ + const knot_node_t *wildcard_node = + knot_zone_contents_find_wildcard_child( + qdata->zone->contents, qdata->encloser); + qdata->node = wildcard_node; + assert(qdata->node != NULL); + /* keep encloser */ qdata->previous = NULL; @@ -463,7 +470,7 @@ static int name_not_found(knot_pkt_t *pkt, struct query_data *qdata) /* Put to wildcard node list. */ if (wildcard_visit(qdata, wildcard_node, qdata->name) != KNOT_EOK) { - next_state = ERROR; + next_state = ERROR; } return next_state; diff --git a/src/knot/updates/xfr-in.c b/src/knot/updates/xfr-in.c index 90f4e83c86377e1d26f627e7e016fffdbcb7ee6c..c29b4aaeb99193cd501623c4d00cb7309dc01f38 100644 --- a/src/knot/updates/xfr-in.c +++ b/src/knot/updates/xfr-in.c @@ -987,8 +987,9 @@ static int xfrin_mark_empty(knot_node_t **node_p, void *data) } knot_node_set_empty(node); if (node->parent) { - if (node->parent->wildcard_child == node) { - node->parent->wildcard_child = NULL; + if (knot_node_has_wildcard_child(node->parent) + && knot_dname_is_wildcard(node->owner)) { + knot_node_clear_wildcard_child(node->parent); } node->parent->children--; // Recurse using the parent node diff --git a/src/knot/zone/node.c b/src/knot/zone/node.c index 8a131da05a5e79c1a059b02e87b09287b4134911..fd2dd524ea35faed2b9bdbdb3948d83ced5531a6 100644 --- a/src/knot/zone/node.c +++ b/src/knot/zone/node.c @@ -377,37 +377,27 @@ knot_dname_t *knot_node_get_owner(const knot_node_t *node) /*----------------------------------------------------------------------------*/ -knot_node_t *knot_node_get_wildcard_child(const knot_node_t *node) +void knot_node_set_wildcard_child(knot_node_t *node) { if (node == NULL) { - return NULL; + return; } - return node->wildcard_child; + knot_node_flags_set(node, KNOT_NODE_FLAGS_WILDCARD_CHILD); } /*----------------------------------------------------------------------------*/ -void knot_node_set_wildcard_child(knot_node_t *node, - knot_node_t *wildcard_child) +int knot_node_has_wildcard_child(const knot_node_t *node) { - if (node == NULL) { - return; - } - - node->wildcard_child = wildcard_child; -// assert(wildcard_child->parent == node); + return knot_node_flags_get(node, KNOT_NODE_FLAGS_WILDCARD_CHILD); } /*----------------------------------------------------------------------------*/ -const knot_node_t *knot_node_wildcard_child(const knot_node_t *node) +void knot_node_clear_wildcard_child(knot_node_t *node) { - if (node == NULL) { - return NULL; - } - - return knot_node_get_wildcard_child(node); + knot_node_flags_clear(node, KNOT_NODE_FLAGS_WILDCARD_CHILD); } /*----------------------------------------------------------------------------*/ @@ -641,4 +631,3 @@ bool knot_node_rrtype_exists(const knot_node_t *node, uint16_t type) { return knot_node_rrs(node, type) != NULL; } - diff --git a/src/knot/zone/node.h b/src/knot/zone/node.h index 42fd2908697e5945565bd84d02a2e4fbaa86bccb..51dbf2d3e4a4a3ffcaca7e003fdb52818c332cfe 100644 --- a/src/knot/zone/node.h +++ b/src/knot/zone/node.h @@ -48,9 +48,6 @@ struct knot_node { /*! \brief Type-ordered array of RRSets belonging to this node. */ struct rr_data *rrs; - /*! \brief Wildcard node being the direct descendant of this node. */ - struct knot_node *wildcard_child; - /*! * \brief Previous node in canonical order. * @@ -75,10 +72,7 @@ struct knot_node { /*! * \brief Various flags. * - * 0x01 - node is a delegation point - * 0x02 - node is non-authoritative (under a delegation point) - * 0x04 - NSEC(3) was removed from the node. - * 0x10 - node is empty and will be deleted after update + * \ref knot_node_flags_t */ uint8_t flags; }; @@ -106,6 +100,8 @@ typedef enum { /*! \brief Node is empty and will be deleted after update. * \todo Remove after dname refactoring, update description in node. */ KNOT_NODE_FLAGS_EMPTY = 1 << 4, + /*! \brief Node has a wildcard child. */ + KNOT_NODE_FLAGS_WILDCARD_CHILD = 1 << 5 } knot_node_flags_t; /*----------------------------------------------------------------------------*/ @@ -260,29 +256,37 @@ void knot_node_set_nsec3_node(knot_node_t *node, knot_node_t *nsec3_node); const knot_dname_t *knot_node_owner(const knot_node_t *node); /*! - * \todo Document me. + * \brief Returns the owner of the node as a non-const reference. + * + * \param node Node to get the owner of. + * + * \return Owner of the given node. */ knot_dname_t *knot_node_get_owner(const knot_node_t *node); /*! - * \brief Returns the wildcard child of the node. - * - * \param node Node to get the owner of. + * \brief Sets the wildcard child flag of the node. * - * \return Wildcard child of the given node or NULL if it has none. + * \param node Node that has wildcard. */ -const knot_node_t *knot_node_wildcard_child(const knot_node_t *node); +void knot_node_set_wildcard_child(knot_node_t *node); /*! - * \brief Sets the wildcard child of the node. + * \brief Checks if node has a wildcard child. * - * \param node Node to set the wildcard child of. - * \param wildcard_child Wildcard child of the node. + * \param node Node to check. + * + * \retval > 0 if the node has a wildcard child. + * \retval 0 otherwise. */ -void knot_node_set_wildcard_child(knot_node_t *node, - knot_node_t *wildcard_child); +int knot_node_has_wildcard_child(const knot_node_t *node); -knot_node_t *knot_node_get_wildcard_child(const knot_node_t *node); +/*! + * \brief Clears the node's wildcard child flag. + * + * \param node Node to clear the flag in. + */ +void knot_node_clear_wildcard_child(knot_node_t *node); /*! * \brief Mark the node as a delegation point. diff --git a/src/knot/zone/zone-contents.c b/src/knot/zone/zone-contents.c index ff9155fe2958eb6b5e4d750b542285b05384e034..00227537f37e90a1b0fb8c6c8af5b928583fbdb3 100644 --- a/src/knot/zone/zone-contents.c +++ b/src/knot/zone/zone-contents.c @@ -175,8 +175,12 @@ static int discover_additionals(struct rr_data *rr_data, /* Try to find node for the dname in the RDATA. */ dname = knot_rrs_name(rrs, i, rr_data->type); knot_zone_contents_find_dname(zone, dname, &node, &encloser, &prev); - if (node == NULL && encloser && encloser->wildcard_child) { - node = encloser->wildcard_child; + if (node == NULL && encloser + && knot_node_has_wildcard_child(encloser)) { + /* Find wildcard child in the zone. */ + node = knot_zone_contents_find_wildcard_child(zone, + encloser); + assert(node != NULL); } rr_data->additional[i] = (knot_node_t *)node; @@ -200,11 +204,14 @@ static int adjust_pointers(knot_node_t **tnode, void *data) args->first_node = node; } + // clear Removed NSEC flag so that no relicts remain + knot_node_clear_removed_nsec(node); + // check if this node is not a wildcard child of its parent if (knot_dname_is_wildcard(knot_node_owner(node))) { assert(knot_node_parent(node) != NULL); - knot_node_set_wildcard_child(knot_node_get_parent(node), node); + knot_node_set_wildcard_child(knot_node_get_parent(node)); } // set flags (delegation point, non-authoritative) @@ -551,7 +558,7 @@ dbg_zone_exec_detail( // check if the node is not wildcard child of the parent if (knot_dname_is_wildcard(knot_node_owner(node))) { - knot_node_set_wildcard_child(zone->apex, node); + knot_node_set_wildcard_child(zone->apex); } } else { while (parent != NULL && @@ -575,7 +582,7 @@ dbg_zone_exec_detail( /* Update node pointers. */ knot_node_set_parent(node, next_node); if (knot_dname_is_wildcard(knot_node_owner(node))) { - knot_node_set_wildcard_child(next_node, node); + knot_node_set_wildcard_child(next_node); } ++zone->node_count; @@ -1119,6 +1126,20 @@ const knot_node_t *knot_zone_contents_apex( /*----------------------------------------------------------------------------*/ +const knot_node_t *knot_zone_contents_find_wildcard_child( + const knot_zone_contents_t *contents, const knot_node_t *parent) +{ + if (contents == NULL || parent == NULL || parent->owner == NULL) { + return NULL; + } + + knot_dname_t wildcard[KNOT_DNAME_MAXLEN] = { 0x01, '*' }; + knot_dname_to_wire(wildcard + 2, parent->owner, KNOT_DNAME_MAXLEN - 2); + return knot_zone_contents_find_node(contents, wildcard); +} + +/*----------------------------------------------------------------------------*/ + static int knot_zone_contents_adjust_nodes(knot_zone_tree_t *nodes, knot_zone_adjust_arg_t *adjust_arg, knot_zone_tree_apply_cb_t callback) diff --git a/src/knot/zone/zone-contents.h b/src/knot/zone/zone-contents.h index 4331a98451d340da117c68dcaf1b96d14133423f..0233e4b778949b98cf92aaa8e83f9f862dbc8477 100644 --- a/src/knot/zone/zone-contents.h +++ b/src/knot/zone/zone-contents.h @@ -199,6 +199,9 @@ int knot_zone_contents_find_nsec3_for_name( const knot_node_t *knot_zone_contents_apex( const knot_zone_contents_t *contents); +const knot_node_t *knot_zone_contents_find_wildcard_child( + const knot_zone_contents_t *contents, const knot_node_t *parent); + /*! * \brief Sets parent and previous pointers and node flags. (cheap operation) * For both normal and NSEC3 tree