int knot_zone_tree_get_less_or_equal(knot_zone_tree_t *tree, const knot_dname_t *owner, knot_node_t **found, knot_node_t **previous) { if (tree == NULL || owner == NULL || found == NULL || previous == NULL) { return KNOT_EINVAL; } char lf[DNAME_LFT_MAXLEN]; dname_lf(lf, owner, sizeof(lf)); value_t *fval = NULL; int ret = hattrie_find_leq(tree, lf+1, *lf, &fval); if (fval) *found = (knot_node_t *)(*fval); int exact_match = 0; if (ret == 0) { *previous = knot_node_get_previous(*found); exact_match = 1; } else if (ret < 0) { *previous = *found; *found = NULL; } else if (ret > 0) { /* node is before first node in the trie */ *previous = knot_node_get_previous(*found); /* left of leftmost node is the rightmost node */ *found = NULL; } /* Check if previous node is not an empty non-terminal. */ if (knot_node_rrset_count(*previous) == 0) { *previous = knot_node_get_previous(*previous); } dbg_zone_exec_detail( char *name = knot_dname_to_str(owner); char *name_f = (*found != NULL) ? knot_dname_to_str(knot_node_owner(*found)) : "none"; dbg_zone_detail("Searched for owner %s in zone tree.\n", name); dbg_zone_detail("Exact match: %d\n", exact_match); dbg_zone_detail("Found node: %p: %s.\n", *found, name_f); dbg_zone_detail("Previous node: %p.\n", *previous); free(name); if (*found != NULL) { free(name_f); } );
static int knot_zc_nsec3_parameters_match(const knot_rdataset_t *rrs, const knot_nsec3_params_t *params, size_t rdata_pos) { assert(rrs != NULL && params != NULL); dbg_zone_detail("RDATA algo: %u, iterations: %u, salt length: %u, salt:" " %.*s\n", knot_nsec3_algorithm(rrs, rdata_pos), knot_nsec3_iterations(rrs, rdata_pos), knot_nsec3_salt_length(rrs, rdata_pos), knot_nsec3_salt_length(rrs, rdata_pos), knot_nsec3_salt(rrs, 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_nsec3_algorithm(rrs, rdata_pos) == params->algorithm && knot_nsec3_iterations(rrs, rdata_pos) == params->iterations && knot_nsec3_salt_length(rrs, rdata_pos) == params->salt_length && memcmp(knot_nsec3_salt(rrs, rdata_pos), params->salt, params->salt_length) == 0); }
int zone_tree_get_less_or_equal(zone_tree_t *tree, const knot_dname_t *owner, zone_node_t **found, zone_node_t **previous) { if (owner == NULL || found == NULL || previous == NULL) { return KNOT_EINVAL; } if (zone_tree_is_empty(tree)) { return KNOT_ENONODE; } uint8_t lf[KNOT_DNAME_MAXLEN]; knot_dname_lf(lf, owner, NULL); value_t *fval = NULL; int ret = hattrie_find_leq(tree, (char*)lf+1, *lf, &fval); if (fval) { *found = (zone_node_t *)(*fval); } int exact_match = 0; if (ret == 0) { if (fval) { *previous = (*found)->prev; } exact_match = 1; } else if (ret < 0) { *previous = *found; *found = NULL; } else if (ret > 0) { /* Previous should be the rightmost node. * For regular zone it is the node left of apex, but for some * cases like NSEC3, there is no such sort of thing (name wise). */ /*! \todo We could store rightmost node in zonetree probably. */ hattrie_iter_t *i = hattrie_iter_begin(tree, 1); *previous = *(zone_node_t **)hattrie_iter_val(i); /* leftmost */ *previous = (*previous)->prev; /* rightmost */ *found = NULL; hattrie_iter_free(i); } /* Previous node for proof must be non-empty and authoritative. */ if (*previous && ((*previous)->rrset_count == 0 || (*previous)->flags & NODE_FLAGS_NONAUTH)) { *previous = (*previous)->prev; } dbg_zone_exec_detail( char *name = knot_dname_to_str_alloc(owner); char *name_f = (*found != NULL) ? knot_dname_to_str_alloc((*found)->owner) : "none"; dbg_zone_detail("Searched for owner %s in zone tree.\n", name); dbg_zone_detail("Exact match: %d\n", exact_match); dbg_zone_detail("Found node: %p: %s.\n", *found, name_f); dbg_zone_detail("Previous node: %p.\n", *previous); free(name); if (*found != NULL) { free(name_f); } );
static int zone_contents_add_node(zone_contents_t *zone, zone_node_t *node, bool create_parents) { if (zone == NULL || node == NULL) { return KNOT_EINVAL; } int ret = 0; if ((ret = zone_contents_check_node(zone, node)) != 0) { dbg_zone("Node check failed.\n"); return ret; } ret = zone_tree_insert(zone->nodes, node); if (ret != KNOT_EOK) { dbg_zone("Failed to insert node into zone tree.\n"); return ret; } if (!create_parents) { return KNOT_EOK; } dbg_zone_detail("Creating parents of the node.\n"); /* No parents for root domain. */ if (*node->owner == '\0') return KNOT_EOK; zone_node_t *next_node = NULL; const uint8_t *parent = knot_wire_next_label(node->owner, NULL); if (knot_dname_cmp(zone->apex->owner, parent) == 0) { dbg_zone_detail("Zone apex is the parent.\n"); node_set_parent(node, zone->apex); // check if the node is not wildcard child of the parent if (knot_dname_is_wildcard(node->owner)) { zone->apex->flags |= NODE_FLAGS_WILDCARD_CHILD; } } else { while (parent != NULL && !(next_node = zone_contents_get_node(zone, parent))) { /* Create a new node. */ dbg_zone_detail("Creating new node.\n"); next_node = node_new(parent, NULL); if (next_node == NULL) { return KNOT_ENOMEM; } /* Insert node to a tree. */ dbg_zone_detail("Inserting new node to zone tree.\n"); ret = zone_tree_insert(zone->nodes, next_node); if (ret != KNOT_EOK) { node_free(&next_node, NULL); return ret; } /* Update node pointers. */ node_set_parent(node, next_node); if (knot_dname_is_wildcard(node->owner)) { next_node->flags |= NODE_FLAGS_WILDCARD_CHILD; } dbg_zone_detail("Next parent.\n"); node = next_node; parent = knot_wire_next_label(parent, NULL); } // set the found parent (in the zone) as the parent of the last // inserted node assert(node->parent == NULL); node_set_parent(node, next_node); dbg_zone_detail("Created all parents.\n"); } return KNOT_EOK; }