]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-dns-domain.c
dhcp: make host/domain name validity checks stricter
[thirdparty/systemd.git] / src / test / test-dns-domain.c
CommitLineData
74b2466e
LP
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
b5efdb8a 22#include "alloc-util.h"
4ad7f276 23#include "dns-domain.h"
07630cea
LP
24#include "macro.h"
25#include "string-util.h"
74b2466e
LP
26
27static void test_dns_label_unescape_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
28 char buffer[buffer_sz];
29 int r;
30
31 r = dns_label_unescape(&what, buffer, buffer_sz);
32 assert_se(r == ret);
33
34 if (r < 0)
35 return;
36
37 assert_se(streq(buffer, expect));
38}
39
40static void test_dns_label_unescape(void) {
41 test_dns_label_unescape_one("hallo", "hallo", 6, 5);
37ade128 42 test_dns_label_unescape_one("hallo", "hallo", 4, -ENOBUFS);
74b2466e
LP
43 test_dns_label_unescape_one("", "", 10, 0);
44 test_dns_label_unescape_one("hallo\\.foobar", "hallo.foobar", 20, 12);
45 test_dns_label_unescape_one("hallo.foobar", "hallo", 10, 5);
46 test_dns_label_unescape_one("hallo\n.foobar", "hallo", 20, -EINVAL);
47 test_dns_label_unescape_one("hallo\\", "hallo", 20, -EINVAL);
48 test_dns_label_unescape_one("hallo\\032 ", "hallo ", 20, 7);
49 test_dns_label_unescape_one(".", "", 20, 0);
50 test_dns_label_unescape_one("..", "", 20, -EINVAL);
51 test_dns_label_unescape_one(".foobar", "", 20, -EINVAL);
52 test_dns_label_unescape_one("foobar.", "foobar", 20, 6);
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) {
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);
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);
197 test_dns_name_normalize_one(".", "", 0);
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) {
343 test_dns_name_concat_one("foo", "bar", 0, "foo.bar");
344 test_dns_name_concat_one("foo.foo", "bar.bar", 0, "foo.foo.bar.bar");
345 test_dns_name_concat_one("foo", NULL, 0, "foo");
346 test_dns_name_concat_one("foo.", "bar.", 0, "foo.bar");
347}
348
349static void test_dns_name_is_valid_one(const char *s, int ret) {
350 assert_se(dns_name_is_valid(s) == ret);
351}
352
353static void test_dns_name_is_valid(void) {
354 test_dns_name_is_valid_one("foo", 1);
355 test_dns_name_is_valid_one("foo.", 1);
356 test_dns_name_is_valid_one("Foo", 1);
357 test_dns_name_is_valid_one("foo.bar", 1);
358 test_dns_name_is_valid_one("foo.bar.baz", 1);
359 test_dns_name_is_valid_one("", 1);
360 test_dns_name_is_valid_one("foo..bar", 0);
361 test_dns_name_is_valid_one(".foo.bar", 0);
362 test_dns_name_is_valid_one("foo.bar.", 1);
363 test_dns_name_is_valid_one("\\zbar", 0);
364 test_dns_name_is_valid_one("ä", 1);
365 test_dns_name_is_valid_one("\n", 0);
1dfbf000
LP
366
367 /* 256 characters*/
368 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);
369
370 /* 255 characters*/
371 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);
372
373 /* 254 characters*/
374 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);
375
376 /* 253 characters*/
377 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);
378
379 /* label of 64 chars length */
380 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a123", 0);
381
382 /* label of 63 chars length */
383 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a12", 1);
9ca45586
LP
384}
385
0a49b6b6
LP
386static void test_dns_service_name_is_valid(void) {
387 assert_se(dns_service_name_is_valid("Lennart's Compüter"));
388 assert_se(dns_service_name_is_valid("piff.paff"));
389
390 assert_se(!dns_service_name_is_valid(NULL));
391 assert_se(!dns_service_name_is_valid(""));
392 assert_se(!dns_service_name_is_valid("foo\nbar"));
393 assert_se(!dns_service_name_is_valid("foo\201bar"));
394 assert_se(!dns_service_name_is_valid("this is an overly long string that is certainly longer than 63 characters"));
395}
396
7e8131e9
LP
397static void test_dns_srv_type_is_valid(void) {
398
399 assert_se(dns_srv_type_is_valid("_http._tcp"));
400 assert_se(dns_srv_type_is_valid("_foo-bar._tcp"));
401 assert_se(dns_srv_type_is_valid("_w._udp"));
402 assert_se(dns_srv_type_is_valid("_a800._tcp"));
403 assert_se(dns_srv_type_is_valid("_a-800._tcp"));
404
405 assert_se(!dns_srv_type_is_valid(NULL));
406 assert_se(!dns_srv_type_is_valid(""));
407 assert_se(!dns_srv_type_is_valid("x"));
408 assert_se(!dns_srv_type_is_valid("_foo"));
409 assert_se(!dns_srv_type_is_valid("_tcp"));
410 assert_se(!dns_srv_type_is_valid("_"));
411 assert_se(!dns_srv_type_is_valid("_foo."));
412 assert_se(!dns_srv_type_is_valid("_föo._tcp"));
413 assert_se(!dns_srv_type_is_valid("_f\no._tcp"));
414 assert_se(!dns_srv_type_is_valid("_800._tcp"));
415 assert_se(!dns_srv_type_is_valid("_-800._tcp"));
416 assert_se(!dns_srv_type_is_valid("_-foo._tcp"));
417 assert_se(!dns_srv_type_is_valid("_piep._foo._udp"));
0e8eedbb
LP
418}
419
420static void test_dns_service_join_one(const char *a, const char *b, const char *c, int r, const char *d) {
421 _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *t = NULL;
422
423 assert_se(dns_service_join(a, b, c, &t) == r);
424 assert_se(streq_ptr(t, d));
425
426 if (r < 0)
427 return;
428
429 assert_se(dns_service_split(t, &x, &y, &z) >= 0);
430 assert_se(streq_ptr(a, x));
431 assert_se(streq_ptr(b, y));
432 assert_se(streq_ptr(c, z));
433}
434
435static void test_dns_service_join(void) {
436 test_dns_service_join_one("", "", "", -EINVAL, NULL);
437 test_dns_service_join_one("", "_http._tcp", "", -EINVAL, NULL);
438 test_dns_service_join_one("", "_http._tcp", "foo", -EINVAL, NULL);
439 test_dns_service_join_one("foo", "", "foo", -EINVAL, NULL);
440 test_dns_service_join_one("foo", "foo", "foo", -EINVAL, NULL);
441
442 test_dns_service_join_one("foo", "_http._tcp", "", 0, "foo._http._tcp");
443 test_dns_service_join_one(NULL, "_http._tcp", "", 0, "_http._tcp");
444 test_dns_service_join_one("foo", "_http._tcp", "foo", 0, "foo._http._tcp.foo");
445 test_dns_service_join_one(NULL, "_http._tcp", "foo", 0, "_http._tcp.foo");
446 test_dns_service_join_one("Lennart's PC", "_pc._tcp", "foo.bar.com", 0, "Lennart\\039s\\032PC._pc._tcp.foo.bar.com");
447 test_dns_service_join_one(NULL, "_pc._tcp", "foo.bar.com", 0, "_pc._tcp.foo.bar.com");
448}
449
450static void test_dns_service_split_one(const char *joined, const char *a, const char *b, const char *c, int r) {
451 _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *t = NULL;
452
453 assert_se(dns_service_split(joined, &x, &y, &z) == r);
454 assert_se(streq_ptr(x, a));
455 assert_se(streq_ptr(y, b));
456 assert_se(streq_ptr(z, c));
457
458 if (r < 0)
459 return;
460
461 if (y) {
462 assert_se(dns_service_join(x, y, z, &t) == 0);
463 assert_se(streq_ptr(joined, t));
464 } else
465 assert_se(!x && streq_ptr(z, joined));
466}
467
468static void test_dns_service_split(void) {
469 test_dns_service_split_one("", NULL, NULL, "", 0);
470 test_dns_service_split_one("foo", NULL, NULL, "foo", 0);
471 test_dns_service_split_one("foo.bar", NULL, NULL, "foo.bar", 0);
472 test_dns_service_split_one("_foo.bar", NULL, NULL, "_foo.bar", 0);
473 test_dns_service_split_one("_foo._bar", NULL, "_foo._bar", "", 0);
474 test_dns_service_split_one("_meh._foo._bar", "_meh", "_foo._bar", "", 0);
475 test_dns_service_split_one("Wuff\\032Wuff._foo._bar.waldo.com", "Wuff Wuff", "_foo._bar", "waldo.com", 0);
0a49b6b6
LP
476}
477
58db254a
LP
478static void test_dns_name_change_suffix_one(const char *name, const char *old_suffix, const char *new_suffix, int r, const char *result) {
479 _cleanup_free_ char *s = NULL;
480
481 assert_se(dns_name_change_suffix(name, old_suffix, new_suffix, &s) == r);
482 assert_se(streq_ptr(s, result));
483}
484
485static void test_dns_name_change_suffix(void) {
486 test_dns_name_change_suffix_one("foo.bar", "bar", "waldo", 1, "foo.waldo");
487 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "foo.bar.waldi.quux", "piff.paff", 1, "piff.paff");
488 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "bar.waldi.quux", "piff.paff", 1, "foo.piff.paff");
489 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "waldi.quux", "piff.paff", 1, "foo.bar.piff.paff");
490 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "quux", "piff.paff", 1, "foo.bar.waldi.piff.paff");
491 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "", "piff.paff", 1, "foo.bar.waldi.quux.piff.paff");
492 test_dns_name_change_suffix_one("", "", "piff.paff", 1, "piff.paff");
493 test_dns_name_change_suffix_one("", "", "", 1, "");
494 test_dns_name_change_suffix_one("a", "b", "c", 0, NULL);
495}
496
e7ff0e0b
LP
497static void test_dns_name_suffix_one(const char *name, unsigned n_labels, const char *result, int ret) {
498 const char *p = NULL;
499
500 assert_se(ret == dns_name_suffix(name, n_labels, &p));
501 assert_se(streq_ptr(p, result));
502}
503
504static void test_dns_name_suffix(void) {
505 test_dns_name_suffix_one("foo.bar", 2, "foo.bar", 0);
506 test_dns_name_suffix_one("foo.bar", 1, "bar", 1);
507 test_dns_name_suffix_one("foo.bar", 0, "", 2);
508 test_dns_name_suffix_one("foo.bar", 3, NULL, -EINVAL);
509 test_dns_name_suffix_one("foo.bar", 4, NULL, -EINVAL);
510
511 test_dns_name_suffix_one("bar", 1, "bar", 0);
512 test_dns_name_suffix_one("bar", 0, "", 1);
513 test_dns_name_suffix_one("bar", 2, NULL, -EINVAL);
514 test_dns_name_suffix_one("bar", 3, NULL, -EINVAL);
515
516 test_dns_name_suffix_one("", 0, "", 0);
517 test_dns_name_suffix_one("", 1, NULL, -EINVAL);
518 test_dns_name_suffix_one("", 2, NULL, -EINVAL);
519}
520
521static void test_dns_name_count_labels_one(const char *name, int n) {
522 assert_se(dns_name_count_labels(name) == n);
523}
524
525static void test_dns_name_count_labels(void) {
526 test_dns_name_count_labels_one("foo.bar.quux.", 3);
527 test_dns_name_count_labels_one("foo.bar.quux", 3);
528 test_dns_name_count_labels_one("foo.bar.", 2);
529 test_dns_name_count_labels_one("foo.bar", 2);
530 test_dns_name_count_labels_one("foo.", 1);
531 test_dns_name_count_labels_one("foo", 1);
532 test_dns_name_count_labels_one("", 0);
533 test_dns_name_count_labels_one(".", 0);
534 test_dns_name_count_labels_one("..", -EINVAL);
535}
536
db5b0e92
LP
537static void test_dns_name_equal_skip_one(const char *a, unsigned n_labels, const char *b, int ret) {
538 assert_se(dns_name_equal_skip(a, n_labels, b) == ret);
539}
540
541static void test_dns_name_equal_skip(void) {
542 test_dns_name_equal_skip_one("foo", 0, "bar", 0);
543 test_dns_name_equal_skip_one("foo", 0, "foo", 1);
544 test_dns_name_equal_skip_one("foo", 1, "foo", 0);
545 test_dns_name_equal_skip_one("foo", 2, "foo", 0);
546
547 test_dns_name_equal_skip_one("foo.bar", 0, "foo.bar", 1);
548 test_dns_name_equal_skip_one("foo.bar", 1, "foo.bar", 0);
549 test_dns_name_equal_skip_one("foo.bar", 2, "foo.bar", 0);
550 test_dns_name_equal_skip_one("foo.bar", 3, "foo.bar", 0);
551
552 test_dns_name_equal_skip_one("foo.bar", 0, "bar", 0);
553 test_dns_name_equal_skip_one("foo.bar", 1, "bar", 1);
554 test_dns_name_equal_skip_one("foo.bar", 2, "bar", 0);
555 test_dns_name_equal_skip_one("foo.bar", 3, "bar", 0);
556
557 test_dns_name_equal_skip_one("foo.bar", 0, "", 0);
558 test_dns_name_equal_skip_one("foo.bar", 1, "", 0);
559 test_dns_name_equal_skip_one("foo.bar", 2, "", 1);
560 test_dns_name_equal_skip_one("foo.bar", 3, "", 0);
561
562 test_dns_name_equal_skip_one("", 0, "", 1);
563 test_dns_name_equal_skip_one("", 1, "", 0);
564 test_dns_name_equal_skip_one("", 1, "foo", 0);
565 test_dns_name_equal_skip_one("", 2, "foo", 0);
566}
567
56512859
LP
568static void test_dns_name_compare_func(void) {
569 assert_se(dns_name_compare_func("", "") == 0);
570 assert_se(dns_name_compare_func("", ".") == 0);
571 assert_se(dns_name_compare_func(".", "") == 0);
572 assert_se(dns_name_compare_func("foo", "foo.") == 0);
573 assert_se(dns_name_compare_func("foo.", "foo") == 0);
574 assert_se(dns_name_compare_func("foo", "foo") == 0);
575 assert_se(dns_name_compare_func("foo.", "foo.") == 0);
576 assert_se(dns_name_compare_func("heise.de", "HEISE.DE.") == 0);
577
578 assert_se(dns_name_compare_func("de.", "heise.de") != 0);
579}
580
b9282bc1
LP
581static void test_dns_name_common_suffix_one(const char *a, const char *b, const char *result) {
582 const char *c;
583
584 assert_se(dns_name_common_suffix(a, b, &c) >= 0);
585 assert_se(streq(c, result));
586}
587
588static void test_dns_name_common_suffix(void) {
589 test_dns_name_common_suffix_one("", "", "");
590 test_dns_name_common_suffix_one("foo", "", "");
591 test_dns_name_common_suffix_one("", "foo", "");
592 test_dns_name_common_suffix_one("foo", "bar", "");
593 test_dns_name_common_suffix_one("bar", "foo", "");
594 test_dns_name_common_suffix_one("foo", "foo", "foo");
595 test_dns_name_common_suffix_one("quux.foo", "foo", "foo");
596 test_dns_name_common_suffix_one("foo", "quux.foo", "foo");
597 test_dns_name_common_suffix_one("this.is.a.short.sentence", "this.is.another.short.sentence", "short.sentence");
598 test_dns_name_common_suffix_one("FOO.BAR", "tEST.bAR", "BAR");
599}
600
0cf40f55
LP
601static void test_dns_name_apply_idna_one(const char *s, const char *result) {
602#ifdef HAVE_LIBIDN
603 _cleanup_free_ char *buf = NULL;
604 assert_se(dns_name_apply_idna(s, &buf) >= 0);
605 assert_se(dns_name_equal(buf, result) > 0);
606#endif
607}
608
609static void test_dns_name_apply_idna(void) {
610 test_dns_name_apply_idna_one("", "");
611 test_dns_name_apply_idna_one("foo", "foo");
612 test_dns_name_apply_idna_one("foo.", "foo");
613 test_dns_name_apply_idna_one("foo.bar", "foo.bar");
614 test_dns_name_apply_idna_one("foo.bar.", "foo.bar");
615 test_dns_name_apply_idna_one("föö", "xn--f-1gaa");
616 test_dns_name_apply_idna_one("föö.", "xn--f-1gaa");
617 test_dns_name_apply_idna_one("föö.bär", "xn--f-1gaa.xn--br-via");
618 test_dns_name_apply_idna_one("föö.bär.", "xn--f-1gaa.xn--br-via");
619}
620
74b2466e
LP
621int main(int argc, char *argv[]) {
622
623 test_dns_label_unescape();
642900d3 624 test_dns_label_unescape_suffix();
74b2466e
LP
625 test_dns_label_escape();
626 test_dns_name_normalize();
627 test_dns_name_equal();
628 test_dns_name_endswith();
eb241cdb 629 test_dns_name_startswith();
ae72b22c 630 test_dns_name_between();
dc477e73
LP
631 test_dns_name_is_root();
632 test_dns_name_is_single_label();
b914e211 633 test_dns_name_reverse();
9ca45586
LP
634 test_dns_name_concat();
635 test_dns_name_is_valid();
54adabf7 636 test_dns_name_to_wire_format();
0a49b6b6 637 test_dns_service_name_is_valid();
7e8131e9 638 test_dns_srv_type_is_valid();
0e8eedbb
LP
639 test_dns_service_join();
640 test_dns_service_split();
58db254a 641 test_dns_name_change_suffix();
e7ff0e0b
LP
642 test_dns_name_suffix();
643 test_dns_name_count_labels();
db5b0e92 644 test_dns_name_equal_skip();
56512859 645 test_dns_name_compare_func();
b9282bc1 646 test_dns_name_common_suffix();
0cf40f55 647 test_dns_name_apply_idna();
74b2466e
LP
648
649 return 0;
650}