]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-dns-domain.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
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.
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.
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/>.
22 #include "alloc-util.h"
23 #include "dns-domain.h"
25 #include "string-util.h"
27 static void test_dns_label_unescape_one(const char *what
, const char *expect
, size_t buffer_sz
, int ret
) {
28 char buffer
[buffer_sz
];
31 r
= dns_label_unescape(&what
, buffer
, buffer_sz
);
37 assert_se(streq(buffer
, expect
));
40 static void test_dns_label_unescape(void) {
41 test_dns_label_unescape_one("hallo", "hallo", 6, 5);
42 test_dns_label_unescape_one("hallo", "hallo", 4, -ENOBUFS
);
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);
55 static void test_dns_name_to_wire_format_one(const char *what
, const char *expect
, size_t buffer_sz
, int ret
) {
56 uint8_t buffer
[buffer_sz
];
59 r
= dns_name_to_wire_format(what
, buffer
, buffer_sz
, false);
65 assert_se(!memcmp(buffer
, expect
, r
));
68 static void test_dns_name_to_wire_format(void) {
69 static const char out0
[] = { 0 };
70 static const char out1
[] = { 3, 'f', 'o', 'o', 0 };
71 static const char out2
[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
72 static const char out3
[] = { 4, ' ', 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
73 static const char out4
[] = { 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
74 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
75 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
76 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
77 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
78 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
79 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
80 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
81 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
82 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
83 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
84 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
85 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
86 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
87 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
88 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
89 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
90 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
91 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
92 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
93 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
94 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
95 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
96 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
97 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
98 3, 'a', '1', '2', 0 };
100 test_dns_name_to_wire_format_one("", out0
, sizeof(out0
), sizeof(out0
));
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
);
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
);
109 test_dns_name_to_wire_format_one("\\032foo.bar", out3
, sizeof(out3
), sizeof(out3
));
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
));
115 static void test_dns_label_unescape_suffix_one(const char *what
, const char *expect1
, const char *expect2
, size_t buffer_sz
, int ret1
, int ret2
) {
116 char buffer
[buffer_sz
];
120 label
= what
+ strlen(what
);
122 r
= dns_label_unescape_suffix(what
, &label
, buffer
, buffer_sz
);
123 assert_se(r
== ret1
);
125 assert_se(streq(buffer
, expect1
));
127 r
= dns_label_unescape_suffix(what
, &label
, buffer
, buffer_sz
);
128 assert_se(r
== ret2
);
130 assert_se(streq(buffer
, expect2
));
133 static void test_dns_label_unescape_suffix(void) {
134 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 6, 5, 0);
135 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOBUFS
, -ENOBUFS
);
136 test_dns_label_unescape_suffix_one("", "", "", 10, 0, 0);
137 test_dns_label_unescape_suffix_one("hallo\\.foobar", "hallo.foobar", "", 20, 12, 0);
138 test_dns_label_unescape_suffix_one("hallo.foobar", "foobar", "hallo", 10, 6, 5);
139 test_dns_label_unescape_suffix_one("hallo.foobar\n", "foobar", "foobar", 20, -EINVAL
, -EINVAL
);
140 test_dns_label_unescape_suffix_one("hallo\\", "hallo", "hallo", 20, -EINVAL
, -EINVAL
);
141 test_dns_label_unescape_suffix_one("hallo\\032 ", "hallo ", "", 20, 7, 0);
142 test_dns_label_unescape_suffix_one(".", "", "", 20, 0, 0);
143 test_dns_label_unescape_suffix_one("..", "", "", 20, 0, -EINVAL
);
144 test_dns_label_unescape_suffix_one(".foobar", "foobar", "", 20, 6, -EINVAL
);
145 test_dns_label_unescape_suffix_one("foobar.", "foobar", "", 20, 6, 0);
146 test_dns_label_unescape_suffix_one("foo\\\\bar", "foo\\bar", "", 20, 7, 0);
147 test_dns_label_unescape_suffix_one("foo.bar", "bar", "foo", 20, 3, 3);
148 test_dns_label_unescape_suffix_one("foo..bar", "bar", "", 20, 3, -EINVAL
);
149 test_dns_label_unescape_suffix_one("foo...bar", "bar", "", 20, 3, -EINVAL
);
150 test_dns_label_unescape_suffix_one("foo\\.bar", "foo.bar", "", 20, 7, 0);
151 test_dns_label_unescape_suffix_one("foo\\\\.bar", "bar", "foo\\", 20, 3, 4);
152 test_dns_label_unescape_suffix_one("foo\\\\\\.bar", "foo\\.bar", "", 20, 8, 0);
155 static void test_dns_label_escape_one(const char *what
, size_t l
, const char *expect
, int ret
) {
156 _cleanup_free_
char *t
= NULL
;
159 r
= dns_label_escape_new(what
, l
, &t
);
165 assert_se(streq_ptr(expect
, t
));
168 static void test_dns_label_escape(void) {
169 test_dns_label_escape_one("", 0, NULL
, -EINVAL
);
170 test_dns_label_escape_one("hallo", 5, "hallo", 5);
171 test_dns_label_escape_one("hallo", 6, "hallo\\000", 9);
172 test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
175 static void test_dns_name_normalize_one(const char *what
, const char *expect
, int ret
) {
176 _cleanup_free_
char *t
= NULL
;
179 r
= dns_name_normalize(what
, &t
);
185 assert_se(streq_ptr(expect
, t
));
188 static void test_dns_name_normalize(void) {
189 test_dns_name_normalize_one("", "", 0);
190 test_dns_name_normalize_one("f", "f", 0);
191 test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
192 test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
193 test_dns_name_normalize_one("\\000", "\\000", 0);
194 test_dns_name_normalize_one("..", NULL
, -EINVAL
);
195 test_dns_name_normalize_one(".foobar", NULL
, -EINVAL
);
196 test_dns_name_normalize_one("foobar.", "foobar", 0);
197 test_dns_name_normalize_one(".", "", 0);
200 static void test_dns_name_equal_one(const char *a
, const char *b
, int ret
) {
203 r
= dns_name_equal(a
, b
);
206 r
= dns_name_equal(b
, a
);
210 static void test_dns_name_equal(void) {
211 test_dns_name_equal_one("", "", true);
212 test_dns_name_equal_one("x", "x", true);
213 test_dns_name_equal_one("x", "x.", true);
214 test_dns_name_equal_one("abc.def", "abc.def", true);
215 test_dns_name_equal_one("abc.def", "ABC.def", true);
216 test_dns_name_equal_one("abc.def", "CBA.def", false);
217 test_dns_name_equal_one("", "xxx", false);
218 test_dns_name_equal_one("ab", "a", false);
219 test_dns_name_equal_one("\\000", "\\000", true);
220 test_dns_name_equal_one(".", "", true);
221 test_dns_name_equal_one(".", ".", true);
222 test_dns_name_equal_one("..", "..", -EINVAL
);
225 static void test_dns_name_between_one(const char *a
, const char *b
, const char *c
, int ret
) {
228 r
= dns_name_between(a
, b
, c
);
231 r
= dns_name_between(c
, b
, a
);
238 static void test_dns_name_between(void) {
239 /* see https://tools.ietf.org/html/rfc4034#section-6.1
240 Note that we use "\033.z.example" in stead of "\001.z.example" as we
241 consider the latter invalid */
242 test_dns_name_between_one("example", "a.example", "yljkjljk.a.example", true);
243 test_dns_name_between_one("a.example", "yljkjljk.a.example", "Z.a.example", true);
244 test_dns_name_between_one("yljkjljk.a.example", "Z.a.example", "zABC.a.EXAMPLE", true);
245 test_dns_name_between_one("Z.a.example", "zABC.a.EXAMPLE", "z.example", true);
246 test_dns_name_between_one("zABC.a.EXAMPLE", "z.example", "\\033.z.example", true);
247 test_dns_name_between_one("z.example", "\\033.z.example", "*.z.example", true);
248 test_dns_name_between_one("\\033.z.example", "*.z.example", "\\200.z.example", true);
249 test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
250 test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
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);
257 static void test_dns_name_endswith_one(const char *a
, const char *b
, int ret
) {
258 assert_se(dns_name_endswith(a
, b
) == ret
);
261 static 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
);
279 static void test_dns_name_startswith_one(const char *a
, const char *b
, int ret
) {
280 assert_se(dns_name_startswith(a
, b
) == ret
);
283 static 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);
298 static 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(".."));
306 static 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"));
315 static void test_dns_name_reverse_one(const char *address
, const char *name
) {
316 _cleanup_free_
char *p
= NULL
;
317 union in_addr_union a
, b
= {};
318 int familya
, familyb
;
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
));
328 static 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");
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");
335 static void test_dns_name_concat_one(const char *a
, const char *b
, int r
, const char *result
) {
336 _cleanup_free_
char *p
= NULL
;
338 assert_se(dns_name_concat(a
, b
, &p
) == r
);
339 assert_se(streq_ptr(p
, result
));
342 static 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");
349 static void test_dns_name_is_valid_one(const char *s
, int ret
) {
350 assert_se(dns_name_is_valid(s
) == ret
);
353 static 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);
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);
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);
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);
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);
379 /* label of 64 chars length */
380 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a123", 0);
382 /* label of 63 chars length */
383 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a12", 1);
386 static 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"));
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"));
397 static void test_dns_srv_type_is_valid(void) {
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"));
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"));
420 static 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
;
423 assert_se(dns_service_join(a
, b
, c
, &t
) == r
);
424 assert_se(streq_ptr(t
, d
));
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
));
435 static 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
);
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");
450 static 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
;
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
));
462 assert_se(dns_service_join(x
, y
, z
, &t
) == 0);
463 assert_se(streq_ptr(joined
, t
));
465 assert_se(!x
&& streq_ptr(z
, joined
));
468 static 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);
478 static 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
;
481 assert_se(dns_name_change_suffix(name
, old_suffix
, new_suffix
, &s
) == r
);
482 assert_se(streq_ptr(s
, result
));
485 static 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
);
497 static void test_dns_name_suffix_one(const char *name
, unsigned n_labels
, const char *result
, int ret
) {
498 const char *p
= NULL
;
500 assert_se(ret
== dns_name_suffix(name
, n_labels
, &p
));
501 assert_se(streq_ptr(p
, result
));
504 static 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
);
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
);
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
);
521 static void test_dns_name_count_labels_one(const char *name
, int n
) {
522 assert_se(dns_name_count_labels(name
) == n
);
525 static 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
);
537 static 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
);
541 static 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);
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);
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);
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);
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);
568 static 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);
578 assert_se(dns_name_compare_func("de.", "heise.de") != 0);
581 int main(int argc
, char *argv
[]) {
583 test_dns_label_unescape();
584 test_dns_label_unescape_suffix();
585 test_dns_label_escape();
586 test_dns_name_normalize();
587 test_dns_name_equal();
588 test_dns_name_endswith();
589 test_dns_name_startswith();
590 test_dns_name_between();
591 test_dns_name_is_root();
592 test_dns_name_is_single_label();
593 test_dns_name_reverse();
594 test_dns_name_concat();
595 test_dns_name_is_valid();
596 test_dns_name_to_wire_format();
597 test_dns_service_name_is_valid();
598 test_dns_srv_type_is_valid();
599 test_dns_service_join();
600 test_dns_service_split();
601 test_dns_name_change_suffix();
602 test_dns_name_suffix();
603 test_dns_name_count_labels();
604 test_dns_name_equal_skip();
605 test_dns_name_compare_func();