]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-dns-domain.c
Merge pull request #7618 from tiagosh/sysctl_use_read_line
[thirdparty/systemd.git] / src / test / test-dns-domain.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
74b2466e
LP
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
b5efdb8a 21#include "alloc-util.h"
4ad7f276 22#include "dns-domain.h"
07630cea
LP
23#include "macro.h"
24#include "string-util.h"
74b2466e
LP
25
26static 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
39static void test_dns_label_unescape(void) {
40 test_dns_label_unescape_one("hallo", "hallo", 6, 5);
37ade128 41 test_dns_label_unescape_one("hallo", "hallo", 4, -ENOBUFS);
74b2466e
LP
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);
f35c467d 52 test_dns_label_unescape_one("foobar..", "foobar", 20, -EINVAL);
74b2466e
LP
53}
54
54adabf7
BG
55static 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
3cd03457 59 r = dns_name_to_wire_format(what, buffer, buffer_sz, false);
54adabf7
BG
60 assert_se(r == ret);
61
62 if (r < 0)
63 return;
64
65 assert_se(!memcmp(buffer, expect, r));
66}
67
68static void test_dns_name_to_wire_format(void) {
50dee79b
LP
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 };
54adabf7 99
c6cefd13 100 test_dns_name_to_wire_format_one("", out0, sizeof(out0), sizeof(out0));
54adabf7
BG
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));
50dee79b
LP
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));
54adabf7
BG
113}
114
642900d3
TG
115static 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
133static void test_dns_label_unescape_suffix(void) {
134 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 6, 5, 0);
37ade128 135 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOBUFS, -ENOBUFS);
642900d3
TG
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);
56512859 143 test_dns_label_unescape_suffix_one("..", "", "", 20, 0, -EINVAL);
642900d3 144 test_dns_label_unescape_suffix_one(".foobar", "foobar", "", 20, 6, -EINVAL);
56512859 145 test_dns_label_unescape_suffix_one("foobar.", "foobar", "", 20, 6, 0);
642900d3
TG
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
74b2466e
LP
155static 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
422baca0 159 r = dns_label_escape_new(what, l, &t);
0c0cdb06 160 assert_se(r == ret);
74b2466e
LP
161
162 if (r < 0)
163 return;
164
165 assert_se(streq_ptr(expect, t));
166}
167
168static void test_dns_label_escape(void) {
3b37fa73 169 test_dns_label_escape_one("", 0, NULL, -EINVAL);
74b2466e 170 test_dns_label_escape_one("hallo", 5, "hallo", 5);
c7feab76 171 test_dns_label_escape_one("hallo", 6, "hallo\\000", 9);
74b2466e
LP
172 test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
173}
174
175static 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
188static void test_dns_name_normalize(void) {
3a519900 189 test_dns_name_normalize_one("", ".", 0);
74b2466e
LP
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);
c7feab76 193 test_dns_name_normalize_one("\\000", "\\000", 0);
74b2466e
LP
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);
3a519900 197 test_dns_name_normalize_one(".", ".", 0);
74b2466e
LP
198}
199
200static 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
210static 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);
c7feab76 219 test_dns_name_equal_one("\\000", "\\000", true);
74b2466e
LP
220 test_dns_name_equal_one(".", "", true);
221 test_dns_name_equal_one(".", ".", true);
222 test_dns_name_equal_one("..", "..", -EINVAL);
223}
224
ae72b22c
TG
225static 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);
234 else
235 assert_se(r == ret);
236}
237
238static 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", -EINVAL);
253 test_dns_name_between_one("example", "example", "yljkjljk.a.example", false);
254 test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false);
255}
256
74b2466e
LP
257static void test_dns_name_endswith_one(const char *a, const char *b, int ret) {
258 assert_se(dns_name_endswith(a, b) == ret);
259}
260
261static void test_dns_name_endswith(void) {
262 test_dns_name_endswith_one("", "", true);
263 test_dns_name_endswith_one("", "xxx", false);
264 test_dns_name_endswith_one("xxx", "", true);
265 test_dns_name_endswith_one("x", "x", true);
266 test_dns_name_endswith_one("x", "y", false);
267 test_dns_name_endswith_one("x.y", "y", true);
268 test_dns_name_endswith_one("x.y", "Y", true);
269 test_dns_name_endswith_one("x.y", "x", false);
270 test_dns_name_endswith_one("x.y.z", "Z", true);
271 test_dns_name_endswith_one("x.y.z", "y.Z", true);
272 test_dns_name_endswith_one("x.y.z", "x.y.Z", true);
273 test_dns_name_endswith_one("x.y.z", "waldo", false);
274 test_dns_name_endswith_one("x.y.z.u.v.w", "y.z", false);
275 test_dns_name_endswith_one("x.y.z.u.v.w", "u.v.w", true);
276 test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL);
277}
278
eb241cdb
LP
279static void test_dns_name_startswith_one(const char *a, const char *b, int ret) {
280 assert_se(dns_name_startswith(a, b) == ret);
281}
282
283static void test_dns_name_startswith(void) {
284 test_dns_name_startswith_one("", "", true);
285 test_dns_name_startswith_one("", "xxx", false);
286 test_dns_name_startswith_one("xxx", "", true);
287 test_dns_name_startswith_one("x", "x", true);
288 test_dns_name_startswith_one("x", "y", false);
289 test_dns_name_startswith_one("x.y", "x.y", true);
290 test_dns_name_startswith_one("x.y", "y.x", false);
291 test_dns_name_startswith_one("x.y", "x", true);
292 test_dns_name_startswith_one("x.y", "X", true);
293 test_dns_name_startswith_one("x.y", "y", false);
294 test_dns_name_startswith_one("x.y", "", true);
295 test_dns_name_startswith_one("x.y", "X", true);
296}
297
dc477e73
LP
298static void test_dns_name_is_root(void) {
299 assert_se(dns_name_is_root(""));
300 assert_se(dns_name_is_root("."));
301 assert_se(!dns_name_is_root("xxx"));
302 assert_se(!dns_name_is_root("xxx."));
303 assert_se(!dns_name_is_root(".."));
74b2466e
LP
304}
305
dc477e73
LP
306static void test_dns_name_is_single_label(void) {
307 assert_se(!dns_name_is_single_label(""));
308 assert_se(!dns_name_is_single_label("."));
309 assert_se(!dns_name_is_single_label(".."));
310 assert_se(dns_name_is_single_label("x"));
311 assert_se(dns_name_is_single_label("x."));
312 assert_se(!dns_name_is_single_label("xx.yy"));
74b2466e
LP
313}
314
b914e211
LP
315static void test_dns_name_reverse_one(const char *address, const char *name) {
316 _cleanup_free_ char *p = NULL;
a7f7d1bd 317 union in_addr_union a, b = {};
b914e211
LP
318 int familya, familyb;
319
320 assert_se(in_addr_from_string_auto(address, &familya, &a) >= 0);
321 assert_se(dns_name_reverse(familya, &a, &p) >= 0);
322 assert_se(streq(p, name));
323 assert_se(dns_name_address(p, &familyb, &b) > 0);
324 assert_se(familya == familyb);
325 assert_se(in_addr_equal(familya, &a, &b));
326}
327
328static void test_dns_name_reverse(void) {
329 test_dns_name_reverse_one("47.11.8.15", "15.8.11.47.in-addr.arpa");
330 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");
9436e8ca
LP
331 test_dns_name_reverse_one("127.0.0.1", "1.0.0.127.in-addr.arpa");
332 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");
b914e211
LP
333}
334
9ca45586
LP
335static void test_dns_name_concat_one(const char *a, const char *b, int r, const char *result) {
336 _cleanup_free_ char *p = NULL;
337
338 assert_se(dns_name_concat(a, b, &p) == r);
339 assert_se(streq_ptr(p, result));
340}
341
342static void test_dns_name_concat(void) {
3a519900
LP
343 test_dns_name_concat_one("", "", 0, ".");
344 test_dns_name_concat_one(".", "", 0, ".");
345 test_dns_name_concat_one("", ".", 0, ".");
346 test_dns_name_concat_one(".", ".", 0, ".");
9ca45586
LP
347 test_dns_name_concat_one("foo", "bar", 0, "foo.bar");
348 test_dns_name_concat_one("foo.foo", "bar.bar", 0, "foo.foo.bar.bar");
349 test_dns_name_concat_one("foo", NULL, 0, "foo");
3a519900 350 test_dns_name_concat_one("foo", ".", 0, "foo");
9ca45586 351 test_dns_name_concat_one("foo.", "bar.", 0, "foo.bar");
3a519900
LP
352 test_dns_name_concat_one(NULL, NULL, 0, ".");
353 test_dns_name_concat_one(NULL, ".", 0, ".");
354 test_dns_name_concat_one(NULL, "foo", 0, "foo");
9ca45586
LP
355}
356
357static void test_dns_name_is_valid_one(const char *s, int ret) {
358 assert_se(dns_name_is_valid(s) == ret);
359}
360
361static void test_dns_name_is_valid(void) {
362 test_dns_name_is_valid_one("foo", 1);
363 test_dns_name_is_valid_one("foo.", 1);
f35c467d 364 test_dns_name_is_valid_one("foo..", 0);
9ca45586
LP
365 test_dns_name_is_valid_one("Foo", 1);
366 test_dns_name_is_valid_one("foo.bar", 1);
367 test_dns_name_is_valid_one("foo.bar.baz", 1);
368 test_dns_name_is_valid_one("", 1);
369 test_dns_name_is_valid_one("foo..bar", 0);
370 test_dns_name_is_valid_one(".foo.bar", 0);
371 test_dns_name_is_valid_one("foo.bar.", 1);
f35c467d 372 test_dns_name_is_valid_one("foo.bar..", 0);
9ca45586
LP
373 test_dns_name_is_valid_one("\\zbar", 0);
374 test_dns_name_is_valid_one("ä", 1);
375 test_dns_name_is_valid_one("\n", 0);
1dfbf000 376
13e785f7 377 /* 256 characters */
1dfbf000
LP
378 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);
379
13e785f7 380 /* 255 characters */
1dfbf000
LP
381 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);
382
13e785f7 383 /* 254 characters */
1dfbf000
LP
384 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);
385
13e785f7 386 /* 253 characters */
1dfbf000
LP
387 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);
388
389 /* label of 64 chars length */
390 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a123", 0);
391
392 /* label of 63 chars length */
393 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a12", 1);
9ca45586
LP
394}
395
0a49b6b6
LP
396static void test_dns_service_name_is_valid(void) {
397 assert_se(dns_service_name_is_valid("Lennart's Compüter"));
398 assert_se(dns_service_name_is_valid("piff.paff"));
399
400 assert_se(!dns_service_name_is_valid(NULL));
401 assert_se(!dns_service_name_is_valid(""));
402 assert_se(!dns_service_name_is_valid("foo\nbar"));
403 assert_se(!dns_service_name_is_valid("foo\201bar"));
404 assert_se(!dns_service_name_is_valid("this is an overly long string that is certainly longer than 63 characters"));
405}
406
7e8131e9
LP
407static void test_dns_srv_type_is_valid(void) {
408
409 assert_se(dns_srv_type_is_valid("_http._tcp"));
410 assert_se(dns_srv_type_is_valid("_foo-bar._tcp"));
411 assert_se(dns_srv_type_is_valid("_w._udp"));
412 assert_se(dns_srv_type_is_valid("_a800._tcp"));
413 assert_se(dns_srv_type_is_valid("_a-800._tcp"));
414
415 assert_se(!dns_srv_type_is_valid(NULL));
416 assert_se(!dns_srv_type_is_valid(""));
417 assert_se(!dns_srv_type_is_valid("x"));
418 assert_se(!dns_srv_type_is_valid("_foo"));
419 assert_se(!dns_srv_type_is_valid("_tcp"));
420 assert_se(!dns_srv_type_is_valid("_"));
421 assert_se(!dns_srv_type_is_valid("_foo."));
422 assert_se(!dns_srv_type_is_valid("_föo._tcp"));
423 assert_se(!dns_srv_type_is_valid("_f\no._tcp"));
424 assert_se(!dns_srv_type_is_valid("_800._tcp"));
425 assert_se(!dns_srv_type_is_valid("_-800._tcp"));
426 assert_se(!dns_srv_type_is_valid("_-foo._tcp"));
427 assert_se(!dns_srv_type_is_valid("_piep._foo._udp"));
0e8eedbb
LP
428}
429
154ae087
DR
430static void test_dnssd_srv_type_is_valid(void) {
431
432 assert_se(dnssd_srv_type_is_valid("_http._tcp"));
433 assert_se(dnssd_srv_type_is_valid("_foo-bar._tcp"));
434 assert_se(dnssd_srv_type_is_valid("_w._udp"));
435 assert_se(dnssd_srv_type_is_valid("_a800._tcp"));
436 assert_se(dnssd_srv_type_is_valid("_a-800._tcp"));
437
438 assert_se(!dnssd_srv_type_is_valid(NULL));
439 assert_se(!dnssd_srv_type_is_valid(""));
440 assert_se(!dnssd_srv_type_is_valid("x"));
441 assert_se(!dnssd_srv_type_is_valid("_foo"));
442 assert_se(!dnssd_srv_type_is_valid("_tcp"));
443 assert_se(!dnssd_srv_type_is_valid("_"));
444 assert_se(!dnssd_srv_type_is_valid("_foo."));
445 assert_se(!dnssd_srv_type_is_valid("_föo._tcp"));
446 assert_se(!dnssd_srv_type_is_valid("_f\no._tcp"));
447 assert_se(!dnssd_srv_type_is_valid("_800._tcp"));
448 assert_se(!dnssd_srv_type_is_valid("_-800._tcp"));
449 assert_se(!dnssd_srv_type_is_valid("_-foo._tcp"));
450 assert_se(!dnssd_srv_type_is_valid("_piep._foo._udp"));
451 assert_se(!dnssd_srv_type_is_valid("_foo._unknown"));
452}
453
0e8eedbb
LP
454static void test_dns_service_join_one(const char *a, const char *b, const char *c, int r, const char *d) {
455 _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *t = NULL;
456
457 assert_se(dns_service_join(a, b, c, &t) == r);
458 assert_se(streq_ptr(t, d));
459
460 if (r < 0)
461 return;
462
463 assert_se(dns_service_split(t, &x, &y, &z) >= 0);
464 assert_se(streq_ptr(a, x));
465 assert_se(streq_ptr(b, y));
3a519900 466 assert_se(dns_name_equal(c, z) > 0);
0e8eedbb
LP
467}
468
469static void test_dns_service_join(void) {
470 test_dns_service_join_one("", "", "", -EINVAL, NULL);
471 test_dns_service_join_one("", "_http._tcp", "", -EINVAL, NULL);
472 test_dns_service_join_one("", "_http._tcp", "foo", -EINVAL, NULL);
473 test_dns_service_join_one("foo", "", "foo", -EINVAL, NULL);
474 test_dns_service_join_one("foo", "foo", "foo", -EINVAL, NULL);
475
476 test_dns_service_join_one("foo", "_http._tcp", "", 0, "foo._http._tcp");
477 test_dns_service_join_one(NULL, "_http._tcp", "", 0, "_http._tcp");
478 test_dns_service_join_one("foo", "_http._tcp", "foo", 0, "foo._http._tcp.foo");
479 test_dns_service_join_one(NULL, "_http._tcp", "foo", 0, "_http._tcp.foo");
480 test_dns_service_join_one("Lennart's PC", "_pc._tcp", "foo.bar.com", 0, "Lennart\\039s\\032PC._pc._tcp.foo.bar.com");
481 test_dns_service_join_one(NULL, "_pc._tcp", "foo.bar.com", 0, "_pc._tcp.foo.bar.com");
482}
483
484static void test_dns_service_split_one(const char *joined, const char *a, const char *b, const char *c, int r) {
485 _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *t = NULL;
486
487 assert_se(dns_service_split(joined, &x, &y, &z) == r);
488 assert_se(streq_ptr(x, a));
489 assert_se(streq_ptr(y, b));
490 assert_se(streq_ptr(z, c));
491
492 if (r < 0)
493 return;
494
495 if (y) {
496 assert_se(dns_service_join(x, y, z, &t) == 0);
3a519900 497 assert_se(dns_name_equal(joined, t) > 0);
0e8eedbb 498 } else
3a519900 499 assert_se(!x && dns_name_equal(z, joined) > 0);
0e8eedbb
LP
500}
501
502static void test_dns_service_split(void) {
3a519900 503 test_dns_service_split_one("", NULL, NULL, ".", 0);
0e8eedbb
LP
504 test_dns_service_split_one("foo", NULL, NULL, "foo", 0);
505 test_dns_service_split_one("foo.bar", NULL, NULL, "foo.bar", 0);
506 test_dns_service_split_one("_foo.bar", NULL, NULL, "_foo.bar", 0);
3a519900
LP
507 test_dns_service_split_one("_foo._bar", NULL, "_foo._bar", ".", 0);
508 test_dns_service_split_one("_meh._foo._bar", "_meh", "_foo._bar", ".", 0);
0e8eedbb 509 test_dns_service_split_one("Wuff\\032Wuff._foo._bar.waldo.com", "Wuff Wuff", "_foo._bar", "waldo.com", 0);
0a49b6b6
LP
510}
511
58db254a
LP
512static void test_dns_name_change_suffix_one(const char *name, const char *old_suffix, const char *new_suffix, int r, const char *result) {
513 _cleanup_free_ char *s = NULL;
514
515 assert_se(dns_name_change_suffix(name, old_suffix, new_suffix, &s) == r);
516 assert_se(streq_ptr(s, result));
517}
518
519static void test_dns_name_change_suffix(void) {
520 test_dns_name_change_suffix_one("foo.bar", "bar", "waldo", 1, "foo.waldo");
521 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "foo.bar.waldi.quux", "piff.paff", 1, "piff.paff");
522 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "bar.waldi.quux", "piff.paff", 1, "foo.piff.paff");
523 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "waldi.quux", "piff.paff", 1, "foo.bar.piff.paff");
524 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "quux", "piff.paff", 1, "foo.bar.waldi.piff.paff");
525 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "", "piff.paff", 1, "foo.bar.waldi.quux.piff.paff");
526 test_dns_name_change_suffix_one("", "", "piff.paff", 1, "piff.paff");
3a519900 527 test_dns_name_change_suffix_one("", "", "", 1, ".");
58db254a
LP
528 test_dns_name_change_suffix_one("a", "b", "c", 0, NULL);
529}
530
e7ff0e0b
LP
531static void test_dns_name_suffix_one(const char *name, unsigned n_labels, const char *result, int ret) {
532 const char *p = NULL;
533
534 assert_se(ret == dns_name_suffix(name, n_labels, &p));
535 assert_se(streq_ptr(p, result));
536}
537
538static void test_dns_name_suffix(void) {
539 test_dns_name_suffix_one("foo.bar", 2, "foo.bar", 0);
540 test_dns_name_suffix_one("foo.bar", 1, "bar", 1);
541 test_dns_name_suffix_one("foo.bar", 0, "", 2);
542 test_dns_name_suffix_one("foo.bar", 3, NULL, -EINVAL);
543 test_dns_name_suffix_one("foo.bar", 4, NULL, -EINVAL);
544
545 test_dns_name_suffix_one("bar", 1, "bar", 0);
546 test_dns_name_suffix_one("bar", 0, "", 1);
547 test_dns_name_suffix_one("bar", 2, NULL, -EINVAL);
548 test_dns_name_suffix_one("bar", 3, NULL, -EINVAL);
549
550 test_dns_name_suffix_one("", 0, "", 0);
551 test_dns_name_suffix_one("", 1, NULL, -EINVAL);
552 test_dns_name_suffix_one("", 2, NULL, -EINVAL);
553}
554
555static void test_dns_name_count_labels_one(const char *name, int n) {
556 assert_se(dns_name_count_labels(name) == n);
557}
558
559static void test_dns_name_count_labels(void) {
560 test_dns_name_count_labels_one("foo.bar.quux.", 3);
561 test_dns_name_count_labels_one("foo.bar.quux", 3);
562 test_dns_name_count_labels_one("foo.bar.", 2);
563 test_dns_name_count_labels_one("foo.bar", 2);
564 test_dns_name_count_labels_one("foo.", 1);
565 test_dns_name_count_labels_one("foo", 1);
566 test_dns_name_count_labels_one("", 0);
567 test_dns_name_count_labels_one(".", 0);
568 test_dns_name_count_labels_one("..", -EINVAL);
569}
570
db5b0e92
LP
571static void test_dns_name_equal_skip_one(const char *a, unsigned n_labels, const char *b, int ret) {
572 assert_se(dns_name_equal_skip(a, n_labels, b) == ret);
573}
574
575static void test_dns_name_equal_skip(void) {
576 test_dns_name_equal_skip_one("foo", 0, "bar", 0);
577 test_dns_name_equal_skip_one("foo", 0, "foo", 1);
578 test_dns_name_equal_skip_one("foo", 1, "foo", 0);
579 test_dns_name_equal_skip_one("foo", 2, "foo", 0);
580
581 test_dns_name_equal_skip_one("foo.bar", 0, "foo.bar", 1);
582 test_dns_name_equal_skip_one("foo.bar", 1, "foo.bar", 0);
583 test_dns_name_equal_skip_one("foo.bar", 2, "foo.bar", 0);
584 test_dns_name_equal_skip_one("foo.bar", 3, "foo.bar", 0);
585
586 test_dns_name_equal_skip_one("foo.bar", 0, "bar", 0);
587 test_dns_name_equal_skip_one("foo.bar", 1, "bar", 1);
588 test_dns_name_equal_skip_one("foo.bar", 2, "bar", 0);
589 test_dns_name_equal_skip_one("foo.bar", 3, "bar", 0);
590
591 test_dns_name_equal_skip_one("foo.bar", 0, "", 0);
592 test_dns_name_equal_skip_one("foo.bar", 1, "", 0);
593 test_dns_name_equal_skip_one("foo.bar", 2, "", 1);
594 test_dns_name_equal_skip_one("foo.bar", 3, "", 0);
595
596 test_dns_name_equal_skip_one("", 0, "", 1);
597 test_dns_name_equal_skip_one("", 1, "", 0);
598 test_dns_name_equal_skip_one("", 1, "foo", 0);
599 test_dns_name_equal_skip_one("", 2, "foo", 0);
600}
601
56512859
LP
602static void test_dns_name_compare_func(void) {
603 assert_se(dns_name_compare_func("", "") == 0);
604 assert_se(dns_name_compare_func("", ".") == 0);
605 assert_se(dns_name_compare_func(".", "") == 0);
606 assert_se(dns_name_compare_func("foo", "foo.") == 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("heise.de", "HEISE.DE.") == 0);
611
612 assert_se(dns_name_compare_func("de.", "heise.de") != 0);
613}
614
b9282bc1
LP
615static void test_dns_name_common_suffix_one(const char *a, const char *b, const char *result) {
616 const char *c;
617
618 assert_se(dns_name_common_suffix(a, b, &c) >= 0);
619 assert_se(streq(c, result));
620}
621
622static void test_dns_name_common_suffix(void) {
623 test_dns_name_common_suffix_one("", "", "");
624 test_dns_name_common_suffix_one("foo", "", "");
625 test_dns_name_common_suffix_one("", "foo", "");
626 test_dns_name_common_suffix_one("foo", "bar", "");
627 test_dns_name_common_suffix_one("bar", "foo", "");
628 test_dns_name_common_suffix_one("foo", "foo", "foo");
629 test_dns_name_common_suffix_one("quux.foo", "foo", "foo");
630 test_dns_name_common_suffix_one("foo", "quux.foo", "foo");
631 test_dns_name_common_suffix_one("this.is.a.short.sentence", "this.is.another.short.sentence", "short.sentence");
632 test_dns_name_common_suffix_one("FOO.BAR", "tEST.bAR", "BAR");
633}
634
ad1f3fe6 635static void test_dns_name_apply_idna_one(const char *s, int expected, const char *result) {
0cf40f55 636 _cleanup_free_ char *buf = NULL;
ad1f3fe6
ZJS
637 int r;
638
639 r = dns_name_apply_idna(s, &buf);
640 log_debug("dns_name_apply_idna: \"%s\" → %d/\"%s\" (expected %d/\"%s\")",
641 s, r, strnull(buf), expected, strnull(result));
642
0fe36dd9
ZJS
643 /* Different libidn2 versions are more and less accepting
644 * of underscore-prefixed names. So let's list the lowest
645 * expected return value. */
646 assert_se(r >= expected);
ad1f3fe6
ZJS
647 if (expected == 1)
648 assert_se(dns_name_equal(buf, result) == 1);
0cf40f55
LP
649}
650
651static void test_dns_name_apply_idna(void) {
349cc4a5 652#if HAVE_LIBIDN2 || HAVE_LIBIDN
ad1f3fe6
ZJS
653 const int ret = 1;
654#else
655 const int ret = 0;
656#endif
657
658 /* IDNA2008 forbids names with hyphens in third and fourth positions
659 * (https://tools.ietf.org/html/rfc5891#section-4.2.3.1).
660 * IDNA2003 does not have this restriction
661 * (https://tools.ietf.org/html/rfc3490#section-5).
662 * This means that when using libidn we will transform and test more
663 * labels. If registrars follow IDNA2008 we'll just be performing a
664 * useless lookup.
665 */
349cc4a5 666#if HAVE_LIBIDN
ad1f3fe6
ZJS
667 const int ret2 = 1;
668#else
669 const int ret2 = 0;
670#endif
671
672 test_dns_name_apply_idna_one("", ret, "");
673 test_dns_name_apply_idna_one("foo", ret, "foo");
674 test_dns_name_apply_idna_one("foo.", ret, "foo");
675 test_dns_name_apply_idna_one("foo.bar", ret, "foo.bar");
676 test_dns_name_apply_idna_one("foo.bar.", ret, "foo.bar");
677 test_dns_name_apply_idna_one("föö", ret, "xn--f-1gaa");
678 test_dns_name_apply_idna_one("föö.", ret, "xn--f-1gaa");
679 test_dns_name_apply_idna_one("föö.bär", ret, "xn--f-1gaa.xn--br-via");
680 test_dns_name_apply_idna_one("föö.bär.", ret, "xn--f-1gaa.xn--br-via");
681 test_dns_name_apply_idna_one("xn--f-1gaa.xn--br-via", ret, "xn--f-1gaa.xn--br-via");
682
0926f348
ZJS
683 test_dns_name_apply_idna_one("_443._tcp.fedoraproject.org", ret2,
684 "_443._tcp.fedoraproject.org");
685 test_dns_name_apply_idna_one("_443", ret2, "_443");
686 test_dns_name_apply_idna_one("gateway", ret, "gateway");
687 test_dns_name_apply_idna_one("_gateway", ret2, "_gateway");
688
ad1f3fe6
ZJS
689 test_dns_name_apply_idna_one("r3---sn-ab5l6ne7.googlevideo.com", ret2,
690 ret2 ? "r3---sn-ab5l6ne7.googlevideo.com" : "");
0cf40f55
LP
691}
692
08a4849e
LP
693static void test_dns_name_is_valid_or_address(void) {
694 assert_se(dns_name_is_valid_or_address(NULL) == 0);
695 assert_se(dns_name_is_valid_or_address("") == 0);
696 assert_se(dns_name_is_valid_or_address("foobar") > 0);
697 assert_se(dns_name_is_valid_or_address("foobar.com") > 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("127.0.0.1") > 0);
701 assert_se(dns_name_is_valid_or_address("::") > 0);
702 assert_se(dns_name_is_valid_or_address("::1") > 0);
703}
704
74b2466e 705int main(int argc, char *argv[]) {
ad1f3fe6
ZJS
706 log_set_max_level(LOG_DEBUG);
707 log_parse_environment();
708 log_open();
74b2466e
LP
709
710 test_dns_label_unescape();
642900d3 711 test_dns_label_unescape_suffix();
74b2466e
LP
712 test_dns_label_escape();
713 test_dns_name_normalize();
714 test_dns_name_equal();
715 test_dns_name_endswith();
eb241cdb 716 test_dns_name_startswith();
ae72b22c 717 test_dns_name_between();
dc477e73
LP
718 test_dns_name_is_root();
719 test_dns_name_is_single_label();
b914e211 720 test_dns_name_reverse();
9ca45586
LP
721 test_dns_name_concat();
722 test_dns_name_is_valid();
54adabf7 723 test_dns_name_to_wire_format();
0a49b6b6 724 test_dns_service_name_is_valid();
7e8131e9 725 test_dns_srv_type_is_valid();
154ae087 726 test_dnssd_srv_type_is_valid();
0e8eedbb
LP
727 test_dns_service_join();
728 test_dns_service_split();
58db254a 729 test_dns_name_change_suffix();
e7ff0e0b
LP
730 test_dns_name_suffix();
731 test_dns_name_count_labels();
db5b0e92 732 test_dns_name_equal_skip();
56512859 733 test_dns_name_compare_func();
b9282bc1 734 test_dns_name_common_suffix();
0cf40f55 735 test_dns_name_apply_idna();
08a4849e 736 test_dns_name_is_valid_or_address();
74b2466e
LP
737
738 return 0;
739}