From eb241cdbeea092d891137c018cacf919a895e6a6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 13 Jan 2016 02:23:08 +0100 Subject: shared: add new dns_name_startswith() call dns_name_startswith() is to dns_name_endswith() as startswith() is to endswith(). --- src/shared/dns-domain.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- src/shared/dns-domain.h | 1 + 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'src/shared') diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c index 59475115ba..e777badb6b 100644 --- a/src/shared/dns-domain.c +++ b/src/shared/dns-domain.c @@ -263,7 +263,6 @@ int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) { *(q++) = '0' + (char) ((uint8_t) *p % 10); sz -= 4; - } p++; @@ -653,6 +652,54 @@ int dns_name_endswith(const char *name, const char *suffix) { } } +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_startswith(const char *name, const char *prefix) { + const char *n, *p; + int r, q; + + assert(name); + assert(prefix); + + n = name; + p = prefix; + + for (;;) { + char ln[DNS_LABEL_MAX], lp[DNS_LABEL_MAX]; + + r = dns_label_unescape_undo_idna(&p, lp, sizeof(lp)); + if (r < 0) + return r; + if (r == 0) + return true; + + q = dns_label_unescape_undo_idna(&n, ln, sizeof(ln)); + if (q < 0) + return q; + + if (r != q) + return false; + if (ascii_strcasecmp_n(ln, lp, r) != 0) + return false; + } +} + 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; diff --git a/src/shared/dns-domain.h b/src/shared/dns-domain.h index dd8ae3ac98..4fbe0a618f 100644 --- a/src/shared/dns-domain.h +++ b/src/shared/dns-domain.h @@ -83,6 +83,7 @@ extern const struct hash_ops dns_name_hash_ops; int dns_name_between(const char *a, const char *b, const char *c); int dns_name_equal(const char *x, const char *y); int dns_name_endswith(const char *name, const char *suffix); +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); -- cgit v1.2.3-54-g00ecf