summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-01-18 20:31:39 +0100
committerLennart Poettering <lennart@poettering.net>2016-01-18 23:31:16 +0100
commit23b298bce75a0d1f4f15f34458af9678b4a30c3a (patch)
treef1137704b66a45e057e22b74f6c01534536f1b1b /src/shared
parentb6800689e03456efd0430d171ebf962f64b94eb0 (diff)
resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs. Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix. With this change IDNA conversion is done only: - When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname() - When the user passes a non-ASCII domain suffix when resolving a service using ResolveService() No IDNA encoding is done anymore: - When the user does raw ResolveRecord() RR resolving - On the service part of a DNS-SD service name Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/dns-domain.c70
1 files changed, 11 insertions, 59 deletions
diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c
index 33bc26ad7d..3ad409fc29 100644
--- a/src/shared/dns-domain.c
+++ b/src/shared/dns-domain.c
@@ -413,7 +413,6 @@ int dns_name_concat(const char *a, const char *b, char **_ret) {
for (;;) {
char label[DNS_LABEL_MAX];
- int k;
r = dns_label_unescape(&p, label, sizeof(label));
if (r < 0)
@@ -432,12 +431,6 @@ int dns_name_concat(const char *a, const char *b, char **_ret) {
break;
}
- k = dns_label_undo_idna(label, r, label, sizeof(label));
- if (k < 0)
- return k;
- if (k > 0)
- r = k;
-
if (_ret) {
if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
return -ENOMEM;
@@ -487,7 +480,6 @@ void dns_name_hash_func(const void *s, struct siphash *state) {
for (;;) {
char label[DNS_LABEL_MAX+1];
- int k;
r = dns_label_unescape(&p, label, sizeof(label));
if (r < 0)
@@ -495,12 +487,6 @@ void dns_name_hash_func(const void *s, struct siphash *state) {
if (r == 0)
break;
- k = dns_label_undo_idna(label, r, label, sizeof(label));
- if (k < 0)
- break;
- if (k > 0)
- r = k;
-
ascii_strlower_n(label, r);
siphash24_compress(label, r, state);
siphash24_compress_byte(0, state); /* make sure foobar and foo.bar result in different hashes */
@@ -512,7 +498,7 @@ void dns_name_hash_func(const void *s, struct siphash *state) {
int dns_name_compare_func(const void *a, const void *b) {
const char *x, *y;
- int r, q, k, w;
+ int r, q;
assert(a);
assert(b);
@@ -531,22 +517,6 @@ int dns_name_compare_func(const void *a, const void *b) {
if (r < 0 || q < 0)
return r - q;
- if (r > 0)
- k = dns_label_undo_idna(la, r, la, sizeof(la));
- else
- k = 0;
- if (q > 0)
- w = dns_label_undo_idna(lb, q, lb, sizeof(lb));
- else
- w = 0;
-
- if (k < 0 || w < 0)
- return k - w;
- if (k > 0)
- r = k;
- if (w > 0)
- q = w;
-
r = ascii_strcasecmp_nn(la, r, lb, q);
if (r != 0)
return r;
@@ -558,24 +528,6 @@ const struct hash_ops dns_name_hash_ops = {
.compare = dns_name_compare_func
};
-static int dns_label_unescape_undo_idna(const char **name, char *dest, size_t sz) {
- int r, k;
-
- /* Clobbers all arguments on failure... */
-
- r = dns_label_unescape(name, dest, sz);
- if (r <= 0)
- return r;
-
- k = dns_label_undo_idna(dest, r, dest, sz);
- if (k < 0)
- return k;
- if (k == 0) /* not an IDNA name */
- return r;
-
- return k;
-}
-
int dns_name_equal(const char *x, const char *y) {
int r, q;
@@ -585,11 +537,11 @@ int dns_name_equal(const char *x, const char *y) {
for (;;) {
char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
- r = dns_label_unescape_undo_idna(&x, la, sizeof(la));
+ r = dns_label_unescape(&x, la, sizeof(la));
if (r < 0)
return r;
- q = dns_label_unescape_undo_idna(&y, lb, sizeof(lb));
+ q = dns_label_unescape(&y, lb, sizeof(lb));
if (q < 0)
return q;
@@ -616,14 +568,14 @@ int dns_name_endswith(const char *name, const char *suffix) {
for (;;) {
char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
- r = dns_label_unescape_undo_idna(&n, ln, sizeof(ln));
+ r = dns_label_unescape(&n, ln, sizeof(ln));
if (r < 0)
return r;
if (!saved_n)
saved_n = n;
- q = dns_label_unescape_undo_idna(&s, ls, sizeof(ls));
+ q = dns_label_unescape(&s, ls, sizeof(ls));
if (q < 0)
return q;
@@ -655,13 +607,13 @@ int dns_name_startswith(const char *name, const char *prefix) {
for (;;) {
char ln[DNS_LABEL_MAX], lp[DNS_LABEL_MAX];
- r = dns_label_unescape_undo_idna(&p, lp, sizeof(lp));
+ r = dns_label_unescape(&p, lp, sizeof(lp));
if (r < 0)
return r;
if (r == 0)
return true;
- q = dns_label_unescape_undo_idna(&n, ln, sizeof(ln));
+ q = dns_label_unescape(&n, ln, sizeof(ln));
if (q < 0)
return q;
@@ -690,14 +642,14 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
if (!saved_before)
saved_before = n;
- r = dns_label_unescape_undo_idna(&n, ln, sizeof(ln));
+ r = dns_label_unescape(&n, ln, sizeof(ln));
if (r < 0)
return r;
if (!saved_after)
saved_after = n;
- q = dns_label_unescape_undo_idna(&s, ls, sizeof(ls));
+ q = dns_label_unescape(&s, ls, sizeof(ls));
if (q < 0)
return q;
@@ -1286,12 +1238,12 @@ int dns_name_common_suffix(const char *a, const char *b, const char **ret) {
}
x = a_labels[n - 1 - k];
- r = dns_label_unescape_undo_idna(&x, la, sizeof(la));
+ r = dns_label_unescape(&x, la, sizeof(la));
if (r < 0)
return r;
y = b_labels[m - 1 - k];
- q = dns_label_unescape_undo_idna(&y, lb, sizeof(lb));
+ q = dns_label_unescape(&y, lb, sizeof(lb));
if (q < 0)
return q;