1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "alloc-util.h"
4 #include "dns-domain.h"
6 #include "string-util.h"
9 static void test_dns_label_unescape_one(const char *what
, const char *expect
, size_t buffer_sz
, int ret
, int ret_ldh
) {
10 char buffer
[buffer_sz
];
14 log_info("%s, %s, %zu, →%d/%d", what
, expect
, buffer_sz
, ret
, ret_ldh
);
16 r
= dns_label_unescape(&w
, buffer
, buffer_sz
, 0);
19 ASSERT_STREQ(buffer
, expect
);
22 r
= dns_label_unescape(&w
, buffer
, buffer_sz
, DNS_LABEL_LDH
);
23 assert_se(r
== ret_ldh
);
25 ASSERT_STREQ(buffer
, expect
);
28 r
= dns_label_unescape(&w
, buffer
, buffer_sz
, DNS_LABEL_NO_ESCAPES
);
29 const int ret_noe
= strchr(what
, '\\') ? -EINVAL
: ret
;
30 assert_se(r
== ret_noe
);
32 ASSERT_STREQ(buffer
, expect
);
35 TEST(dns_label_unescape
) {
36 test_dns_label_unescape_one("hallo", "hallo", 6, 5, 5);
37 test_dns_label_unescape_one("hallo", "hallo", 4, -ENOBUFS
, -ENOBUFS
);
38 test_dns_label_unescape_one("", "", 10, 0, 0);
39 test_dns_label_unescape_one("hallo\\.foobar", "hallo.foobar", 20, 12, -EINVAL
);
40 test_dns_label_unescape_one("hallo.foobar", "hallo", 10, 5, 5);
41 test_dns_label_unescape_one("hallo\n.foobar", "hallo", 20, -EINVAL
, -EINVAL
);
42 test_dns_label_unescape_one("hallo\\", "hallo", 20, -EINVAL
, -EINVAL
);
43 test_dns_label_unescape_one("hallo\\032 ", "hallo ", 20, 7, -EINVAL
);
44 test_dns_label_unescape_one(".", "", 20, 0, 0);
45 test_dns_label_unescape_one("..", "", 20, -EINVAL
, -EINVAL
);
46 test_dns_label_unescape_one(".foobar", "", 20, -EINVAL
, -EINVAL
);
47 test_dns_label_unescape_one("foobar.", "foobar", 20, 6, 6);
48 test_dns_label_unescape_one("foobar..", "foobar", 20, -EINVAL
, -EINVAL
);
49 test_dns_label_unescape_one("foo-bar", "foo-bar", 20, 7, 7);
50 test_dns_label_unescape_one("foo-", "foo-", 20, 4, -EINVAL
);
51 test_dns_label_unescape_one("-foo", "-foo", 20, 4, -EINVAL
);
52 test_dns_label_unescape_one("-foo-", "-foo-", 20, 5, -EINVAL
);
53 test_dns_label_unescape_one("foo-.", "foo-", 20, 4, -EINVAL
);
54 test_dns_label_unescape_one("foo.-", "foo", 20, 3, 3);
55 test_dns_label_unescape_one("foo\\032", "foo ", 20, 4, -EINVAL
);
56 test_dns_label_unescape_one("foo\\045", "foo-", 20, 4, -EINVAL
);
57 test_dns_label_unescape_one("głąb", "głąb", 20, 6, -EINVAL
);
60 static void test_dns_name_to_wire_format_one(const char *what
, const char *expect
, size_t buffer_sz
, int ret
) {
61 uint8_t buffer
[buffer_sz
];
64 log_info("%s, %s, %zu, →%d", what
, strnull(expect
), buffer_sz
, ret
);
66 r
= dns_name_to_wire_format(what
, buffer
, buffer_sz
, false);
70 assert(expect
); /* for gcc */
71 assert_se(memcmp(buffer
, expect
, r
) == 0);
75 TEST(dns_name_to_wire_format
) {
76 static const char out0
[] = { 0 };
77 static const char out1
[] = { 3, 'f', 'o', 'o', 0 };
78 static const char out2
[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
79 static const char out3
[] = { 4, ' ', 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
80 static const char out4
[] = { 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 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
99 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
100 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
101 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
102 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
103 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
104 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
105 3, 'a', '1', '2', 0 };
107 test_dns_name_to_wire_format_one("", out0
, sizeof(out0
), sizeof(out0
));
109 test_dns_name_to_wire_format_one("foo", out1
, sizeof(out1
), sizeof(out1
));
110 test_dns_name_to_wire_format_one("foo", out1
, sizeof(out1
) + 1, sizeof(out1
));
111 test_dns_name_to_wire_format_one("foo", out1
, sizeof(out1
) - 1, -ENOBUFS
);
113 test_dns_name_to_wire_format_one("hallo.foo.bar", out2
, sizeof(out2
), sizeof(out2
));
114 test_dns_name_to_wire_format_one("hallo.foo..bar", NULL
, 32, -EINVAL
);
116 test_dns_name_to_wire_format_one("\\032foo.bar", out3
, sizeof(out3
), sizeof(out3
));
118 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
);
119 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
));
122 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
) {
123 char buffer
[buffer_sz
];
127 log_info("%s, %s, %s, %zu, %d, %d", what
, expect1
, expect2
, buffer_sz
, ret1
, ret2
);
129 label
= what
+ strlen(what
);
131 r
= dns_label_unescape_suffix(what
, &label
, buffer
, buffer_sz
);
132 assert_se(r
== ret1
);
134 ASSERT_STREQ(buffer
, expect1
);
136 r
= dns_label_unescape_suffix(what
, &label
, buffer
, buffer_sz
);
137 assert_se(r
== ret2
);
139 ASSERT_STREQ(buffer
, expect2
);
142 TEST(dns_label_unescape_suffix
) {
143 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 6, 5, 0);
144 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOBUFS
, -ENOBUFS
);
145 test_dns_label_unescape_suffix_one("", "", "", 10, 0, 0);
146 test_dns_label_unescape_suffix_one("hallo\\.foobar", "hallo.foobar", "", 20, 12, 0);
147 test_dns_label_unescape_suffix_one("hallo.foobar", "foobar", "hallo", 10, 6, 5);
148 test_dns_label_unescape_suffix_one("hallo.foobar\n", "foobar", "foobar", 20, -EINVAL
, -EINVAL
);
149 test_dns_label_unescape_suffix_one("hallo\\", "hallo", "hallo", 20, -EINVAL
, -EINVAL
);
150 test_dns_label_unescape_suffix_one("hallo\\032 ", "hallo ", "", 20, 7, 0);
151 test_dns_label_unescape_suffix_one(".", "", "", 20, 0, 0);
152 test_dns_label_unescape_suffix_one("..", "", "", 20, 0, -EINVAL
);
153 test_dns_label_unescape_suffix_one(".foobar", "foobar", "", 20, 6, -EINVAL
);
154 test_dns_label_unescape_suffix_one("foobar.", "foobar", "", 20, 6, 0);
155 test_dns_label_unescape_suffix_one("foo\\\\bar", "foo\\bar", "", 20, 7, 0);
156 test_dns_label_unescape_suffix_one("foo.bar", "bar", "foo", 20, 3, 3);
157 test_dns_label_unescape_suffix_one("foo..bar", "bar", "", 20, 3, -EINVAL
);
158 test_dns_label_unescape_suffix_one("foo...bar", "bar", "", 20, 3, -EINVAL
);
159 test_dns_label_unescape_suffix_one("foo\\.bar", "foo.bar", "", 20, 7, 0);
160 test_dns_label_unescape_suffix_one("foo\\\\.bar", "bar", "foo\\", 20, 3, 4);
161 test_dns_label_unescape_suffix_one("foo\\\\\\.bar", "foo\\.bar", "", 20, 8, 0);
164 static void test_dns_label_escape_one(const char *what
, size_t l
, const char *expect
, int ret
) {
165 _cleanup_free_
char *t
= NULL
;
168 log_info("%s, %zu, %s, →%d", what
, l
, strnull(expect
), ret
);
170 r
= dns_label_escape_new(what
, l
, &t
);
176 ASSERT_STREQ(expect
, t
);
179 TEST(dns_label_escape
) {
180 test_dns_label_escape_one("", 0, NULL
, -EINVAL
);
181 test_dns_label_escape_one("hallo", 5, "hallo", 5);
182 test_dns_label_escape_one("hallo", 6, "hallo\\000", 9);
183 test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
186 static void test_dns_name_normalize_one(const char *what
, const char *expect
, int ret
) {
187 _cleanup_free_
char *t
= NULL
;
190 r
= dns_name_normalize(what
, 0, &t
);
196 ASSERT_STREQ(expect
, t
);
199 TEST(dns_name_normalize
) {
200 test_dns_name_normalize_one("", ".", 0);
201 test_dns_name_normalize_one("f", "f", 0);
202 test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
203 test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
204 test_dns_name_normalize_one("\\000", "\\000", 0);
205 test_dns_name_normalize_one("..", NULL
, -EINVAL
);
206 test_dns_name_normalize_one(".foobar", NULL
, -EINVAL
);
207 test_dns_name_normalize_one("foobar.", "foobar", 0);
208 test_dns_name_normalize_one(".", ".", 0);
211 static void test_dns_name_equal_one(const char *a
, const char *b
, int ret
) {
214 r
= dns_name_equal(a
, b
);
217 r
= dns_name_equal(b
, a
);
221 TEST(dns_name_equal
) {
222 test_dns_name_equal_one("", "", true);
223 test_dns_name_equal_one("x", "x", true);
224 test_dns_name_equal_one("x", "x.", true);
225 test_dns_name_equal_one("abc.def", "abc.def", true);
226 test_dns_name_equal_one("abc.def", "ABC.def", true);
227 test_dns_name_equal_one("abc.def", "CBA.def", false);
228 test_dns_name_equal_one("", "xxx", false);
229 test_dns_name_equal_one("ab", "a", false);
230 test_dns_name_equal_one("\\000", "\\000", true);
231 test_dns_name_equal_one(".", "", true);
232 test_dns_name_equal_one(".", ".", true);
233 test_dns_name_equal_one("..", "..", -EINVAL
);
236 static void test_dns_name_between_one(const char *a
, const char *b
, const char *c
, int ret
) {
239 r
= dns_name_between(a
, b
, c
);
242 r
= dns_name_between(c
, b
, a
);
244 assert_se(r
== 0 || dns_name_equal(a
, c
) > 0);
249 TEST(dns_name_between
) {
250 /* see https://tools.ietf.org/html/rfc4034#section-6.1
251 Note that we use "\033.z.example" in stead of "\001.z.example" as we
252 consider the latter invalid */
253 test_dns_name_between_one("example", "a.example", "yljkjljk.a.example", true);
254 test_dns_name_between_one("a.example", "yljkjljk.a.example", "Z.a.example", true);
255 test_dns_name_between_one("yljkjljk.a.example", "Z.a.example", "zABC.a.EXAMPLE", true);
256 test_dns_name_between_one("Z.a.example", "zABC.a.EXAMPLE", "z.example", true);
257 test_dns_name_between_one("zABC.a.EXAMPLE", "z.example", "\\033.z.example", true);
258 test_dns_name_between_one("z.example", "\\033.z.example", "*.z.example", true);
259 test_dns_name_between_one("\\033.z.example", "*.z.example", "\\200.z.example", true);
260 test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
261 test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
263 test_dns_name_between_one("example", "a.example", "example", true);
264 test_dns_name_between_one("example", "example", "example", false);
265 test_dns_name_between_one("example", "example", "yljkjljk.a.example", false);
266 test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false);
267 test_dns_name_between_one("hkps.pool.sks-keyservers.net", "_pgpkey-https._tcp.hkps.pool.sks-keyservers.net", "ipv4.pool.sks-keyservers.net", true);
270 static void test_dns_name_endswith_one(const char *a
, const char *b
, int ret
) {
271 assert_se(dns_name_endswith(a
, b
) == ret
);
274 TEST(dns_name_endswith
) {
275 test_dns_name_endswith_one("", "", true);
276 test_dns_name_endswith_one("", "xxx", false);
277 test_dns_name_endswith_one("xxx", "", true);
278 test_dns_name_endswith_one("x", "x", true);
279 test_dns_name_endswith_one("x", "y", false);
280 test_dns_name_endswith_one("x.y", "y", true);
281 test_dns_name_endswith_one("x.y", "Y", true);
282 test_dns_name_endswith_one("x.y", "x", false);
283 test_dns_name_endswith_one("x.y.z", "Z", true);
284 test_dns_name_endswith_one("x.y.z", "y.Z", true);
285 test_dns_name_endswith_one("x.y.z", "x.y.Z", true);
286 test_dns_name_endswith_one("x.y.z", "waldo", false);
287 test_dns_name_endswith_one("x.y.z.u.v.w", "y.z", false);
288 test_dns_name_endswith_one("x.y.z.u.v.w", "u.v.w", true);
289 test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL
);
292 static void test_dns_name_startswith_one(const char *a
, const char *b
, int ret
) {
293 assert_se(dns_name_startswith(a
, b
) == ret
);
296 TEST(dns_name_startswith
) {
297 test_dns_name_startswith_one("", "", true);
298 test_dns_name_startswith_one("", "xxx", false);
299 test_dns_name_startswith_one("xxx", "", true);
300 test_dns_name_startswith_one("x", "x", true);
301 test_dns_name_startswith_one("x", "y", false);
302 test_dns_name_startswith_one("x.y", "x.y", true);
303 test_dns_name_startswith_one("x.y", "y.x", false);
304 test_dns_name_startswith_one("x.y", "x", true);
305 test_dns_name_startswith_one("x.y", "X", true);
306 test_dns_name_startswith_one("x.y", "y", false);
307 test_dns_name_startswith_one("x.y", "", true);
308 test_dns_name_startswith_one("x.y", "X", true);
311 TEST(dns_name_is_root
) {
312 assert_se(dns_name_is_root(""));
313 assert_se(dns_name_is_root("."));
314 assert_se(!dns_name_is_root("xxx"));
315 assert_se(!dns_name_is_root("xxx."));
316 assert_se(!dns_name_is_root(".."));
319 TEST(dns_name_is_single_label
) {
320 assert_se(!dns_name_is_single_label(""));
321 assert_se(!dns_name_is_single_label("."));
322 assert_se(!dns_name_is_single_label(".."));
323 assert_se(dns_name_is_single_label("x"));
324 assert_se(dns_name_is_single_label("x."));
325 assert_se(!dns_name_is_single_label("xx.yy"));
328 static void test_dns_name_reverse_one(const char *address
, const char *name
) {
329 _cleanup_free_
char *p
= NULL
;
330 union in_addr_union a
, b
= {};
331 int familya
, familyb
;
333 assert_se(in_addr_from_string_auto(address
, &familya
, &a
) >= 0);
334 assert_se(dns_name_reverse(familya
, &a
, &p
) >= 0);
335 ASSERT_STREQ(p
, name
);
336 assert_se(dns_name_address(p
, &familyb
, &b
) > 0);
337 assert_se(familya
== familyb
);
338 assert_se(in_addr_equal(familya
, &a
, &b
));
341 TEST(dns_name_reverse
) {
342 test_dns_name_reverse_one("47.11.8.15", "15.8.11.47.in-addr.arpa");
343 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");
344 test_dns_name_reverse_one("127.0.0.1", "1.0.0.127.in-addr.arpa");
345 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");
348 static void test_dns_name_concat_one(const char *a
, const char *b
, int r
, const char *result
) {
349 _cleanup_free_
char *p
= NULL
;
351 assert_se(dns_name_concat(a
, b
, 0, &p
) == r
);
352 ASSERT_STREQ(p
, result
);
355 TEST(dns_name_concat
) {
356 test_dns_name_concat_one("", "", 0, ".");
357 test_dns_name_concat_one(".", "", 0, ".");
358 test_dns_name_concat_one("", ".", 0, ".");
359 test_dns_name_concat_one(".", ".", 0, ".");
360 test_dns_name_concat_one("foo", "bar", 0, "foo.bar");
361 test_dns_name_concat_one("foo.foo", "bar.bar", 0, "foo.foo.bar.bar");
362 test_dns_name_concat_one("foo", NULL
, 0, "foo");
363 test_dns_name_concat_one("foo", ".", 0, "foo");
364 test_dns_name_concat_one("foo.", "bar.", 0, "foo.bar");
365 test_dns_name_concat_one(NULL
, NULL
, 0, ".");
366 test_dns_name_concat_one(NULL
, ".", 0, ".");
367 test_dns_name_concat_one(NULL
, "foo", 0, "foo");
370 static void test_dns_name_is_valid_one(const char *s
, int ret
, int ret_ldh
) {
371 log_info("%s, →%d", s
, ret
);
373 assert_se(dns_name_is_valid(s
) == ret
);
374 assert_se(dns_name_is_valid_ldh(s
) == ret_ldh
);
377 TEST(dns_name_is_valid
) {
378 test_dns_name_is_valid_one("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[._qotd._tcp.local", 1, 0);
379 test_dns_name_is_valid_one("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]._qotd._tcp.local", 0, 0);
381 test_dns_name_is_valid_one("foo", 1, 1);
382 test_dns_name_is_valid_one("foo.", 1, 1);
383 test_dns_name_is_valid_one("foo..", 0, 0);
384 test_dns_name_is_valid_one("Foo", 1, 1);
385 test_dns_name_is_valid_one("foo.bar", 1, 1);
386 test_dns_name_is_valid_one("foo.bar.baz", 1, 1);
387 test_dns_name_is_valid_one("", 1, 1);
388 test_dns_name_is_valid_one("foo..bar", 0, 0);
389 test_dns_name_is_valid_one(".foo.bar", 0, 0);
390 test_dns_name_is_valid_one("foo.bar.", 1, 1);
391 test_dns_name_is_valid_one("foo.bar..", 0, 0);
392 test_dns_name_is_valid_one("\\zbar", 0, 0);
393 test_dns_name_is_valid_one("ä", 1, 0);
394 test_dns_name_is_valid_one("\n", 0, 0);
396 test_dns_name_is_valid_one("dash-", 1, 0);
397 test_dns_name_is_valid_one("-dash", 1, 0);
398 test_dns_name_is_valid_one("dash-dash", 1, 1);
399 test_dns_name_is_valid_one("foo.dash-", 1, 0);
400 test_dns_name_is_valid_one("foo.-dash", 1, 0);
401 test_dns_name_is_valid_one("foo.dash-dash", 1, 1);
402 test_dns_name_is_valid_one("foo.dash-.bar", 1, 0);
403 test_dns_name_is_valid_one("foo.-dash.bar", 1, 0);
404 test_dns_name_is_valid_one("foo.dash-dash.bar", 1, 1);
405 test_dns_name_is_valid_one("dash-.bar", 1, 0);
406 test_dns_name_is_valid_one("-dash.bar", 1, 0);
407 test_dns_name_is_valid_one("dash-dash.bar", 1, 1);
408 test_dns_name_is_valid_one("-.bar", 1, 0);
409 test_dns_name_is_valid_one("foo.-", 1, 0);
412 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, 0);
415 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, 0);
418 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, 0);
421 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, 1);
423 /* label of 64 chars length */
424 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a123", 0, 0);
426 /* label of 63 chars length */
427 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a12", 1, 1);
430 TEST(dns_service_name_is_valid
) {
431 assert_se(dns_service_name_is_valid("Lennart's Compüter"));
432 assert_se(dns_service_name_is_valid("piff.paff"));
434 assert_se(!dns_service_name_is_valid(NULL
));
435 assert_se(!dns_service_name_is_valid(""));
436 assert_se(!dns_service_name_is_valid("foo\nbar"));
437 assert_se(!dns_service_name_is_valid("foo\201bar"));
438 assert_se(!dns_service_name_is_valid("this is an overly long string that is certainly longer than 63 characters"));
441 TEST(dns_srv_type_is_valid
) {
442 assert_se(dns_srv_type_is_valid("_http._tcp"));
443 assert_se(dns_srv_type_is_valid("_foo-bar._tcp"));
444 assert_se(dns_srv_type_is_valid("_w._udp"));
445 assert_se(dns_srv_type_is_valid("_a800._tcp"));
446 assert_se(dns_srv_type_is_valid("_a-800._tcp"));
448 assert_se(!dns_srv_type_is_valid(NULL
));
449 assert_se(!dns_srv_type_is_valid(""));
450 assert_se(!dns_srv_type_is_valid("x"));
451 assert_se(!dns_srv_type_is_valid("_foo"));
452 assert_se(!dns_srv_type_is_valid("_tcp"));
453 assert_se(!dns_srv_type_is_valid("_"));
454 assert_se(!dns_srv_type_is_valid("_foo."));
455 assert_se(!dns_srv_type_is_valid("_föo._tcp"));
456 assert_se(!dns_srv_type_is_valid("_f\no._tcp"));
457 assert_se(!dns_srv_type_is_valid("_800._tcp"));
458 assert_se(!dns_srv_type_is_valid("_-800._tcp"));
459 assert_se(!dns_srv_type_is_valid("_-foo._tcp"));
460 assert_se(!dns_srv_type_is_valid("_piep._foo._udp"));
463 TEST(dnssd_srv_type_is_valid
) {
464 assert_se(dnssd_srv_type_is_valid("_http._tcp"));
465 assert_se(dnssd_srv_type_is_valid("_foo-bar._tcp"));
466 assert_se(dnssd_srv_type_is_valid("_w._udp"));
467 assert_se(dnssd_srv_type_is_valid("_a800._tcp"));
468 assert_se(dnssd_srv_type_is_valid("_a-800._tcp"));
470 assert_se(!dnssd_srv_type_is_valid(NULL
));
471 assert_se(!dnssd_srv_type_is_valid(""));
472 assert_se(!dnssd_srv_type_is_valid("x"));
473 assert_se(!dnssd_srv_type_is_valid("_foo"));
474 assert_se(!dnssd_srv_type_is_valid("_tcp"));
475 assert_se(!dnssd_srv_type_is_valid("_"));
476 assert_se(!dnssd_srv_type_is_valid("_foo."));
477 assert_se(!dnssd_srv_type_is_valid("_föo._tcp"));
478 assert_se(!dnssd_srv_type_is_valid("_f\no._tcp"));
479 assert_se(!dnssd_srv_type_is_valid("_800._tcp"));
480 assert_se(!dnssd_srv_type_is_valid("_-800._tcp"));
481 assert_se(!dnssd_srv_type_is_valid("_-foo._tcp"));
482 assert_se(!dnssd_srv_type_is_valid("_piep._foo._udp"));
483 assert_se(!dnssd_srv_type_is_valid("_foo._unknown"));
486 static void test_dns_service_join_one(const char *a
, const char *b
, const char *c
, int r
, const char *d
) {
487 _cleanup_free_
char *x
= NULL
, *y
= NULL
, *z
= NULL
, *t
= NULL
;
489 log_info("%s, %s, %s, →%d, %s", strnull(a
), strnull(b
), strnull(c
), r
, strnull(d
));
491 assert_se(dns_service_join(a
, b
, c
, &t
) == r
);
497 assert_se(dns_service_split(t
, &x
, &y
, &z
) >= 0);
500 assert_se(dns_name_equal(c
, z
) > 0);
503 TEST(dns_service_join
) {
504 test_dns_service_join_one("", "", "", -EINVAL
, NULL
);
505 test_dns_service_join_one("", "_http._tcp", "", -EINVAL
, NULL
);
506 test_dns_service_join_one("", "_http._tcp", "foo", -EINVAL
, NULL
);
507 test_dns_service_join_one("foo", "", "foo", -EINVAL
, NULL
);
508 test_dns_service_join_one("foo", "foo", "foo", -EINVAL
, NULL
);
510 test_dns_service_join_one("foo", "_http._tcp", "", 0, "foo._http._tcp");
511 test_dns_service_join_one(NULL
, "_http._tcp", "", 0, "_http._tcp");
512 test_dns_service_join_one("foo", "_http._tcp", "foo", 0, "foo._http._tcp.foo");
513 test_dns_service_join_one(NULL
, "_http._tcp", "foo", 0, "_http._tcp.foo");
514 test_dns_service_join_one("Lennart's PC", "_pc._tcp", "foo.bar.com", 0, "Lennart\\039s\\032PC._pc._tcp.foo.bar.com");
515 test_dns_service_join_one(NULL
, "_pc._tcp", "foo.bar.com", 0, "_pc._tcp.foo.bar.com");
518 static void test_dns_service_split_one(const char *joined
, const char *a
, const char *b
, const char *c
, int r
) {
519 _cleanup_free_
char *x
= NULL
, *y
= NULL
, *z
= NULL
, *t
= NULL
;
521 log_info("%s, %s, %s, %s, →%d", joined
, strnull(a
), strnull(b
), strnull(c
), r
);
523 assert_se(dns_service_split(joined
, &x
, &y
, &z
) == r
);
532 assert_se(dns_service_join(x
, y
, z
, &t
) == 0);
533 assert_se(dns_name_equal(joined
, t
) > 0);
535 assert_se(!x
&& dns_name_equal(z
, joined
) > 0);
538 TEST(dns_service_split
) {
539 test_dns_service_split_one("", NULL
, NULL
, ".", 0);
540 test_dns_service_split_one("foo", NULL
, NULL
, "foo", 0);
541 test_dns_service_split_one("foo.bar", NULL
, NULL
, "foo.bar", 0);
542 test_dns_service_split_one("_foo.bar", NULL
, NULL
, "_foo.bar", 0);
543 test_dns_service_split_one("_foo._bar", NULL
, "_foo._bar", ".", 0);
544 test_dns_service_split_one("_meh._foo._bar", "_meh", "_foo._bar", ".", 0);
545 test_dns_service_split_one("Wuff\\032Wuff._foo._bar.waldo.com", "Wuff Wuff", "_foo._bar", "waldo.com", 0);
546 test_dns_service_split_one("_Q._Q-------------------------------------------------------------", NULL
, "_Q._Q-------------------------------------------------------------", ".", 0);
549 static void test_dns_name_change_suffix_one(const char *name
, const char *old_suffix
, const char *new_suffix
, int r
, const char *result
) {
550 _cleanup_free_
char *s
= NULL
;
552 log_info("%s, %s, %s, →%s", name
, old_suffix
, new_suffix
, strnull(result
));
554 assert_se(dns_name_change_suffix(name
, old_suffix
, new_suffix
, &s
) == r
);
555 ASSERT_STREQ(s
, result
);
558 TEST(dns_name_change_suffix
) {
559 test_dns_name_change_suffix_one("foo.bar", "bar", "waldo", 1, "foo.waldo");
560 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "foo.bar.waldi.quux", "piff.paff", 1, "piff.paff");
561 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "bar.waldi.quux", "piff.paff", 1, "foo.piff.paff");
562 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "waldi.quux", "piff.paff", 1, "foo.bar.piff.paff");
563 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "quux", "piff.paff", 1, "foo.bar.waldi.piff.paff");
564 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "", "piff.paff", 1, "foo.bar.waldi.quux.piff.paff");
565 test_dns_name_change_suffix_one("", "", "piff.paff", 1, "piff.paff");
566 test_dns_name_change_suffix_one("", "", "", 1, ".");
567 test_dns_name_change_suffix_one("a", "b", "c", 0, NULL
);
570 static void test_dns_name_suffix_one(const char *name
, unsigned n_labels
, const char *result
, int ret
) {
571 const char *p
= NULL
;
573 log_info("%s, %u, → %s, %d", name
, n_labels
, strnull(result
), ret
);
575 assert_se(ret
== dns_name_suffix(name
, n_labels
, &p
));
576 ASSERT_STREQ(p
, result
);
579 TEST(dns_name_suffix
) {
580 test_dns_name_suffix_one("foo.bar", 2, "foo.bar", 0);
581 test_dns_name_suffix_one("foo.bar", 1, "bar", 1);
582 test_dns_name_suffix_one("foo.bar", 0, "", 2);
583 test_dns_name_suffix_one("foo.bar", 3, NULL
, -EINVAL
);
584 test_dns_name_suffix_one("foo.bar", 4, NULL
, -EINVAL
);
586 test_dns_name_suffix_one("bar", 1, "bar", 0);
587 test_dns_name_suffix_one("bar", 0, "", 1);
588 test_dns_name_suffix_one("bar", 2, NULL
, -EINVAL
);
589 test_dns_name_suffix_one("bar", 3, NULL
, -EINVAL
);
591 test_dns_name_suffix_one("", 0, "", 0);
592 test_dns_name_suffix_one("", 1, NULL
, -EINVAL
);
593 test_dns_name_suffix_one("", 2, NULL
, -EINVAL
);
596 static void test_dns_name_count_labels_one(const char *name
, int n
) {
597 log_info("%s, →%d", name
, n
);
599 assert_se(dns_name_count_labels(name
) == n
);
602 TEST(dns_name_count_labels
) {
603 test_dns_name_count_labels_one("foo.bar.quux.", 3);
604 test_dns_name_count_labels_one("foo.bar.quux", 3);
605 test_dns_name_count_labels_one("foo.bar.", 2);
606 test_dns_name_count_labels_one("foo.bar", 2);
607 test_dns_name_count_labels_one("foo.", 1);
608 test_dns_name_count_labels_one("foo", 1);
609 test_dns_name_count_labels_one("", 0);
610 test_dns_name_count_labels_one(".", 0);
611 test_dns_name_count_labels_one("..", -EINVAL
);
614 static void test_dns_name_equal_skip_one(const char *a
, unsigned n_labels
, const char *b
, int ret
) {
615 log_info("%s, %u, %s, →%d", a
, n_labels
, b
, ret
);
617 assert_se(dns_name_equal_skip(a
, n_labels
, b
) == ret
);
620 TEST(dns_name_equal_skip
) {
621 test_dns_name_equal_skip_one("foo", 0, "bar", 0);
622 test_dns_name_equal_skip_one("foo", 0, "foo", 1);
623 test_dns_name_equal_skip_one("foo", 1, "foo", 0);
624 test_dns_name_equal_skip_one("foo", 2, "foo", 0);
626 test_dns_name_equal_skip_one("foo.bar", 0, "foo.bar", 1);
627 test_dns_name_equal_skip_one("foo.bar", 1, "foo.bar", 0);
628 test_dns_name_equal_skip_one("foo.bar", 2, "foo.bar", 0);
629 test_dns_name_equal_skip_one("foo.bar", 3, "foo.bar", 0);
631 test_dns_name_equal_skip_one("foo.bar", 0, "bar", 0);
632 test_dns_name_equal_skip_one("foo.bar", 1, "bar", 1);
633 test_dns_name_equal_skip_one("foo.bar", 2, "bar", 0);
634 test_dns_name_equal_skip_one("foo.bar", 3, "bar", 0);
636 test_dns_name_equal_skip_one("foo.bar", 0, "", 0);
637 test_dns_name_equal_skip_one("foo.bar", 1, "", 0);
638 test_dns_name_equal_skip_one("foo.bar", 2, "", 1);
639 test_dns_name_equal_skip_one("foo.bar", 3, "", 0);
641 test_dns_name_equal_skip_one("", 0, "", 1);
642 test_dns_name_equal_skip_one("", 1, "", 0);
643 test_dns_name_equal_skip_one("", 1, "foo", 0);
644 test_dns_name_equal_skip_one("", 2, "foo", 0);
647 TEST(dns_name_compare_func
) {
648 assert_se(dns_name_compare_func("", "") == 0);
649 assert_se(dns_name_compare_func("", ".") == 0);
650 assert_se(dns_name_compare_func(".", "") == 0);
651 assert_se(dns_name_compare_func("foo", "foo.") == 0);
652 assert_se(dns_name_compare_func("foo.", "foo") == 0);
653 assert_se(dns_name_compare_func("foo", "foo") == 0);
654 assert_se(dns_name_compare_func("foo.", "foo.") == 0);
655 assert_se(dns_name_compare_func("heise.de", "HEISE.DE.") == 0);
657 assert_se(dns_name_compare_func("de.", "heise.de") != 0);
660 static void test_dns_name_common_suffix_one(const char *a
, const char *b
, const char *result
) {
663 log_info("%s, %s, →%s", a
, b
, result
);
665 assert_se(dns_name_common_suffix(a
, b
, &c
) >= 0);
666 ASSERT_STREQ(c
, result
);
669 TEST(dns_name_common_suffix
) {
670 test_dns_name_common_suffix_one("", "", "");
671 test_dns_name_common_suffix_one("foo", "", "");
672 test_dns_name_common_suffix_one("", "foo", "");
673 test_dns_name_common_suffix_one("foo", "bar", "");
674 test_dns_name_common_suffix_one("bar", "foo", "");
675 test_dns_name_common_suffix_one("foo", "foo", "foo");
676 test_dns_name_common_suffix_one("quux.foo", "foo", "foo");
677 test_dns_name_common_suffix_one("foo", "quux.foo", "foo");
678 test_dns_name_common_suffix_one("this.is.a.short.sentence", "this.is.another.short.sentence", "short.sentence");
679 test_dns_name_common_suffix_one("FOO.BAR", "tEST.bAR", "BAR");
682 static void test_dns_name_apply_idna_one(const char *s
, int expected
, const char *result
) {
683 _cleanup_free_
char *buf
= NULL
;
686 r
= dns_name_apply_idna(s
, &buf
);
687 log_debug("dns_name_apply_idna: \"%s\" → %d/\"%s\" (expected %d/\"%s\")",
688 s
, r
, strnull(buf
), expected
, strnull(result
));
690 /* Different libidn2 versions are more and less accepting
691 * of underscore-prefixed names. So let's list the lowest
692 * expected return value. */
693 assert_se(r
>= expected
);
695 assert_se(dns_name_equal(buf
, result
) == 1);
698 TEST(dns_name_apply_idna
) {
699 const int ret
= HAVE_LIBIDN2
| HAVE_LIBIDN
;
701 /* IDNA2008 forbids names with hyphens in third and fourth positions
702 * (https://tools.ietf.org/html/rfc5891#section-4.2.3.1).
703 * IDNA2003 does not have this restriction
704 * (https://tools.ietf.org/html/rfc3490#section-5).
705 * This means that when using libidn we will transform and test more
706 * labels. If registrars follow IDNA2008 we'll just be performing a
709 const int ret2
= HAVE_LIBIDN
;
711 test_dns_name_apply_idna_one("", ret
, "");
712 test_dns_name_apply_idna_one("foo", ret
, "foo");
713 test_dns_name_apply_idna_one("foo.", ret
, "foo");
714 test_dns_name_apply_idna_one("foo.bar", ret
, "foo.bar");
715 test_dns_name_apply_idna_one("foo.bar.", ret
, "foo.bar");
716 test_dns_name_apply_idna_one("föö", ret
, "xn--f-1gaa");
717 test_dns_name_apply_idna_one("föö.", ret
, "xn--f-1gaa");
718 test_dns_name_apply_idna_one("föö.bär", ret
, "xn--f-1gaa.xn--br-via");
719 test_dns_name_apply_idna_one("föö.bär.", ret
, "xn--f-1gaa.xn--br-via");
720 test_dns_name_apply_idna_one("xn--f-1gaa.xn--br-via", ret
, "xn--f-1gaa.xn--br-via");
722 test_dns_name_apply_idna_one("_443._tcp.fedoraproject.org", ret2
,
723 "_443._tcp.fedoraproject.org");
724 test_dns_name_apply_idna_one("_443", ret2
, "_443");
725 test_dns_name_apply_idna_one("gateway", ret
, "gateway");
726 test_dns_name_apply_idna_one("_gateway", ret2
, "_gateway");
728 test_dns_name_apply_idna_one("r3---sn-ab5l6ne7.googlevideo.com", ret2
,
729 ret2
? "r3---sn-ab5l6ne7.googlevideo.com" : "");
732 TEST(dns_name_is_valid_or_address
) {
733 assert_se(dns_name_is_valid_or_address(NULL
) == 0);
734 assert_se(dns_name_is_valid_or_address("") == 0);
735 assert_se(dns_name_is_valid_or_address("foobar") > 0);
736 assert_se(dns_name_is_valid_or_address("foobar.com") > 0);
737 assert_se(dns_name_is_valid_or_address("foobar..com") == 0);
738 assert_se(dns_name_is_valid_or_address("foobar.com.") > 0);
739 assert_se(dns_name_is_valid_or_address("127.0.0.1") > 0);
740 assert_se(dns_name_is_valid_or_address("::") > 0);
741 assert_se(dns_name_is_valid_or_address("::1") > 0);
744 TEST(dns_name_dot_suffixed
) {
745 assert_se(dns_name_dot_suffixed("") == 0);
746 assert_se(dns_name_dot_suffixed(".") > 0);
747 assert_se(dns_name_dot_suffixed("foo") == 0);
748 assert_se(dns_name_dot_suffixed("foo.") > 0);
749 assert_se(dns_name_dot_suffixed("foo\\..") > 0);
750 assert_se(dns_name_dot_suffixed("foo\\.") == 0);
751 assert_se(dns_name_dot_suffixed("foo.bar.") > 0);
752 assert_se(dns_name_dot_suffixed("foo.bar\\.\\.\\..") > 0);
753 assert_se(dns_name_dot_suffixed("foo.bar\\.\\.\\.\\.") == 0);
756 DEFINE_TEST_MAIN(LOG_DEBUG
);