diff options
author | Daniel Salzman <daniel.salzman@nic.cz> | 2024-11-14 14:40:37 +0100 |
---|---|---|
committer | Daniel Salzman <daniel.salzman@nic.cz> | 2024-11-15 08:35:14 +0100 |
commit | 91751b5a0ee471550eb84d7bafbf3cd73765c7cd (patch) | |
tree | d9870ab8f8787d466222088c3e9672dc83168937 /src | |
parent | nameserver: add check for \0 bytes in QNAME labels and respond it as NXDOMAIN... (diff) | |
download | knot-91751b5a0ee471550eb84d7bafbf3cd73765c7cd.tar.xz knot-91751b5a0ee471550eb84d7bafbf3cd73765c7cd.zip |
contents: refactor zone_contents_find_dname()
Diffstat (limited to 'src')
-rw-r--r-- | src/knot/zone/contents.c | 53 |
1 files changed, 25 insertions, 28 deletions
diff --git a/src/knot/zone/contents.c b/src/knot/zone/contents.c index 760a0c5f8..8a32cc87e 100644 --- a/src/knot/zone/contents.c +++ b/src/knot/zone/contents.c @@ -276,6 +276,22 @@ zone_node_t *zone_contents_find_node_for_rr(zone_contents_t *contents, const kno get_node(contents, rrset->owner); } +static bool null_byte_mismatch(const zone_node_t *node, const knot_dname_t *name, + bool name_nullbyte) +{ + /* WARNING: for the sake of efficiency, Knot does not handle \0 byte + * in qname correctly, which can lead to disasters here and there. + * The following check should cover most of the cases. + */ + + bool node_nullbyte = (node->flags & NODE_FLAGS_NULLBYTE); + if (node_nullbyte != name_nullbyte || + (node_nullbyte && !knot_dname_is_equal(node->owner, name))) { + return true; + } + return false; +} + int zone_contents_find_dname(const zone_contents_t *zone, const knot_dname_t *name, const zone_node_t **match, @@ -300,48 +316,29 @@ int zone_contents_find_dname(const zone_contents_t *zone, int found = zone_tree_get_less_or_equal(zone->nodes, name, &node, &prev); if (found < 0) { - // error return found; - } else if (found == 1) { - // exact match - // if previous==NULL, zone not adjusted yet - - assert(node); + } - // WARNING: for the sake of efficiency, Knot does not handle \0 byte in qname correctly - // which can lead to disasters here and there. This should cover most of the cases. - bool node_nullbyte = (node->flags & NODE_FLAGS_NULLBYTE); - if (node_nullbyte != name_nullbyte || - (node_nullbyte && !knot_dname_is_equal(node->owner, name))) { - goto nxd; - } + if (previous != NULL) { // Null previous means zone not adjusted yet. + assert(prev); + *previous = prev; + } + if (found == 1 && !null_byte_mismatch(node, name, name_nullbyte)) { + assert(node); *match = node; *closest = node; - if (previous != NULL) { - assert(prev); - *previous = prev; - } - return ZONE_NAME_FOUND; } else { - // closest match - - assert(!node && prev); -nxd: + assert(prev); + *match = NULL; node = prev; size_t matched_labels = knot_dname_matched_labels(node->owner, name); while (matched_labels < knot_dname_labels(node->owner, NULL)) { node = node_parent(node); assert(node); } - - *match = NULL; *closest = node; - if (previous != NULL) { - *previous = prev; - } - return ZONE_NAME_NOT_FOUND; } } |