]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-dns-domain.c
shared: add new dns_name_startswith() call
[thirdparty/systemd.git] / src / test / test-dns-domain.c
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
22 #include "alloc-util.h"
23 #include "dns-domain.h"
24 #include "macro.h"
25 #include "string-util.h"
26
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];
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
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);
53 }
54
55 static void test_dns_name_to_wire_format_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
56 uint8_t buffer[buffer_sz];
57 int r;
58
59 r = dns_name_to_wire_format(what, buffer, buffer_sz, false);
60 assert_se(r == ret);
61
62 if (r < 0)
63 return;
64
65 assert_se(!memcmp(buffer, expect, r));
66 }
67
68 static void test_dns_name_to_wire_format(void) {
69 static const char out0[] = { 0 };
70 static const char out1[] = { 3, 'f', 'o', 'o', 0 };
71 static const char out2[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
72 static const char out3[] = { 4, ' ', 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
73 static const char out4[] = { 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
74 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
75 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
76 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
77 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
78 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
79 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
80 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
81 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
82 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
83 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
84 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
85 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
86 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
87 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
88 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
89 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
90 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
91 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
92 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
93 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
94 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
95 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
96 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
97 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
98 3, 'a', '1', '2', 0 };
99
100 test_dns_name_to_wire_format_one("", out0, sizeof(out0), sizeof(out0));
101
102 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1), sizeof(out1));
103 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1) + 1, sizeof(out1));
104 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1) - 1, -ENOBUFS);
105
106 test_dns_name_to_wire_format_one("hallo.foo.bar", out2, sizeof(out2), sizeof(out2));
107 test_dns_name_to_wire_format_one("hallo.foo..bar", NULL, 32, -EINVAL);
108
109 test_dns_name_to_wire_format_one("\\032foo.bar", out3, sizeof(out3), sizeof(out3));
110
111 test_dns_name_to_wire_format_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a123", NULL, 500, -EINVAL);
112 test_dns_name_to_wire_format_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12", out4, sizeof(out4), sizeof(out4));
113 }
114
115 static void test_dns_label_unescape_suffix_one(const char *what, const char *expect1, const char *expect2, size_t buffer_sz, int ret1, int ret2) {
116 char buffer[buffer_sz];
117 const char *label;
118 int r;
119
120 label = what + strlen(what);
121
122 r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz);
123 assert_se(r == ret1);
124 if (r >= 0)
125 assert_se(streq(buffer, expect1));
126
127 r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz);
128 assert_se(r == ret2);
129 if (r >= 0)
130 assert_se(streq(buffer, expect2));
131 }
132
133 static void test_dns_label_unescape_suffix(void) {
134 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 6, 5, 0);
135 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOBUFS, -ENOBUFS);
136 test_dns_label_unescape_suffix_one("", "", "", 10, 0, 0);
137 test_dns_label_unescape_suffix_one("hallo\\.foobar", "hallo.foobar", "", 20, 12, 0);
138 test_dns_label_unescape_suffix_one("hallo.foobar", "foobar", "hallo", 10, 6, 5);
139 test_dns_label_unescape_suffix_one("hallo.foobar\n", "foobar", "foobar", 20, -EINVAL, -EINVAL);
140 test_dns_label_unescape_suffix_one("hallo\\", "hallo", "hallo", 20, -EINVAL, -EINVAL);
141 test_dns_label_unescape_suffix_one("hallo\\032 ", "hallo ", "", 20, 7, 0);
142 test_dns_label_unescape_suffix_one(".", "", "", 20, 0, 0);
143 test_dns_label_unescape_suffix_one("..", "", "", 20, 0, -EINVAL);
144 test_dns_label_unescape_suffix_one(".foobar", "foobar", "", 20, 6, -EINVAL);
145 test_dns_label_unescape_suffix_one("foobar.", "foobar", "", 20, 6, 0);
146 test_dns_label_unescape_suffix_one("foo\\\\bar", "foo\\bar", "", 20, 7, 0);
147 test_dns_label_unescape_suffix_one("foo.bar", "bar", "foo", 20, 3, 3);
148 test_dns_label_unescape_suffix_one("foo..bar", "bar", "", 20, 3, -EINVAL);
149 test_dns_label_unescape_suffix_one("foo...bar", "bar", "", 20, 3, -EINVAL);
150 test_dns_label_unescape_suffix_one("foo\\.bar", "foo.bar", "", 20, 7, 0);
151 test_dns_label_unescape_suffix_one("foo\\\\.bar", "bar", "foo\\", 20, 3, 4);
152 test_dns_label_unescape_suffix_one("foo\\\\\\.bar", "foo\\.bar", "", 20, 8, 0);
153 }
154
155 static void test_dns_label_escape_one(const char *what, size_t l, const char *expect, int ret) {
156 _cleanup_free_ char *t = NULL;
157 int r;
158
159 r = dns_label_escape_new(what, l, &t);
160 assert_se(r == ret);
161
162 if (r < 0)
163 return;
164
165 assert_se(streq_ptr(expect, t));
166 }
167
168 static void test_dns_label_escape(void) {
169 test_dns_label_escape_one("", 0, NULL, -EINVAL);
170 test_dns_label_escape_one("hallo", 5, "hallo", 5);
171 test_dns_label_escape_one("hallo", 6, "hallo\\000", 9);
172 test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
173 }
174
175 static void test_dns_name_normalize_one(const char *what, const char *expect, int ret) {
176 _cleanup_free_ char *t = NULL;
177 int r;
178
179 r = dns_name_normalize(what, &t);
180 assert_se(r == ret);
181
182 if (r < 0)
183 return;
184
185 assert_se(streq_ptr(expect, t));
186 }
187
188 static void test_dns_name_normalize(void) {
189 test_dns_name_normalize_one("", "", 0);
190 test_dns_name_normalize_one("f", "f", 0);
191 test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
192 test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
193 test_dns_name_normalize_one("\\000", "\\000", 0);
194 test_dns_name_normalize_one("..", NULL, -EINVAL);
195 test_dns_name_normalize_one(".foobar", NULL, -EINVAL);
196 test_dns_name_normalize_one("foobar.", "foobar", 0);
197 test_dns_name_normalize_one(".", "", 0);
198 }
199
200 static void test_dns_name_equal_one(const char *a, const char *b, int ret) {
201 int r;
202
203 r = dns_name_equal(a, b);
204 assert_se(r == ret);
205
206 r = dns_name_equal(b, a);
207 assert_se(r == ret);
208 }
209
210 static void test_dns_name_equal(void) {
211 test_dns_name_equal_one("", "", true);
212 test_dns_name_equal_one("x", "x", true);
213 test_dns_name_equal_one("x", "x.", true);
214 test_dns_name_equal_one("abc.def", "abc.def", true);
215 test_dns_name_equal_one("abc.def", "ABC.def", true);
216 test_dns_name_equal_one("abc.def", "CBA.def", false);
217 test_dns_name_equal_one("", "xxx", false);
218 test_dns_name_equal_one("ab", "a", false);
219 test_dns_name_equal_one("\\000", "\\000", true);
220 test_dns_name_equal_one(".", "", true);
221 test_dns_name_equal_one(".", ".", true);
222 test_dns_name_equal_one("..", "..", -EINVAL);
223 }
224
225 static void test_dns_name_between_one(const char *a, const char *b, const char *c, int ret) {
226 int r;
227
228 r = dns_name_between(a, b, c);
229 assert_se(r == ret);
230
231 r = dns_name_between(c, b, a);
232 if (ret >= 0)
233 assert_se(r == 0);
234 else
235 assert_se(r == ret);
236 }
237
238 static void test_dns_name_between(void) {
239 /* see https://tools.ietf.org/html/rfc4034#section-6.1
240 Note that we use "\033.z.example" in stead of "\001.z.example" as we
241 consider the latter invalid */
242 test_dns_name_between_one("example", "a.example", "yljkjljk.a.example", true);
243 test_dns_name_between_one("a.example", "yljkjljk.a.example", "Z.a.example", true);
244 test_dns_name_between_one("yljkjljk.a.example", "Z.a.example", "zABC.a.EXAMPLE", true);
245 test_dns_name_between_one("Z.a.example", "zABC.a.EXAMPLE", "z.example", true);
246 test_dns_name_between_one("zABC.a.EXAMPLE", "z.example", "\\033.z.example", true);
247 test_dns_name_between_one("z.example", "\\033.z.example", "*.z.example", true);
248 test_dns_name_between_one("\\033.z.example", "*.z.example", "\\200.z.example", true);
249 test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
250 test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
251
252 test_dns_name_between_one("example", "a.example", "example", -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
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);
259 }
260
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);
277 }
278
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);
281 }
282
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);
296 }
297
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(".."));
304 }
305
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"));
313 }
314
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;
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
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");
333 }
334
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;
337
338 assert_se(dns_name_concat(a, b, &p) == r);
339 assert_se(streq_ptr(p, result));
340 }
341
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");
347 }
348
349 static void test_dns_name_is_valid_one(const char *s, int ret) {
350 assert_se(dns_name_is_valid(s) == ret);
351 }
352
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);
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);
384 }
385
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"));
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
397 static 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"));
418 }
419
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;
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
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);
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
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;
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
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);
476 }
477
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;
480
481 assert_se(dns_name_change_suffix(name, old_suffix, new_suffix, &s) == r);
482 assert_se(streq_ptr(s, result));
483 }
484
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);
495 }
496
497 static 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
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);
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
521 static void test_dns_name_count_labels_one(const char *name, int n) {
522 assert_se(dns_name_count_labels(name) == n);
523 }
524
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);
535 }
536
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);
539 }
540
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);
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
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);
577
578 assert_se(dns_name_compare_func("de.", "heise.de") != 0);
579 }
580
581 int main(int argc, char *argv[]) {
582
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();
606
607 return 0;
608 }