shared: reuse dns_label_unescape_undo_idna() in more places

We frequently unescape DNS label follwed by IDNA undoing. We now have a function that does that in one step, hence use
it everywhere.
This commit is contained in:
Lennart Poettering 2016-01-13 20:45:56 +01:00
parent 45c4210ed6
commit 81ec9e0887

View file

@ -558,100 +558,6 @@ const struct hash_ops dns_name_hash_ops = {
.compare = dns_name_compare_func
};
int dns_name_equal(const char *x, const char *y) {
int r, q, k, w;
assert(x);
assert(y);
for (;;) {
char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
r = dns_label_unescape(&x, la, sizeof(la));
if (r < 0)
return r;
if (r > 0) {
k = dns_label_undo_idna(la, r, la, sizeof(la));
if (k < 0)
return k;
if (k > 0)
r = k;
}
q = dns_label_unescape(&y, lb, sizeof(lb));
if (q < 0)
return q;
if (q > 0) {
w = dns_label_undo_idna(lb, q, lb, sizeof(lb));
if (w < 0)
return w;
if (w > 0)
q = w;
}
if (r != q)
return false;
if (r == 0)
return true;
if (ascii_strcasecmp_n(la, lb, r) != 0)
return false;
}
}
int dns_name_endswith(const char *name, const char *suffix) {
const char *n, *s, *saved_n = NULL;
int r, q, k, w;
assert(name);
assert(suffix);
n = name;
s = suffix;
for (;;) {
char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
r = dns_label_unescape(&n, ln, sizeof(ln));
if (r < 0)
return r;
if (r > 0) {
k = dns_label_undo_idna(ln, r, ln, sizeof(ln));
if (k < 0)
return k;
if (k > 0)
r = k;
}
if (!saved_n)
saved_n = n;
q = dns_label_unescape(&s, ls, sizeof(ls));
if (q < 0)
return q;
if (q > 0) {
w = dns_label_undo_idna(ls, q, ls, sizeof(ls));
if (w < 0)
return w;
if (w > 0)
q = w;
}
if (r == 0 && q == 0)
return true;
if (r == 0 && saved_n == n)
return false;
if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) {
/* Not the same, let's jump back, and try with the next label again */
s = suffix;
n = saved_n;
saved_n = NULL;
}
}
}
static int dns_label_unescape_undo_idna(const char **name, char *dest, size_t sz) {
int r, k;
@ -670,6 +576,72 @@ static int dns_label_unescape_undo_idna(const char **name, char *dest, size_t sz
return k;
}
int dns_name_equal(const char *x, const char *y) {
int r, q;
assert(x);
assert(y);
for (;;) {
char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
r = dns_label_unescape_undo_idna(&x, la, sizeof(la));
if (r < 0)
return r;
q = dns_label_unescape_undo_idna(&y, lb, sizeof(lb));
if (q < 0)
return q;
if (r != q)
return false;
if (r == 0)
return true;
if (ascii_strcasecmp_n(la, lb, r) != 0)
return false;
}
}
int dns_name_endswith(const char *name, const char *suffix) {
const char *n, *s, *saved_n = NULL;
int r, q;
assert(name);
assert(suffix);
n = name;
s = suffix;
for (;;) {
char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
r = dns_label_unescape_undo_idna(&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));
if (q < 0)
return q;
if (r == 0 && q == 0)
return true;
if (r == 0 && saved_n == n)
return false;
if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) {
/* Not the same, let's jump back, and try with the next label again */
s = suffix;
n = saved_n;
saved_n = NULL;
}
}
}
int dns_name_startswith(const char *name, const char *prefix) {
const char *n, *p;
int r, q;
@ -702,7 +674,7 @@ int dns_name_startswith(const char *name, const char *prefix) {
int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret) {
const char *n, *s, *saved_before = NULL, *saved_after = NULL, *prefix;
int r, q, k, w;
int r, q;
assert(name);
assert(old_suffix);
@ -718,30 +690,16 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
if (!saved_before)
saved_before = n;
r = dns_label_unescape(&n, ln, sizeof(ln));
r = dns_label_unescape_undo_idna(&n, ln, sizeof(ln));
if (r < 0)
return r;
if (r > 0) {
k = dns_label_undo_idna(ln, r, ln, sizeof(ln));
if (k < 0)
return k;
if (k > 0)
r = k;
}
if (!saved_after)
saved_after = n;
q = dns_label_unescape(&s, ls, sizeof(ls));
q = dns_label_unescape_undo_idna(&s, ls, sizeof(ls));
if (q < 0)
return q;
if (q > 0) {
w = dns_label_undo_idna(ls, q, ls, sizeof(ls));
if (w < 0)
return w;
if (w > 0)
q = w;
}
if (r == 0 && q == 0)
break;