]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-dns-domain.c
Merge pull request #7469 from kinvolk/dongsu/nspawn-netns
[thirdparty/systemd.git] / src / test / test-dns-domain.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2014 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include "alloc-util.h"
22 #include "dns-domain.h"
23 #include "macro.h"
24 #include "string-util.h"
25
26 static void test_dns_label_unescape_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
27 char buffer[buffer_sz];
28 int r;
29
30 r = dns_label_unescape(&what, buffer, buffer_sz);
31 assert_se(r == ret);
32
33 if (r < 0)
34 return;
35
36 assert_se(streq(buffer, expect));
37 }
38
39 static void test_dns_label_unescape(void) {
40 test_dns_label_unescape_one("hallo", "hallo", 6, 5);
41 test_dns_label_unescape_one("hallo", "hallo", 4, -ENOBUFS);
42 test_dns_label_unescape_one("", "", 10, 0);
43 test_dns_label_unescape_one("hallo\\.foobar", "hallo.foobar", 20, 12);
44 test_dns_label_unescape_one("hallo.foobar", "hallo", 10, 5);
45 test_dns_label_unescape_one("hallo\n.foobar", "hallo", 20, -EINVAL);
46 test_dns_label_unescape_one("hallo\\", "hallo", 20, -EINVAL);
47 test_dns_label_unescape_one("hallo\\032 ", "hallo ", 20, 7);
48 test_dns_label_unescape_one(".", "", 20, 0);
49 test_dns_label_unescape_one("..", "", 20, -EINVAL);
50 test_dns_label_unescape_one(".foobar", "", 20, -EINVAL);
51 test_dns_label_unescape_one("foobar.", "foobar", 20, 6);
52 test_dns_label_unescape_one("foobar..", "foobar", 20, -EINVAL);
53 }
54
55 static void test_dns_name_to_wire_format_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
56 uint8_t buffer[buffer_sz];
57 int r;
58
59 r = dns_name_to_wire_format(what, buffer, buffer_sz, false);
60 assert_se(r == ret);
61
62 if (r < 0)
63 return;
64
65 assert_se(!memcmp(buffer, expect, r));
66 }
67
68 static void test_dns_name_to_wire_format(void) {
69 static const char out0[] = { 0 };
70 static const char out1[] = { 3, 'f', 'o', 'o', 0 };
71 static const char out2[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
72 static const char out3[] = { 4, ' ', 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
73 static const char out4[] = { 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
74 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
75 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
76 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
77 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
78 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
79 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
80 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
81 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
82 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
83 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
84 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
85 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
86 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
87 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
88 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
89 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
90 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
91 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
92 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
93 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
94 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
95 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
96 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
97 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
98 3, 'a', '1', '2', 0 };
99
100 test_dns_name_to_wire_format_one("", out0, sizeof(out0), sizeof(out0));
101
102 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1), sizeof(out1));
103 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1) + 1, sizeof(out1));
104 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1) - 1, -ENOBUFS);
105
106 test_dns_name_to_wire_format_one("hallo.foo.bar", out2, sizeof(out2), sizeof(out2));
107 test_dns_name_to_wire_format_one("hallo.foo..bar", NULL, 32, -EINVAL);
108
109 test_dns_name_to_wire_format_one("\\032foo.bar", out3, sizeof(out3), sizeof(out3));
110
111 test_dns_name_to_wire_format_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a123", NULL, 500, -EINVAL);
112 test_dns_name_to_wire_format_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12", out4, sizeof(out4), sizeof(out4));
113 }
114
115 static void test_dns_label_unescape_suffix_one(const char *what, const char *expect1, const char *expect2, size_t buffer_sz, int ret1, int ret2) {
116 char buffer[buffer_sz];
117 const char *label;
118 int r;
119
120 label = what + strlen(what);
121
122 r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz);
123 assert_se(r == ret1);
124 if (r >= 0)
125 assert_se(streq(buffer, expect1));
126
127 r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz);
128 assert_se(r == ret2);
129 if (r >= 0)
130 assert_se(streq(buffer, expect2));
131 }
132
133 static void test_dns_label_unescape_suffix(void) {
134 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 6, 5, 0);
135 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOBUFS, -ENOBUFS);
136 test_dns_label_unescape_suffix_one("", "", "", 10, 0, 0);
137 test_dns_label_unescape_suffix_one("hallo\\.foobar", "hallo.foobar", "", 20, 12, 0);
138 test_dns_label_unescape_suffix_one("hallo.foobar", "foobar", "hallo", 10, 6, 5);
139 test_dns_label_unescape_suffix_one("hallo.foobar\n", "foobar", "foobar", 20, -EINVAL, -EINVAL);
140 test_dns_label_unescape_suffix_one("hallo\\", "hallo", "hallo", 20, -EINVAL, -EINVAL);
141 test_dns_label_unescape_suffix_one("hallo\\032 ", "hallo ", "", 20, 7, 0);
142 test_dns_label_unescape_suffix_one(".", "", "", 20, 0, 0);
143 test_dns_label_unescape_suffix_one("..", "", "", 20, 0, -EINVAL);
144 test_dns_label_unescape_suffix_one(".foobar", "foobar", "", 20, 6, -EINVAL);
145 test_dns_label_unescape_suffix_one("foobar.", "foobar", "", 20, 6, 0);
146 test_dns_label_unescape_suffix_one("foo\\\\bar", "foo\\bar", "", 20, 7, 0);
147 test_dns_label_unescape_suffix_one("foo.bar", "bar", "foo", 20, 3, 3);
148 test_dns_label_unescape_suffix_one("foo..bar", "bar", "", 20, 3, -EINVAL);
149 test_dns_label_unescape_suffix_one("foo...bar", "bar", "", 20, 3, -EINVAL);
150 test_dns_label_unescape_suffix_one("foo\\.bar", "foo.bar", "", 20, 7, 0);
151 test_dns_label_unescape_suffix_one("foo\\\\.bar", "bar", "foo\\", 20, 3, 4);
152 test_dns_label_unescape_suffix_one("foo\\\\\\.bar", "foo\\.bar", "", 20, 8, 0);
153 }
154
155 static void test_dns_label_escape_one(const char *what, size_t l, const char *expect, int ret) {
156 _cleanup_free_ char *t = NULL;
157 int r;
158
159 r = dns_label_escape_new(what, l, &t);
160 assert_se(r == ret);
161
162 if (r < 0)
163 return;
164
165 assert_se(streq_ptr(expect, t));
166 }
167
168 static void test_dns_label_escape(void) {
169 test_dns_label_escape_one("", 0, NULL, -EINVAL);
170 test_dns_label_escape_one("hallo", 5, "hallo", 5);
171 test_dns_label_escape_one("hallo", 6, "hallo\\000", 9);
172 test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
173 }
174
175 static void test_dns_name_normalize_one(const char *what, const char *expect, int ret) {
176 _cleanup_free_ char *t = NULL;
177 int r;
178
179 r = dns_name_normalize(what, &t);
180 assert_se(r == ret);
181
182 if (r < 0)
183 return;
184
185 assert_se(streq_ptr(expect, t));
186 }
187
188 static void test_dns_name_normalize(void) {
189 test_dns_name_normalize_one("", ".", 0);
190 test_dns_name_normalize_one("f", "f", 0);
191 test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
192 test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
193 test_dns_name_normalize_one("\\000", "\\000", 0);
194 test_dns_name_normalize_one("..", NULL, -EINVAL);
195 test_dns_name_normalize_one(".foobar", NULL, -EINVAL);
196 test_dns_name_normalize_one("foobar.", "foobar", 0);
197 test_dns_name_normalize_one(".", ".", 0);
198 }
199
200 static void test_dns_name_equal_one(const char *a, const char *b, int ret) {
201 int r;
202
203 r = dns_name_equal(a, b);
204 assert_se(r == ret);
205
206 r = dns_name_equal(b, a);
207 assert_se(r == ret);
208 }
209
210 static void test_dns_name_equal(void) {
211 test_dns_name_equal_one("", "", true);
212 test_dns_name_equal_one("x", "x", true);
213 test_dns_name_equal_one("x", "x.", true);
214 test_dns_name_equal_one("abc.def", "abc.def", true);
215 test_dns_name_equal_one("abc.def", "ABC.def", true);
216 test_dns_name_equal_one("abc.def", "CBA.def", false);
217 test_dns_name_equal_one("", "xxx", false);
218 test_dns_name_equal_one("ab", "a", false);
219 test_dns_name_equal_one("\\000", "\\000", true);
220 test_dns_name_equal_one(".", "", true);
221 test_dns_name_equal_one(".", ".", true);
222 test_dns_name_equal_one("..", "..", -EINVAL);
223 }
224
225 static void test_dns_name_between_one(const char *a, const char *b, const char *c, int ret) {
226 int r;
227
228 r = dns_name_between(a, b, c);
229 assert_se(r == ret);
230
231 r = dns_name_between(c, b, a);
232 if (ret >= 0)
233 assert_se(r == 0 || dns_name_equal(a, c) > 0);
234 else
235 assert_se(r == ret);
236 }
237
238 static void test_dns_name_between(void) {
239 /* see https://tools.ietf.org/html/rfc4034#section-6.1
240 Note that we use "\033.z.example" in stead of "\001.z.example" as we
241 consider the latter invalid */
242 test_dns_name_between_one("example", "a.example", "yljkjljk.a.example", true);
243 test_dns_name_between_one("a.example", "yljkjljk.a.example", "Z.a.example", true);
244 test_dns_name_between_one("yljkjljk.a.example", "Z.a.example", "zABC.a.EXAMPLE", true);
245 test_dns_name_between_one("Z.a.example", "zABC.a.EXAMPLE", "z.example", true);
246 test_dns_name_between_one("zABC.a.EXAMPLE", "z.example", "\\033.z.example", true);
247 test_dns_name_between_one("z.example", "\\033.z.example", "*.z.example", true);
248 test_dns_name_between_one("\\033.z.example", "*.z.example", "\\200.z.example", true);
249 test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
250 test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
251
252 test_dns_name_between_one("example", "a.example", "example", true);
253 test_dns_name_between_one("example", "example", "example", false);
254 test_dns_name_between_one("example", "example", "yljkjljk.a.example", false);
255 test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false);
256 }
257
258 static void test_dns_name_endswith_one(const char *a, const char *b, int ret) {
259 assert_se(dns_name_endswith(a, b) == ret);
260 }
261
262 static void test_dns_name_endswith(void) {
263 test_dns_name_endswith_one("", "", true);
264 test_dns_name_endswith_one("", "xxx", false);
265 test_dns_name_endswith_one("xxx", "", true);
266 test_dns_name_endswith_one("x", "x", true);
267 test_dns_name_endswith_one("x", "y", false);
268 test_dns_name_endswith_one("x.y", "y", true);
269 test_dns_name_endswith_one("x.y", "Y", true);
270 test_dns_name_endswith_one("x.y", "x", false);
271 test_dns_name_endswith_one("x.y.z", "Z", true);
272 test_dns_name_endswith_one("x.y.z", "y.Z", true);
273 test_dns_name_endswith_one("x.y.z", "x.y.Z", true);
274 test_dns_name_endswith_one("x.y.z", "waldo", false);
275 test_dns_name_endswith_one("x.y.z.u.v.w", "y.z", false);
276 test_dns_name_endswith_one("x.y.z.u.v.w", "u.v.w", true);
277 test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL);
278 }
279
280 static void test_dns_name_startswith_one(const char *a, const char *b, int ret) {
281 assert_se(dns_name_startswith(a, b) == ret);
282 }
283
284 static void test_dns_name_startswith(void) {
285 test_dns_name_startswith_one("", "", true);
286 test_dns_name_startswith_one("", "xxx", false);
287 test_dns_name_startswith_one("xxx", "", true);
288 test_dns_name_startswith_one("x", "x", true);
289 test_dns_name_startswith_one("x", "y", false);
290 test_dns_name_startswith_one("x.y", "x.y", true);
291 test_dns_name_startswith_one("x.y", "y.x", false);
292 test_dns_name_startswith_one("x.y", "x", true);
293 test_dns_name_startswith_one("x.y", "X", true);
294 test_dns_name_startswith_one("x.y", "y", false);
295 test_dns_name_startswith_one("x.y", "", true);
296 test_dns_name_startswith_one("x.y", "X", true);
297 }
298
299 static void test_dns_name_is_root(void) {
300 assert_se(dns_name_is_root(""));
301 assert_se(dns_name_is_root("."));
302 assert_se(!dns_name_is_root("xxx"));
303 assert_se(!dns_name_is_root("xxx."));
304 assert_se(!dns_name_is_root(".."));
305 }
306
307 static void test_dns_name_is_single_label(void) {
308 assert_se(!dns_name_is_single_label(""));
309 assert_se(!dns_name_is_single_label("."));
310 assert_se(!dns_name_is_single_label(".."));
311 assert_se(dns_name_is_single_label("x"));
312 assert_se(dns_name_is_single_label("x."));
313 assert_se(!dns_name_is_single_label("xx.yy"));
314 }
315
316 static void test_dns_name_reverse_one(const char *address, const char *name) {
317 _cleanup_free_ char *p = NULL;
318 union in_addr_union a, b = {};
319 int familya, familyb;
320
321 assert_se(in_addr_from_string_auto(address, &familya, &a) >= 0);
322 assert_se(dns_name_reverse(familya, &a, &p) >= 0);
323 assert_se(streq(p, name));
324 assert_se(dns_name_address(p, &familyb, &b) > 0);
325 assert_se(familya == familyb);
326 assert_se(in_addr_equal(familya, &a, &b));
327 }
328
329 static void test_dns_name_reverse(void) {
330 test_dns_name_reverse_one("47.11.8.15", "15.8.11.47.in-addr.arpa");
331 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");
332 test_dns_name_reverse_one("127.0.0.1", "1.0.0.127.in-addr.arpa");
333 test_dns_name_reverse_one("::1", "1.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.0.0.0.0.ip6.arpa");
334 }
335
336 static void test_dns_name_concat_one(const char *a, const char *b, int r, const char *result) {
337 _cleanup_free_ char *p = NULL;
338
339 assert_se(dns_name_concat(a, b, &p) == r);
340 assert_se(streq_ptr(p, result));
341 }
342
343 static void test_dns_name_concat(void) {
344 test_dns_name_concat_one("", "", 0, ".");
345 test_dns_name_concat_one(".", "", 0, ".");
346 test_dns_name_concat_one("", ".", 0, ".");
347 test_dns_name_concat_one(".", ".", 0, ".");
348 test_dns_name_concat_one("foo", "bar", 0, "foo.bar");
349 test_dns_name_concat_one("foo.foo", "bar.bar", 0, "foo.foo.bar.bar");
350 test_dns_name_concat_one("foo", NULL, 0, "foo");
351 test_dns_name_concat_one("foo", ".", 0, "foo");
352 test_dns_name_concat_one("foo.", "bar.", 0, "foo.bar");
353 test_dns_name_concat_one(NULL, NULL, 0, ".");
354 test_dns_name_concat_one(NULL, ".", 0, ".");
355 test_dns_name_concat_one(NULL, "foo", 0, "foo");
356 }
357
358 static void test_dns_name_is_valid_one(const char *s, int ret) {
359 assert_se(dns_name_is_valid(s) == ret);
360 }
361
362 static void test_dns_name_is_valid(void) {
363 test_dns_name_is_valid_one("foo", 1);
364 test_dns_name_is_valid_one("foo.", 1);
365 test_dns_name_is_valid_one("foo..", 0);
366 test_dns_name_is_valid_one("Foo", 1);
367 test_dns_name_is_valid_one("foo.bar", 1);
368 test_dns_name_is_valid_one("foo.bar.baz", 1);
369 test_dns_name_is_valid_one("", 1);
370 test_dns_name_is_valid_one("foo..bar", 0);
371 test_dns_name_is_valid_one(".foo.bar", 0);
372 test_dns_name_is_valid_one("foo.bar.", 1);
373 test_dns_name_is_valid_one("foo.bar..", 0);
374 test_dns_name_is_valid_one("\\zbar", 0);
375 test_dns_name_is_valid_one("ä", 1);
376 test_dns_name_is_valid_one("\n", 0);
377
378 /* 256 characters */
379 test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345", 0);
380
381 /* 255 characters */
382 test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a1234", 0);
383
384 /* 254 characters */
385 test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a123", 0);
386
387 /* 253 characters */
388 test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12", 1);
389
390 /* label of 64 chars length */
391 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a123", 0);
392
393 /* label of 63 chars length */
394 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a12", 1);
395 }
396
397 static void test_dns_service_name_is_valid(void) {
398 assert_se(dns_service_name_is_valid("Lennart's Compüter"));
399 assert_se(dns_service_name_is_valid("piff.paff"));
400
401 assert_se(!dns_service_name_is_valid(NULL));
402 assert_se(!dns_service_name_is_valid(""));
403 assert_se(!dns_service_name_is_valid("foo\nbar"));
404 assert_se(!dns_service_name_is_valid("foo\201bar"));
405 assert_se(!dns_service_name_is_valid("this is an overly long string that is certainly longer than 63 characters"));
406 }
407
408 static void test_dns_srv_type_is_valid(void) {
409
410 assert_se(dns_srv_type_is_valid("_http._tcp"));
411 assert_se(dns_srv_type_is_valid("_foo-bar._tcp"));
412 assert_se(dns_srv_type_is_valid("_w._udp"));
413 assert_se(dns_srv_type_is_valid("_a800._tcp"));
414 assert_se(dns_srv_type_is_valid("_a-800._tcp"));
415
416 assert_se(!dns_srv_type_is_valid(NULL));
417 assert_se(!dns_srv_type_is_valid(""));
418 assert_se(!dns_srv_type_is_valid("x"));
419 assert_se(!dns_srv_type_is_valid("_foo"));
420 assert_se(!dns_srv_type_is_valid("_tcp"));
421 assert_se(!dns_srv_type_is_valid("_"));
422 assert_se(!dns_srv_type_is_valid("_foo."));
423 assert_se(!dns_srv_type_is_valid("_föo._tcp"));
424 assert_se(!dns_srv_type_is_valid("_f\no._tcp"));
425 assert_se(!dns_srv_type_is_valid("_800._tcp"));
426 assert_se(!dns_srv_type_is_valid("_-800._tcp"));
427 assert_se(!dns_srv_type_is_valid("_-foo._tcp"));
428 assert_se(!dns_srv_type_is_valid("_piep._foo._udp"));
429 }
430
431 static void test_dnssd_srv_type_is_valid(void) {
432
433 assert_se(dnssd_srv_type_is_valid("_http._tcp"));
434 assert_se(dnssd_srv_type_is_valid("_foo-bar._tcp"));
435 assert_se(dnssd_srv_type_is_valid("_w._udp"));
436 assert_se(dnssd_srv_type_is_valid("_a800._tcp"));
437 assert_se(dnssd_srv_type_is_valid("_a-800._tcp"));
438
439 assert_se(!dnssd_srv_type_is_valid(NULL));
440 assert_se(!dnssd_srv_type_is_valid(""));
441 assert_se(!dnssd_srv_type_is_valid("x"));
442 assert_se(!dnssd_srv_type_is_valid("_foo"));
443 assert_se(!dnssd_srv_type_is_valid("_tcp"));
444 assert_se(!dnssd_srv_type_is_valid("_"));
445 assert_se(!dnssd_srv_type_is_valid("_foo."));
446 assert_se(!dnssd_srv_type_is_valid("_föo._tcp"));
447 assert_se(!dnssd_srv_type_is_valid("_f\no._tcp"));
448 assert_se(!dnssd_srv_type_is_valid("_800._tcp"));
449 assert_se(!dnssd_srv_type_is_valid("_-800._tcp"));
450 assert_se(!dnssd_srv_type_is_valid("_-foo._tcp"));
451 assert_se(!dnssd_srv_type_is_valid("_piep._foo._udp"));
452 assert_se(!dnssd_srv_type_is_valid("_foo._unknown"));
453 }
454
455 static void test_dns_service_join_one(const char *a, const char *b, const char *c, int r, const char *d) {
456 _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *t = NULL;
457
458 assert_se(dns_service_join(a, b, c, &t) == r);
459 assert_se(streq_ptr(t, d));
460
461 if (r < 0)
462 return;
463
464 assert_se(dns_service_split(t, &x, &y, &z) >= 0);
465 assert_se(streq_ptr(a, x));
466 assert_se(streq_ptr(b, y));
467 assert_se(dns_name_equal(c, z) > 0);
468 }
469
470 static void test_dns_service_join(void) {
471 test_dns_service_join_one("", "", "", -EINVAL, NULL);
472 test_dns_service_join_one("", "_http._tcp", "", -EINVAL, NULL);
473 test_dns_service_join_one("", "_http._tcp", "foo", -EINVAL, NULL);
474 test_dns_service_join_one("foo", "", "foo", -EINVAL, NULL);
475 test_dns_service_join_one("foo", "foo", "foo", -EINVAL, NULL);
476
477 test_dns_service_join_one("foo", "_http._tcp", "", 0, "foo._http._tcp");
478 test_dns_service_join_one(NULL, "_http._tcp", "", 0, "_http._tcp");
479 test_dns_service_join_one("foo", "_http._tcp", "foo", 0, "foo._http._tcp.foo");
480 test_dns_service_join_one(NULL, "_http._tcp", "foo", 0, "_http._tcp.foo");
481 test_dns_service_join_one("Lennart's PC", "_pc._tcp", "foo.bar.com", 0, "Lennart\\039s\\032PC._pc._tcp.foo.bar.com");
482 test_dns_service_join_one(NULL, "_pc._tcp", "foo.bar.com", 0, "_pc._tcp.foo.bar.com");
483 }
484
485 static void test_dns_service_split_one(const char *joined, const char *a, const char *b, const char *c, int r) {
486 _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *t = NULL;
487
488 assert_se(dns_service_split(joined, &x, &y, &z) == r);
489 assert_se(streq_ptr(x, a));
490 assert_se(streq_ptr(y, b));
491 assert_se(streq_ptr(z, c));
492
493 if (r < 0)
494 return;
495
496 if (y) {
497 assert_se(dns_service_join(x, y, z, &t) == 0);
498 assert_se(dns_name_equal(joined, t) > 0);
499 } else
500 assert_se(!x && dns_name_equal(z, joined) > 0);
501 }
502
503 static void test_dns_service_split(void) {
504 test_dns_service_split_one("", NULL, NULL, ".", 0);
505 test_dns_service_split_one("foo", NULL, NULL, "foo", 0);
506 test_dns_service_split_one("foo.bar", NULL, NULL, "foo.bar", 0);
507 test_dns_service_split_one("_foo.bar", NULL, NULL, "_foo.bar", 0);
508 test_dns_service_split_one("_foo._bar", NULL, "_foo._bar", ".", 0);
509 test_dns_service_split_one("_meh._foo._bar", "_meh", "_foo._bar", ".", 0);
510 test_dns_service_split_one("Wuff\\032Wuff._foo._bar.waldo.com", "Wuff Wuff", "_foo._bar", "waldo.com", 0);
511 }
512
513 static void test_dns_name_change_suffix_one(const char *name, const char *old_suffix, const char *new_suffix, int r, const char *result) {
514 _cleanup_free_ char *s = NULL;
515
516 assert_se(dns_name_change_suffix(name, old_suffix, new_suffix, &s) == r);
517 assert_se(streq_ptr(s, result));
518 }
519
520 static void test_dns_name_change_suffix(void) {
521 test_dns_name_change_suffix_one("foo.bar", "bar", "waldo", 1, "foo.waldo");
522 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "foo.bar.waldi.quux", "piff.paff", 1, "piff.paff");
523 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "bar.waldi.quux", "piff.paff", 1, "foo.piff.paff");
524 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "waldi.quux", "piff.paff", 1, "foo.bar.piff.paff");
525 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "quux", "piff.paff", 1, "foo.bar.waldi.piff.paff");
526 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "", "piff.paff", 1, "foo.bar.waldi.quux.piff.paff");
527 test_dns_name_change_suffix_one("", "", "piff.paff", 1, "piff.paff");
528 test_dns_name_change_suffix_one("", "", "", 1, ".");
529 test_dns_name_change_suffix_one("a", "b", "c", 0, NULL);
530 }
531
532 static void test_dns_name_suffix_one(const char *name, unsigned n_labels, const char *result, int ret) {
533 const char *p = NULL;
534
535 assert_se(ret == dns_name_suffix(name, n_labels, &p));
536 assert_se(streq_ptr(p, result));
537 }
538
539 static void test_dns_name_suffix(void) {
540 test_dns_name_suffix_one("foo.bar", 2, "foo.bar", 0);
541 test_dns_name_suffix_one("foo.bar", 1, "bar", 1);
542 test_dns_name_suffix_one("foo.bar", 0, "", 2);
543 test_dns_name_suffix_one("foo.bar", 3, NULL, -EINVAL);
544 test_dns_name_suffix_one("foo.bar", 4, NULL, -EINVAL);
545
546 test_dns_name_suffix_one("bar", 1, "bar", 0);
547 test_dns_name_suffix_one("bar", 0, "", 1);
548 test_dns_name_suffix_one("bar", 2, NULL, -EINVAL);
549 test_dns_name_suffix_one("bar", 3, NULL, -EINVAL);
550
551 test_dns_name_suffix_one("", 0, "", 0);
552 test_dns_name_suffix_one("", 1, NULL, -EINVAL);
553 test_dns_name_suffix_one("", 2, NULL, -EINVAL);
554 }
555
556 static void test_dns_name_count_labels_one(const char *name, int n) {
557 assert_se(dns_name_count_labels(name) == n);
558 }
559
560 static void test_dns_name_count_labels(void) {
561 test_dns_name_count_labels_one("foo.bar.quux.", 3);
562 test_dns_name_count_labels_one("foo.bar.quux", 3);
563 test_dns_name_count_labels_one("foo.bar.", 2);
564 test_dns_name_count_labels_one("foo.bar", 2);
565 test_dns_name_count_labels_one("foo.", 1);
566 test_dns_name_count_labels_one("foo", 1);
567 test_dns_name_count_labels_one("", 0);
568 test_dns_name_count_labels_one(".", 0);
569 test_dns_name_count_labels_one("..", -EINVAL);
570 }
571
572 static void test_dns_name_equal_skip_one(const char *a, unsigned n_labels, const char *b, int ret) {
573 assert_se(dns_name_equal_skip(a, n_labels, b) == ret);
574 }
575
576 static void test_dns_name_equal_skip(void) {
577 test_dns_name_equal_skip_one("foo", 0, "bar", 0);
578 test_dns_name_equal_skip_one("foo", 0, "foo", 1);
579 test_dns_name_equal_skip_one("foo", 1, "foo", 0);
580 test_dns_name_equal_skip_one("foo", 2, "foo", 0);
581
582 test_dns_name_equal_skip_one("foo.bar", 0, "foo.bar", 1);
583 test_dns_name_equal_skip_one("foo.bar", 1, "foo.bar", 0);
584 test_dns_name_equal_skip_one("foo.bar", 2, "foo.bar", 0);
585 test_dns_name_equal_skip_one("foo.bar", 3, "foo.bar", 0);
586
587 test_dns_name_equal_skip_one("foo.bar", 0, "bar", 0);
588 test_dns_name_equal_skip_one("foo.bar", 1, "bar", 1);
589 test_dns_name_equal_skip_one("foo.bar", 2, "bar", 0);
590 test_dns_name_equal_skip_one("foo.bar", 3, "bar", 0);
591
592 test_dns_name_equal_skip_one("foo.bar", 0, "", 0);
593 test_dns_name_equal_skip_one("foo.bar", 1, "", 0);
594 test_dns_name_equal_skip_one("foo.bar", 2, "", 1);
595 test_dns_name_equal_skip_one("foo.bar", 3, "", 0);
596
597 test_dns_name_equal_skip_one("", 0, "", 1);
598 test_dns_name_equal_skip_one("", 1, "", 0);
599 test_dns_name_equal_skip_one("", 1, "foo", 0);
600 test_dns_name_equal_skip_one("", 2, "foo", 0);
601 }
602
603 static void test_dns_name_compare_func(void) {
604 assert_se(dns_name_compare_func("", "") == 0);
605 assert_se(dns_name_compare_func("", ".") == 0);
606 assert_se(dns_name_compare_func(".", "") == 0);
607 assert_se(dns_name_compare_func("foo", "foo.") == 0);
608 assert_se(dns_name_compare_func("foo.", "foo") == 0);
609 assert_se(dns_name_compare_func("foo", "foo") == 0);
610 assert_se(dns_name_compare_func("foo.", "foo.") == 0);
611 assert_se(dns_name_compare_func("heise.de", "HEISE.DE.") == 0);
612
613 assert_se(dns_name_compare_func("de.", "heise.de") != 0);
614 }
615
616 static void test_dns_name_common_suffix_one(const char *a, const char *b, const char *result) {
617 const char *c;
618
619 assert_se(dns_name_common_suffix(a, b, &c) >= 0);
620 assert_se(streq(c, result));
621 }
622
623 static void test_dns_name_common_suffix(void) {
624 test_dns_name_common_suffix_one("", "", "");
625 test_dns_name_common_suffix_one("foo", "", "");
626 test_dns_name_common_suffix_one("", "foo", "");
627 test_dns_name_common_suffix_one("foo", "bar", "");
628 test_dns_name_common_suffix_one("bar", "foo", "");
629 test_dns_name_common_suffix_one("foo", "foo", "foo");
630 test_dns_name_common_suffix_one("quux.foo", "foo", "foo");
631 test_dns_name_common_suffix_one("foo", "quux.foo", "foo");
632 test_dns_name_common_suffix_one("this.is.a.short.sentence", "this.is.another.short.sentence", "short.sentence");
633 test_dns_name_common_suffix_one("FOO.BAR", "tEST.bAR", "BAR");
634 }
635
636 static void test_dns_name_apply_idna_one(const char *s, int expected, const char *result) {
637 _cleanup_free_ char *buf = NULL;
638 int r;
639
640 r = dns_name_apply_idna(s, &buf);
641 log_debug("dns_name_apply_idna: \"%s\" → %d/\"%s\" (expected %d/\"%s\")",
642 s, r, strnull(buf), expected, strnull(result));
643
644 /* Different libidn2 versions are more and less accepting
645 * of underscore-prefixed names. So let's list the lowest
646 * expected return value. */
647 assert_se(r >= expected);
648 if (expected == 1)
649 assert_se(dns_name_equal(buf, result) == 1);
650 }
651
652 static void test_dns_name_apply_idna(void) {
653 #if HAVE_LIBIDN2 || HAVE_LIBIDN
654 const int ret = 1;
655 #else
656 const int ret = 0;
657 #endif
658
659 /* IDNA2008 forbids names with hyphens in third and fourth positions
660 * (https://tools.ietf.org/html/rfc5891#section-4.2.3.1).
661 * IDNA2003 does not have this restriction
662 * (https://tools.ietf.org/html/rfc3490#section-5).
663 * This means that when using libidn we will transform and test more
664 * labels. If registrars follow IDNA2008 we'll just be performing a
665 * useless lookup.
666 */
667 #if HAVE_LIBIDN
668 const int ret2 = 1;
669 #else
670 const int ret2 = 0;
671 #endif
672
673 test_dns_name_apply_idna_one("", ret, "");
674 test_dns_name_apply_idna_one("foo", ret, "foo");
675 test_dns_name_apply_idna_one("foo.", ret, "foo");
676 test_dns_name_apply_idna_one("foo.bar", ret, "foo.bar");
677 test_dns_name_apply_idna_one("foo.bar.", ret, "foo.bar");
678 test_dns_name_apply_idna_one("föö", ret, "xn--f-1gaa");
679 test_dns_name_apply_idna_one("föö.", ret, "xn--f-1gaa");
680 test_dns_name_apply_idna_one("föö.bär", ret, "xn--f-1gaa.xn--br-via");
681 test_dns_name_apply_idna_one("föö.bär.", ret, "xn--f-1gaa.xn--br-via");
682 test_dns_name_apply_idna_one("xn--f-1gaa.xn--br-via", ret, "xn--f-1gaa.xn--br-via");
683
684 test_dns_name_apply_idna_one("_443._tcp.fedoraproject.org", ret2,
685 "_443._tcp.fedoraproject.org");
686 test_dns_name_apply_idna_one("_443", ret2, "_443");
687 test_dns_name_apply_idna_one("gateway", ret, "gateway");
688 test_dns_name_apply_idna_one("_gateway", ret2, "_gateway");
689
690 test_dns_name_apply_idna_one("r3---sn-ab5l6ne7.googlevideo.com", ret2,
691 ret2 ? "r3---sn-ab5l6ne7.googlevideo.com" : "");
692 }
693
694 static void test_dns_name_is_valid_or_address(void) {
695 assert_se(dns_name_is_valid_or_address(NULL) == 0);
696 assert_se(dns_name_is_valid_or_address("") == 0);
697 assert_se(dns_name_is_valid_or_address("foobar") > 0);
698 assert_se(dns_name_is_valid_or_address("foobar.com") > 0);
699 assert_se(dns_name_is_valid_or_address("foobar..com") == 0);
700 assert_se(dns_name_is_valid_or_address("foobar.com.") > 0);
701 assert_se(dns_name_is_valid_or_address("127.0.0.1") > 0);
702 assert_se(dns_name_is_valid_or_address("::") > 0);
703 assert_se(dns_name_is_valid_or_address("::1") > 0);
704 }
705
706 int main(int argc, char *argv[]) {
707 log_set_max_level(LOG_DEBUG);
708 log_parse_environment();
709 log_open();
710
711 test_dns_label_unescape();
712 test_dns_label_unescape_suffix();
713 test_dns_label_escape();
714 test_dns_name_normalize();
715 test_dns_name_equal();
716 test_dns_name_endswith();
717 test_dns_name_startswith();
718 test_dns_name_between();
719 test_dns_name_is_root();
720 test_dns_name_is_single_label();
721 test_dns_name_reverse();
722 test_dns_name_concat();
723 test_dns_name_is_valid();
724 test_dns_name_to_wire_format();
725 test_dns_service_name_is_valid();
726 test_dns_srv_type_is_valid();
727 test_dnssd_srv_type_is_valid();
728 test_dns_service_join();
729 test_dns_service_split();
730 test_dns_name_change_suffix();
731 test_dns_name_suffix();
732 test_dns_name_count_labels();
733 test_dns_name_equal_skip();
734 test_dns_name_compare_func();
735 test_dns_name_common_suffix();
736 test_dns_name_apply_idna();
737 test_dns_name_is_valid_or_address();
738
739 return 0;
740 }