From 4ad7f2761da661853dcc29d542efb4727abb1101 Mon Sep 17 00:00:00 2001 From: Nick Owens Date: Tue, 2 Jun 2015 11:49:43 -0700 Subject: resolve: move dns routines into shared --- src/resolve/resolved-bus.c | 2 +- src/resolve/resolved-dns-answer.c | 2 +- src/resolve/resolved-dns-domain.c | 613 ------------------------------------ src/resolve/resolved-dns-domain.h | 50 --- src/resolve/resolved-dns-packet.c | 2 +- src/resolve/resolved-dns-question.c | 2 +- src/resolve/resolved-dns-rr.c | 2 +- src/resolve/resolved-dns-scope.c | 2 +- src/resolve/resolved-dns-zone.c | 2 +- src/resolve/resolved-manager.c | 2 +- src/resolve/test-dns-domain.c | 192 ----------- 11 files changed, 8 insertions(+), 863 deletions(-) delete mode 100644 src/resolve/resolved-dns-domain.c delete mode 100644 src/resolve/resolved-dns-domain.h delete mode 100644 src/resolve/test-dns-domain.c (limited to 'src/resolve') diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 171141e3a4..6db12511f9 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -22,7 +22,7 @@ #include "bus-common-errors.h" #include "bus-util.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-bus.h" #include "resolved-def.h" diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c index e08eb667cc..f77b98e505 100644 --- a/src/resolve/resolved-dns-answer.c +++ b/src/resolve/resolved-dns-answer.c @@ -20,7 +20,7 @@ ***/ #include "resolved-dns-answer.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" DnsAnswer *dns_answer_new(unsigned n) { DnsAnswer *a; diff --git a/src/resolve/resolved-dns-domain.c b/src/resolve/resolved-dns-domain.c deleted file mode 100644 index e1eb3ddfe5..0000000000 --- a/src/resolve/resolved-dns-domain.c +++ /dev/null @@ -1,613 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . - ***/ - -#ifdef HAVE_LIBIDN -#include -#include -#endif - -#include "resolved-dns-domain.h" - -int dns_label_unescape(const char **name, char *dest, size_t sz) { - const char *n; - char *d; - int r = 0; - - assert(name); - assert(*name); - assert(dest); - - n = *name; - d = dest; - - for (;;) { - if (*n == '.') { - n++; - break; - } - - if (*n == 0) - break; - - if (sz <= 0) - return -ENOSPC; - - if (r >= DNS_LABEL_MAX) - return -EINVAL; - - if (*n == '\\') { - /* Escaped character */ - - n++; - - if (*n == 0) - /* Ending NUL */ - return -EINVAL; - - else if (*n == '\\' || *n == '.') { - /* Escaped backslash or dot */ - *(d++) = *(n++); - sz--; - r++; - - } else if (n[0] >= '0' && n[0] <= '9') { - unsigned k; - - /* Escaped literal ASCII character */ - - if (!(n[1] >= '0' && n[1] <= '9') || - !(n[2] >= '0' && n[2] <= '9')) - return -EINVAL; - - k = ((unsigned) (n[0] - '0') * 100) + - ((unsigned) (n[1] - '0') * 10) + - ((unsigned) (n[2] - '0')); - - /* Don't allow CC characters or anything that doesn't fit in 8bit */ - if (k < ' ' || k > 255 || k == 127) - return -EINVAL; - - *(d++) = (char) k; - sz--; - r++; - - n += 3; - } else - return -EINVAL; - - } else if ((uint8_t) *n >= (uint8_t) ' ' && *n != 127) { - - /* Normal character */ - *(d++) = *(n++); - sz--; - r++; - } else - return -EINVAL; - } - - /* Empty label that is not at the end? */ - if (r == 0 && *n) - return -EINVAL; - - if (sz >= 1) - *d = 0; - - *name = n; - return r; -} - -int dns_label_escape(const char *p, size_t l, char **ret) { - _cleanup_free_ char *s = NULL; - char *q; - int r; - - assert(p); - assert(ret); - - if (l > DNS_LABEL_MAX) - return -EINVAL; - - s = malloc(l * 4 + 1); - if (!s) - return -ENOMEM; - - q = s; - while (l > 0) { - - if (*p == '.' || *p == '\\') { - - /* Dot or backslash */ - *(q++) = '\\'; - *(q++) = *p; - - } else if (*p == '_' || - *p == '-' || - (*p >= '0' && *p <= '9') || - (*p >= 'a' && *p <= 'z') || - (*p >= 'A' && *p <= 'Z')) { - - /* Proper character */ - *(q++) = *p; - } else if ((uint8_t) *p >= (uint8_t) ' ' && *p != 127) { - - /* Everything else */ - *(q++) = '\\'; - *(q++) = '0' + (char) ((uint8_t) *p / 100); - *(q++) = '0' + (char) (((uint8_t) *p / 10) % 10); - *(q++) = '0' + (char) ((uint8_t) *p % 10); - - } else - return -EINVAL; - - p++; - l--; - } - - *q = 0; - *ret = s; - r = q - s; - s = NULL; - - return r; -} - -int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) { -#ifdef HAVE_LIBIDN - _cleanup_free_ uint32_t *input = NULL; - size_t input_size; - const char *p; - bool contains_8bit = false; - - assert(encoded); - assert(decoded); - assert(decoded_max >= DNS_LABEL_MAX); - - if (encoded_size <= 0) - return 0; - - for (p = encoded; p < encoded + encoded_size; p++) - if ((uint8_t) *p > 127) - contains_8bit = true; - - if (!contains_8bit) - return 0; - - input = stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size); - if (!input) - return -ENOMEM; - - if (idna_to_ascii_4i(input, input_size, decoded, 0) != 0) - return -EINVAL; - - return strlen(decoded); -#else - return 0; -#endif -} - -int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) { -#ifdef HAVE_LIBIDN - size_t input_size, output_size; - _cleanup_free_ uint32_t *input = NULL; - _cleanup_free_ char *result = NULL; - uint32_t *output = NULL; - size_t w; - - /* To be invoked after unescaping */ - - assert(encoded); - assert(decoded); - - if (encoded_size < sizeof(IDNA_ACE_PREFIX)-1) - return 0; - - if (memcmp(encoded, IDNA_ACE_PREFIX, sizeof(IDNA_ACE_PREFIX) -1) != 0) - return 0; - - input = stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size); - if (!input) - return -ENOMEM; - - output_size = input_size; - output = newa(uint32_t, output_size); - - idna_to_unicode_44i(input, input_size, output, &output_size, 0); - - result = stringprep_ucs4_to_utf8(output, output_size, NULL, &w); - if (!result) - return -ENOMEM; - if (w <= 0) - return 0; - if (w+1 > decoded_max) - return -EINVAL; - - memcpy(decoded, result, w+1); - return w; -#else - return 0; -#endif -} - -int dns_name_normalize(const char *s, char **_ret) { - _cleanup_free_ char *ret = NULL; - size_t n = 0, allocated = 0; - const char *p = s; - bool first = true; - int r; - - assert(s); - - for (;;) { - _cleanup_free_ char *t = NULL; - char label[DNS_LABEL_MAX]; - int k; - - r = dns_label_unescape(&p, label, sizeof(label)); - if (r < 0) - return r; - if (r == 0) { - if (*p != 0) - return -EINVAL; - break; - } - - k = dns_label_undo_idna(label, r, label, sizeof(label)); - if (k < 0) - return k; - if (k > 0) - r = k; - - r = dns_label_escape(label, r, &t); - if (r < 0) - return r; - - if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) - return -ENOMEM; - - if (!first) - ret[n++] = '.'; - else - first = false; - - memcpy(ret + n, t, r); - n += r; - } - - if (n > DNS_NAME_MAX) - return -EINVAL; - - if (!GREEDY_REALLOC(ret, allocated, n + 1)) - return -ENOMEM; - - ret[n] = 0; - - if (_ret) { - *_ret = ret; - ret = NULL; - } - - return 0; -} - -unsigned long dns_name_hash_func(const void *s, const uint8_t hash_key[HASH_KEY_SIZE]) { - const char *p = s; - unsigned long ul = hash_key[0]; - int r; - - assert(p); - - while (*p) { - char label[DNS_LABEL_MAX+1]; - int k; - - r = dns_label_unescape(&p, label, sizeof(label)); - if (r < 0) - break; - - k = dns_label_undo_idna(label, r, label, sizeof(label)); - if (k < 0) - break; - if (k > 0) - r = k; - - label[r] = 0; - ascii_strlower(label); - - ul = ul * hash_key[1] + ul + string_hash_func(label, hash_key); - } - - return ul; -} - -int dns_name_compare_func(const void *a, const void *b) { - const char *x = a, *y = b; - int r, q, k, w; - - assert(a); - assert(b); - - for (;;) { - char la[DNS_LABEL_MAX+1], lb[DNS_LABEL_MAX+1]; - - if (*x == 0 && *y == 0) - return 0; - - r = dns_label_unescape(&x, la, sizeof(la)); - q = dns_label_unescape(&y, lb, sizeof(lb)); - if (r < 0 || q < 0) - return r - q; - - k = dns_label_undo_idna(la, r, la, sizeof(la)); - w = dns_label_undo_idna(lb, q, lb, sizeof(lb)); - if (k < 0 || w < 0) - return k - w; - if (k > 0) - r = k; - if (w > 0) - r = w; - - la[r] = lb[q] = 0; - r = strcasecmp(la, lb); - if (r != 0) - return r; - } -} - -const struct hash_ops dns_name_hash_ops = { - .hash = dns_name_hash_func, - .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+1], lb[DNS_LABEL_MAX+1]; - - if (*x == 0 && *y == 0) - return true; - - r = dns_label_unescape(&x, la, sizeof(la)); - if (r < 0) - return r; - - 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; - w = dns_label_undo_idna(lb, q, lb, sizeof(lb)); - if (w < 0) - return w; - if (w > 0) - q = w; - - la[r] = lb[q] = 0; - if (strcasecmp(la, lb)) - 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+1], ls[DNS_LABEL_MAX+1]; - - r = dns_label_unescape(&n, ln, sizeof(ln)); - if (r < 0) - return r; - 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; - 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; - - ln[r] = ls[q] = 0; - - if (r != q || strcasecmp(ln, ls)) { - - /* 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_reverse(int family, const union in_addr_union *a, char **ret) { - const uint8_t *p; - int r; - - assert(a); - assert(ret); - - p = (const uint8_t*) a; - - if (family == AF_INET) - r = asprintf(ret, "%u.%u.%u.%u.in-addr.arpa", p[3], p[2], p[1], p[0]); - else if (family == AF_INET6) - r = asprintf(ret, "%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.ip6.arpa", - hexchar(p[15] & 0xF), hexchar(p[15] >> 4), hexchar(p[14] & 0xF), hexchar(p[14] >> 4), - hexchar(p[13] & 0xF), hexchar(p[13] >> 4), hexchar(p[12] & 0xF), hexchar(p[12] >> 4), - hexchar(p[11] & 0xF), hexchar(p[11] >> 4), hexchar(p[10] & 0xF), hexchar(p[10] >> 4), - hexchar(p[ 9] & 0xF), hexchar(p[ 9] >> 4), hexchar(p[ 8] & 0xF), hexchar(p[ 8] >> 4), - hexchar(p[ 7] & 0xF), hexchar(p[ 7] >> 4), hexchar(p[ 6] & 0xF), hexchar(p[ 6] >> 4), - hexchar(p[ 5] & 0xF), hexchar(p[ 5] >> 4), hexchar(p[ 4] & 0xF), hexchar(p[ 4] >> 4), - hexchar(p[ 3] & 0xF), hexchar(p[ 3] >> 4), hexchar(p[ 2] & 0xF), hexchar(p[ 2] >> 4), - hexchar(p[ 1] & 0xF), hexchar(p[ 1] >> 4), hexchar(p[ 0] & 0xF), hexchar(p[ 0] >> 4)); - else - return -EAFNOSUPPORT; - if (r < 0) - return -ENOMEM; - - return 0; -} - -int dns_name_address(const char *p, int *family, union in_addr_union *address) { - int r; - - assert(p); - assert(family); - assert(address); - - r = dns_name_endswith(p, "in-addr.arpa"); - if (r < 0) - return r; - if (r > 0) { - uint8_t a[4]; - unsigned i; - - for (i = 0; i < ELEMENTSOF(a); i++) { - char label[DNS_LABEL_MAX+1]; - - r = dns_label_unescape(&p, label, sizeof(label)); - if (r < 0) - return r; - if (r == 0) - return -EINVAL; - if (r > 3) - return -EINVAL; - - r = safe_atou8(label, &a[i]); - if (r < 0) - return r; - } - - r = dns_name_equal(p, "in-addr.arpa"); - if (r <= 0) - return r; - - *family = AF_INET; - address->in.s_addr = htobe32(((uint32_t) a[3] << 24) | - ((uint32_t) a[2] << 16) | - ((uint32_t) a[1] << 8) | - (uint32_t) a[0]); - - return 1; - } - - r = dns_name_endswith(p, "ip6.arpa"); - if (r < 0) - return r; - if (r > 0) { - struct in6_addr a; - unsigned i; - - for (i = 0; i < ELEMENTSOF(a.s6_addr); i++) { - char label[DNS_LABEL_MAX+1]; - int x, y; - - r = dns_label_unescape(&p, label, sizeof(label)); - if (r <= 0) - return r; - if (r != 1) - return -EINVAL; - x = unhexchar(label[0]); - if (x < 0) - return -EINVAL; - - r = dns_label_unescape(&p, label, sizeof(label)); - if (r <= 0) - return r; - if (r != 1) - return -EINVAL; - y = unhexchar(label[0]); - if (y < 0) - return -EINVAL; - - a.s6_addr[ELEMENTSOF(a.s6_addr) - i - 1] = (uint8_t) y << 4 | (uint8_t) x; - } - - r = dns_name_equal(p, "ip6.arpa"); - if (r <= 0) - return r; - - *family = AF_INET6; - address->in6 = a; - return 1; - } - - return 0; -} - -int dns_name_root(const char *name) { - char label[DNS_LABEL_MAX+1]; - int r; - - assert(name); - - r = dns_label_unescape(&name, label, sizeof(label)); - if (r < 0) - return r; - - return r == 0 && *name == 0; -} - -int dns_name_single_label(const char *name) { - char label[DNS_LABEL_MAX+1]; - int r; - - assert(name); - - r = dns_label_unescape(&name, label, sizeof(label)); - if (r < 0) - return r; - if (r == 0) - return 0; - - r = dns_label_unescape(&name, label, sizeof(label)); - if (r < 0) - return r; - - return r == 0 && *name == 0; -} diff --git a/src/resolve/resolved-dns-domain.h b/src/resolve/resolved-dns-domain.h deleted file mode 100644 index 516d244f7a..0000000000 --- a/src/resolve/resolved-dns-domain.h +++ /dev/null @@ -1,50 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . - ***/ - -#pragma once - - -#include "hashmap.h" -#include "in-addr-util.h" - -#define DNS_LABEL_MAX 63 -#define DNS_NAME_MAX 255 - -int dns_label_unescape(const char **name, char *dest, size_t sz); -int dns_label_escape(const char *p, size_t l, char **ret); - -int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max); -int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max); - -int dns_name_normalize(const char *s, char **_ret); - -unsigned long dns_name_hash_func(const void *s, const uint8_t hash_key[HASH_KEY_SIZE]); -int dns_name_compare_func(const void *a, const void *b); -extern const struct hash_ops dns_name_hash_ops; - -int dns_name_equal(const char *x, const char *y); -int dns_name_endswith(const char *name, const char *suffix); - -int dns_name_reverse(int family, const union in_addr_union *a, char **ret); -int dns_name_address(const char *p, int *family, union in_addr_union *a); - -int dns_name_root(const char *name); -int dns_name_single_label(const char *name); diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 21756f566f..bb74b1828e 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -23,7 +23,7 @@ #include "util.h" #include "strv.h" #include "unaligned.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-dns-packet.h" int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) { diff --git a/src/resolve/resolved-dns-question.c b/src/resolve/resolved-dns-question.c index 45bcbbf23a..4d71f5e3d4 100644 --- a/src/resolve/resolved-dns-question.c +++ b/src/resolve/resolved-dns-question.c @@ -20,7 +20,7 @@ ***/ #include "resolved-dns-question.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" DnsQuestion *dns_question_new(unsigned n) { DnsQuestion *q; diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 78d9e4a412..c1818eef9c 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -23,7 +23,7 @@ #include "strv.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-dns-rr.h" #include "resolved-dns-packet.h" #include "dns-type.h" diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index 7369cbf50f..c25ac2216d 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -27,7 +27,7 @@ #include "af-list.h" #include "random-util.h" #include "hostname-util.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-dns-scope.h" #define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC) diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c index a4c9b7d7af..32d771a954 100644 --- a/src/resolve/resolved-dns-zone.c +++ b/src/resolve/resolved-dns-zone.c @@ -22,7 +22,7 @@ #include "list.h" #include "resolved-dns-zone.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-dns-packet.h" /* Never allow more than 1K entries */ diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 7fc2803ddb..f8d4db7aad 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -34,7 +34,7 @@ #include "random-util.h" #include "hostname-util.h" -#include "resolved-dns-domain.h" +#include "dns-domain.h" #include "resolved-conf.h" #include "resolved-bus.h" #include "resolved-manager.h" diff --git a/src/resolve/test-dns-domain.c b/src/resolve/test-dns-domain.c deleted file mode 100644 index c3208abc78..0000000000 --- a/src/resolve/test-dns-domain.c +++ /dev/null @@ -1,192 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . - ***/ - -#include "macro.h" -#include "resolved-dns-domain.h" - -static void test_dns_label_unescape_one(const char *what, const char *expect, size_t buffer_sz, int ret) { - char buffer[buffer_sz]; - int r; - - r = dns_label_unescape(&what, buffer, buffer_sz); - assert_se(r == ret); - - if (r < 0) - return; - - assert_se(streq(buffer, expect)); -} - -static void test_dns_label_unescape(void) { - test_dns_label_unescape_one("hallo", "hallo", 6, 5); - test_dns_label_unescape_one("hallo", "hallo", 4, -ENOSPC); - test_dns_label_unescape_one("", "", 10, 0); - test_dns_label_unescape_one("hallo\\.foobar", "hallo.foobar", 20, 12); - test_dns_label_unescape_one("hallo.foobar", "hallo", 10, 5); - test_dns_label_unescape_one("hallo\n.foobar", "hallo", 20, -EINVAL); - test_dns_label_unescape_one("hallo\\", "hallo", 20, -EINVAL); - test_dns_label_unescape_one("hallo\\032 ", "hallo ", 20, 7); - test_dns_label_unescape_one(".", "", 20, 0); - test_dns_label_unescape_one("..", "", 20, -EINVAL); - test_dns_label_unescape_one(".foobar", "", 20, -EINVAL); - test_dns_label_unescape_one("foobar.", "foobar", 20, 6); -} - -static void test_dns_label_escape_one(const char *what, size_t l, const char *expect, int ret) { - _cleanup_free_ char *t = NULL; - int r; - - r = dns_label_escape(what, l, &t); - assert_se(r == ret); - - if (r < 0) - return; - - assert_se(streq_ptr(expect, t)); -} - -static void test_dns_label_escape(void) { - test_dns_label_escape_one("", 0, "", 0); - test_dns_label_escape_one("hallo", 5, "hallo", 5); - test_dns_label_escape_one("hallo", 6, NULL, -EINVAL); - test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31); -} - -static void test_dns_name_normalize_one(const char *what, const char *expect, int ret) { - _cleanup_free_ char *t = NULL; - int r; - - r = dns_name_normalize(what, &t); - assert_se(r == ret); - - if (r < 0) - return; - - assert_se(streq_ptr(expect, t)); -} - -static void test_dns_name_normalize(void) { - test_dns_name_normalize_one("", "", 0); - test_dns_name_normalize_one("f", "f", 0); - test_dns_name_normalize_one("f.waldi", "f.waldi", 0); - test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0); - test_dns_name_normalize_one("\\000", NULL, -EINVAL); - test_dns_name_normalize_one("..", NULL, -EINVAL); - test_dns_name_normalize_one(".foobar", NULL, -EINVAL); - test_dns_name_normalize_one("foobar.", "foobar", 0); - test_dns_name_normalize_one(".", "", 0); -} - -static void test_dns_name_equal_one(const char *a, const char *b, int ret) { - int r; - - r = dns_name_equal(a, b); - assert_se(r == ret); - - r = dns_name_equal(b, a); - assert_se(r == ret); -} - -static void test_dns_name_equal(void) { - test_dns_name_equal_one("", "", true); - test_dns_name_equal_one("x", "x", true); - test_dns_name_equal_one("x", "x.", true); - test_dns_name_equal_one("abc.def", "abc.def", true); - test_dns_name_equal_one("abc.def", "ABC.def", true); - test_dns_name_equal_one("abc.def", "CBA.def", false); - test_dns_name_equal_one("", "xxx", false); - test_dns_name_equal_one("ab", "a", false); - test_dns_name_equal_one("\\000", "xxxx", -EINVAL); - test_dns_name_equal_one(".", "", true); - test_dns_name_equal_one(".", ".", true); - test_dns_name_equal_one("..", "..", -EINVAL); -} - -static void test_dns_name_endswith_one(const char *a, const char *b, int ret) { - assert_se(dns_name_endswith(a, b) == ret); -} - -static void test_dns_name_endswith(void) { - test_dns_name_endswith_one("", "", true); - test_dns_name_endswith_one("", "xxx", false); - test_dns_name_endswith_one("xxx", "", true); - test_dns_name_endswith_one("x", "x", true); - test_dns_name_endswith_one("x", "y", false); - test_dns_name_endswith_one("x.y", "y", true); - test_dns_name_endswith_one("x.y", "Y", true); - test_dns_name_endswith_one("x.y", "x", false); - test_dns_name_endswith_one("x.y.z", "Z", true); - test_dns_name_endswith_one("x.y.z", "y.Z", true); - test_dns_name_endswith_one("x.y.z", "x.y.Z", true); - test_dns_name_endswith_one("x.y.z", "waldo", false); - test_dns_name_endswith_one("x.y.z.u.v.w", "y.z", false); - test_dns_name_endswith_one("x.y.z.u.v.w", "u.v.w", true); - test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL); -} - -static void test_dns_name_root(void) { - assert_se(dns_name_root("") == true); - assert_se(dns_name_root(".") == true); - assert_se(dns_name_root("xxx") == false); - assert_se(dns_name_root("xxx.") == false); - assert_se(dns_name_root("..") == -EINVAL); -} - -static void test_dns_name_single_label(void) { - assert_se(dns_name_single_label("") == false); - assert_se(dns_name_single_label(".") == false); - assert_se(dns_name_single_label("..") == -EINVAL); - assert_se(dns_name_single_label("x") == true); - assert_se(dns_name_single_label("x.") == true); - assert_se(dns_name_single_label("xx.yy") == false); -} - -static void test_dns_name_reverse_one(const char *address, const char *name) { - _cleanup_free_ char *p = NULL; - union in_addr_union a, b = {}; - int familya, familyb; - - assert_se(in_addr_from_string_auto(address, &familya, &a) >= 0); - assert_se(dns_name_reverse(familya, &a, &p) >= 0); - assert_se(streq(p, name)); - assert_se(dns_name_address(p, &familyb, &b) > 0); - assert_se(familya == familyb); - assert_se(in_addr_equal(familya, &a, &b)); -} - -static void test_dns_name_reverse(void) { - test_dns_name_reverse_one("47.11.8.15", "15.8.11.47.in-addr.arpa"); - test_dns_name_reverse_one("fe80::47", "7.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa"); -} - -int main(int argc, char *argv[]) { - - test_dns_label_unescape(); - test_dns_label_escape(); - test_dns_name_normalize(); - test_dns_name_equal(); - test_dns_name_endswith(); - test_dns_name_root(); - test_dns_name_single_label(); - test_dns_name_reverse(); - - return 0; -} -- cgit v1.2.3-54-g00ecf