Skip to content

Commit

Permalink
dns-domain: tweak hash table comparison function for DNS names
Browse files Browse the repository at this point in the history
Currently, when comparing two DNS names when storing them in a
hashtable, and the DNS names are not actually valid we'll compare the
error codes.

This is not very smart however, since this means two invalid DNS names
that happen to be equally "invalid" will be considered identical, even
if their strings are entirely different.

Let's find a better solution for this niche case: let's simple compare
the domains as strings.

This matters in case of DNS label compression: if we already added added
an invalid DNS name into the label compression hash table, and lookup
any other invalid DNS name, this lookup will likely return what the
earlier one already returned, and that's confusing.

(cherry picked from commit 8ed2c62)
  • Loading branch information
poettering authored and bluca committed Nov 13, 2024
1 parent 5a85347 commit f135354
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/shared/dns-domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,17 +473,17 @@ int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_r
return 0;
}

void dns_name_hash_func(const char *p, struct siphash *state) {
void dns_name_hash_func(const char *name, struct siphash *state) {
int r;

assert(p);
assert(name);

for (;;) {
for (const char *p = name;;) {
char label[DNS_LABEL_MAX+1];

r = dns_label_unescape(&p, label, sizeof label, 0);
if (r < 0)
break;
return string_hash_func(p, state); /* fallback for invalid DNS names */
if (r == 0)
break;

Expand All @@ -509,13 +509,13 @@ int dns_name_compare_func(const char *a, const char *b) {
for (;;) {
char la[DNS_LABEL_MAX+1], lb[DNS_LABEL_MAX+1];

if (x == NULL && y == NULL)
if (!x && !y)
return 0;

r = dns_label_unescape_suffix(a, &x, la, sizeof(la));
q = dns_label_unescape_suffix(b, &y, lb, sizeof(lb));
if (r < 0 || q < 0)
return CMP(r, q);
return strcmp(a, b); /* if not valid DNS labels, then let's compare the whole strings as is */

r = ascii_strcasecmp_nn(la, r, lb, q);
if (r != 0)
Expand Down

0 comments on commit f135354

Please sign in to comment.