Instead of stopping when we find the largest network that
matches, we will have to go as deep as we can and then
check all networks on the way from the bottom up.
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
- // If the node is a leaf node, we end here
- if (__loc_database_node_is_leaf(node)) {
- r = __loc_database_lookup_handle_leaf(db, address, network, network_address, level, node);
- if (r <= 0)
- return r;
- }
-
// Follow the path
int bit = in6_addr_get_bit(address, level);
in6_addr_set_bit(network_address, level, bit);
// Follow the path
int bit = in6_addr_get_bit(address, level);
in6_addr_set_bit(network_address, level, bit);
else
node_index = be32toh(node->one);
else
node_index = be32toh(node->one);
- // If we point back to root, the path ends here
- if (node_index == 0) {
- DEBUG(db->ctx, "Tree ends here\n");
- return 1;
- }
+ // If the node index is zero, the tree ends here
+ // and we cannot descend any further
+ if (node_index > 0) {
+ // Check boundaries
+ if ((size_t)node_index >= db->network_nodes_count)
+ return -EINVAL;
- // Check boundaries
- if ((size_t)node_index >= db->network_nodes_count)
- return -EINVAL;
+ // Move on to the next node
+ r = __loc_database_lookup(db, address, network, network_address,
+ db->network_nodes_v0 + node_index, level + 1);
- // Move on to the next node
- r = __loc_database_lookup(db, address, network, network_address,
- db->network_nodes_v0 + node_index, level + 1);
+ // End here if a result was found
+ if (r == 0)
+ return r;
- // End here if a result was found
- if (r == 0)
- return r;
+ // Raise any errors
+ else if (r < 0)
+ return r;
+ }
- // Raise any errors
- else if (r < 0)
- return r;
+ // If this node has a leaf, we will check if it matches
+ if (__loc_database_node_is_leaf(node)) {
+ r = __loc_database_lookup_handle_leaf(db, address, network, network_address, level, node);
+ if (r <= 0)
+ return r;
+ }
DEBUG(db->ctx, "Could not find an exact match at %u\n", level);
DEBUG(db->ctx, "Could not find an exact match at %u\n", level);