chiark / gitweb /
shared: dns-name - add dns_name_between()
[elogind.git] / src / test / test-dns-domain.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2014 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20  ***/
21
22 #include "macro.h"
23 #include "dns-domain.h"
24
25 static void test_dns_label_unescape_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
26         char buffer[buffer_sz];
27         int r;
28
29         r = dns_label_unescape(&what, buffer, buffer_sz);
30         assert_se(r == ret);
31
32         if (r < 0)
33                 return;
34
35         assert_se(streq(buffer, expect));
36 }
37
38 static void test_dns_label_unescape(void) {
39         test_dns_label_unescape_one("hallo", "hallo", 6, 5);
40         test_dns_label_unescape_one("hallo", "hallo", 4, -ENOSPC);
41         test_dns_label_unescape_one("", "", 10, 0);
42         test_dns_label_unescape_one("hallo\\.foobar", "hallo.foobar", 20, 12);
43         test_dns_label_unescape_one("hallo.foobar", "hallo", 10, 5);
44         test_dns_label_unescape_one("hallo\n.foobar", "hallo", 20, -EINVAL);
45         test_dns_label_unescape_one("hallo\\", "hallo", 20, -EINVAL);
46         test_dns_label_unescape_one("hallo\\032 ", "hallo  ", 20, 7);
47         test_dns_label_unescape_one(".", "", 20, 0);
48         test_dns_label_unescape_one("..", "", 20, -EINVAL);
49         test_dns_label_unescape_one(".foobar", "", 20, -EINVAL);
50         test_dns_label_unescape_one("foobar.", "foobar", 20, 6);
51 }
52
53 static void test_dns_label_escape_one(const char *what, size_t l, const char *expect, int ret) {
54         _cleanup_free_ char *t = NULL;
55         int r;
56
57         r = dns_label_escape(what, l, &t);
58         assert_se(r == ret);
59
60         if (r < 0)
61                 return;
62
63         assert_se(streq_ptr(expect, t));
64 }
65
66 static void test_dns_label_escape(void) {
67         test_dns_label_escape_one("", 0, "", 0);
68         test_dns_label_escape_one("hallo", 5, "hallo", 5);
69         test_dns_label_escape_one("hallo", 6, NULL, -EINVAL);
70         test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
71 }
72
73 static void test_dns_name_normalize_one(const char *what, const char *expect, int ret) {
74         _cleanup_free_ char *t = NULL;
75         int r;
76
77         r = dns_name_normalize(what, &t);
78         assert_se(r == ret);
79
80         if (r < 0)
81                 return;
82
83         assert_se(streq_ptr(expect, t));
84 }
85
86 static void test_dns_name_normalize(void) {
87         test_dns_name_normalize_one("", "", 0);
88         test_dns_name_normalize_one("f", "f", 0);
89         test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
90         test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
91         test_dns_name_normalize_one("\\000", NULL, -EINVAL);
92         test_dns_name_normalize_one("..", NULL, -EINVAL);
93         test_dns_name_normalize_one(".foobar", NULL, -EINVAL);
94         test_dns_name_normalize_one("foobar.", "foobar", 0);
95         test_dns_name_normalize_one(".", "", 0);
96 }
97
98 static void test_dns_name_equal_one(const char *a, const char *b, int ret) {
99         int r;
100
101         r = dns_name_equal(a, b);
102         assert_se(r == ret);
103
104         r = dns_name_equal(b, a);
105         assert_se(r == ret);
106 }
107
108 static void test_dns_name_equal(void) {
109         test_dns_name_equal_one("", "", true);
110         test_dns_name_equal_one("x", "x", true);
111         test_dns_name_equal_one("x", "x.", true);
112         test_dns_name_equal_one("abc.def", "abc.def", true);
113         test_dns_name_equal_one("abc.def", "ABC.def", true);
114         test_dns_name_equal_one("abc.def", "CBA.def", false);
115         test_dns_name_equal_one("", "xxx", false);
116         test_dns_name_equal_one("ab", "a", false);
117         test_dns_name_equal_one("\\000", "xxxx", -EINVAL);
118         test_dns_name_equal_one(".", "", true);
119         test_dns_name_equal_one(".", ".", true);
120         test_dns_name_equal_one("..", "..", -EINVAL);
121 }
122
123 static void test_dns_name_between_one(const char *a, const char *b, const char *c, int ret) {
124         int r;
125
126         r = dns_name_between(a, b, c);
127         assert_se(r == ret);
128
129         r = dns_name_between(c, b, a);
130         if (ret >= 0)
131                 assert_se(r == 0);
132         else
133                 assert_se(r == ret);
134 }
135
136 static void test_dns_name_between(void) {
137         /* see https://tools.ietf.org/html/rfc4034#section-6.1
138            Note that we use "\033.z.example" in stead of "\001.z.example" as we
139            consider the latter invalid */
140         test_dns_name_between_one("example", "a.example", "yljkjljk.a.example", true);
141         test_dns_name_between_one("a.example", "yljkjljk.a.example", "Z.a.example", true);
142         test_dns_name_between_one("yljkjljk.a.example", "Z.a.example", "zABC.a.EXAMPLE", true);
143         test_dns_name_between_one("Z.a.example", "zABC.a.EXAMPLE", "z.example", true);
144         test_dns_name_between_one("zABC.a.EXAMPLE", "z.example", "\\033.z.example", true);
145         test_dns_name_between_one("z.example", "\\033.z.example", "*.z.example", true);
146         test_dns_name_between_one("\\033.z.example", "*.z.example", "\\200.z.example", true);
147         test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
148         test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
149
150         test_dns_name_between_one("example", "a.example", "example", -EINVAL);
151         test_dns_name_between_one("example", "example", "yljkjljk.a.example", false);
152         test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false);
153 }
154
155 static void test_dns_name_endswith_one(const char *a, const char *b, int ret) {
156         assert_se(dns_name_endswith(a, b) == ret);
157 }
158
159 static void test_dns_name_endswith(void) {
160         test_dns_name_endswith_one("", "", true);
161         test_dns_name_endswith_one("", "xxx", false);
162         test_dns_name_endswith_one("xxx", "", true);
163         test_dns_name_endswith_one("x", "x", true);
164         test_dns_name_endswith_one("x", "y", false);
165         test_dns_name_endswith_one("x.y", "y", true);
166         test_dns_name_endswith_one("x.y", "Y", true);
167         test_dns_name_endswith_one("x.y", "x", false);
168         test_dns_name_endswith_one("x.y.z", "Z", true);
169         test_dns_name_endswith_one("x.y.z", "y.Z", true);
170         test_dns_name_endswith_one("x.y.z", "x.y.Z", true);
171         test_dns_name_endswith_one("x.y.z", "waldo", false);
172         test_dns_name_endswith_one("x.y.z.u.v.w", "y.z", false);
173         test_dns_name_endswith_one("x.y.z.u.v.w", "u.v.w", true);
174         test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL);
175 }
176
177 static void test_dns_name_root(void) {
178         assert_se(dns_name_root("") == true);
179         assert_se(dns_name_root(".") == true);
180         assert_se(dns_name_root("xxx") == false);
181         assert_se(dns_name_root("xxx.") == false);
182         assert_se(dns_name_root("..") == -EINVAL);
183 }
184
185 static void test_dns_name_single_label(void) {
186         assert_se(dns_name_single_label("") == false);
187         assert_se(dns_name_single_label(".") == false);
188         assert_se(dns_name_single_label("..") == -EINVAL);
189         assert_se(dns_name_single_label("x") == true);
190         assert_se(dns_name_single_label("x.") == true);
191         assert_se(dns_name_single_label("xx.yy") == false);
192 }
193
194 static void test_dns_name_reverse_one(const char *address, const char *name) {
195         _cleanup_free_ char *p = NULL;
196         union in_addr_union a, b = {};
197         int familya, familyb;
198
199         assert_se(in_addr_from_string_auto(address, &familya, &a) >= 0);
200         assert_se(dns_name_reverse(familya, &a, &p) >= 0);
201         assert_se(streq(p, name));
202         assert_se(dns_name_address(p, &familyb, &b) > 0);
203         assert_se(familya == familyb);
204         assert_se(in_addr_equal(familya, &a, &b));
205 }
206
207 static void test_dns_name_reverse(void) {
208         test_dns_name_reverse_one("47.11.8.15", "15.8.11.47.in-addr.arpa");
209         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");
210 }
211
212 int main(int argc, char *argv[]) {
213
214         test_dns_label_unescape();
215         test_dns_label_escape();
216         test_dns_name_normalize();
217         test_dns_name_equal();
218         test_dns_name_endswith();
219         test_dns_name_between();
220         test_dns_name_root();
221         test_dns_name_single_label();
222         test_dns_name_reverse();
223
224         return 0;
225 }