]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-dns-domain.c
Merge pull request #2068 from grawity/cgls-error-v2
[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);
42 test_dns_label_unescape_one("hallo", "hallo", 4, -ENOSPC);
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
59 r = dns_name_to_wire_format(what, buffer, buffer_sz);
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) {
69 const char out1[] = { 3, 'f', 'o', 'o', 0 };
70 const char out2[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
71 const char out3[] = { 4, ' ', 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
72
73 test_dns_name_to_wire_format_one("", NULL, 0, -EINVAL);
74
75 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1), sizeof(out1));
76 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1) + 1, sizeof(out1));
77 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1) - 1, -ENOBUFS);
78
79 test_dns_name_to_wire_format_one("hallo.foo.bar", out2, sizeof(out2), sizeof(out2));
80 test_dns_name_to_wire_format_one("hallo.foo..bar", NULL, 32, -EINVAL);
81
82 test_dns_name_to_wire_format_one("\\032foo.bar", out3, sizeof(out3), sizeof(out3));
83}
84
642900d3
TG
85static void test_dns_label_unescape_suffix_one(const char *what, const char *expect1, const char *expect2, size_t buffer_sz, int ret1, int ret2) {
86 char buffer[buffer_sz];
87 const char *label;
88 int r;
89
90 label = what + strlen(what);
91
92 r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz);
93 assert_se(r == ret1);
94 if (r >= 0)
95 assert_se(streq(buffer, expect1));
96
97 r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz);
98 assert_se(r == ret2);
99 if (r >= 0)
100 assert_se(streq(buffer, expect2));
101}
102
103static void test_dns_label_unescape_suffix(void) {
104 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 6, 5, 0);
105 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOSPC, -ENOSPC);
106 test_dns_label_unescape_suffix_one("", "", "", 10, 0, 0);
107 test_dns_label_unescape_suffix_one("hallo\\.foobar", "hallo.foobar", "", 20, 12, 0);
108 test_dns_label_unescape_suffix_one("hallo.foobar", "foobar", "hallo", 10, 6, 5);
109 test_dns_label_unescape_suffix_one("hallo.foobar\n", "foobar", "foobar", 20, -EINVAL, -EINVAL);
110 test_dns_label_unescape_suffix_one("hallo\\", "hallo", "hallo", 20, -EINVAL, -EINVAL);
111 test_dns_label_unescape_suffix_one("hallo\\032 ", "hallo ", "", 20, 7, 0);
112 test_dns_label_unescape_suffix_one(".", "", "", 20, 0, 0);
113 test_dns_label_unescape_suffix_one("..", "", "", 20, 0, 0);
114 test_dns_label_unescape_suffix_one(".foobar", "foobar", "", 20, 6, -EINVAL);
115 test_dns_label_unescape_suffix_one("foobar.", "", "foobar", 20, 0, 6);
116 test_dns_label_unescape_suffix_one("foo\\\\bar", "foo\\bar", "", 20, 7, 0);
117 test_dns_label_unescape_suffix_one("foo.bar", "bar", "foo", 20, 3, 3);
118 test_dns_label_unescape_suffix_one("foo..bar", "bar", "", 20, 3, -EINVAL);
119 test_dns_label_unescape_suffix_one("foo...bar", "bar", "", 20, 3, -EINVAL);
120 test_dns_label_unescape_suffix_one("foo\\.bar", "foo.bar", "", 20, 7, 0);
121 test_dns_label_unescape_suffix_one("foo\\\\.bar", "bar", "foo\\", 20, 3, 4);
122 test_dns_label_unescape_suffix_one("foo\\\\\\.bar", "foo\\.bar", "", 20, 8, 0);
123}
124
74b2466e
LP
125static void test_dns_label_escape_one(const char *what, size_t l, const char *expect, int ret) {
126 _cleanup_free_ char *t = NULL;
127 int r;
128
422baca0 129 r = dns_label_escape_new(what, l, &t);
0c0cdb06 130 assert_se(r == ret);
74b2466e
LP
131
132 if (r < 0)
133 return;
134
135 assert_se(streq_ptr(expect, t));
136}
137
138static void test_dns_label_escape(void) {
139 test_dns_label_escape_one("", 0, "", 0);
140 test_dns_label_escape_one("hallo", 5, "hallo", 5);
141 test_dns_label_escape_one("hallo", 6, NULL, -EINVAL);
142 test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
143}
144
145static void test_dns_name_normalize_one(const char *what, const char *expect, int ret) {
146 _cleanup_free_ char *t = NULL;
147 int r;
148
149 r = dns_name_normalize(what, &t);
150 assert_se(r == ret);
151
152 if (r < 0)
153 return;
154
155 assert_se(streq_ptr(expect, t));
156}
157
158static void test_dns_name_normalize(void) {
159 test_dns_name_normalize_one("", "", 0);
160 test_dns_name_normalize_one("f", "f", 0);
161 test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
162 test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
163 test_dns_name_normalize_one("\\000", NULL, -EINVAL);
164 test_dns_name_normalize_one("..", NULL, -EINVAL);
165 test_dns_name_normalize_one(".foobar", NULL, -EINVAL);
166 test_dns_name_normalize_one("foobar.", "foobar", 0);
167 test_dns_name_normalize_one(".", "", 0);
168}
169
170static void test_dns_name_equal_one(const char *a, const char *b, int ret) {
171 int r;
172
173 r = dns_name_equal(a, b);
174 assert_se(r == ret);
175
176 r = dns_name_equal(b, a);
177 assert_se(r == ret);
178}
179
180static void test_dns_name_equal(void) {
181 test_dns_name_equal_one("", "", true);
182 test_dns_name_equal_one("x", "x", true);
183 test_dns_name_equal_one("x", "x.", true);
184 test_dns_name_equal_one("abc.def", "abc.def", true);
185 test_dns_name_equal_one("abc.def", "ABC.def", true);
186 test_dns_name_equal_one("abc.def", "CBA.def", false);
187 test_dns_name_equal_one("", "xxx", false);
188 test_dns_name_equal_one("ab", "a", false);
189 test_dns_name_equal_one("\\000", "xxxx", -EINVAL);
190 test_dns_name_equal_one(".", "", true);
191 test_dns_name_equal_one(".", ".", true);
192 test_dns_name_equal_one("..", "..", -EINVAL);
193}
194
ae72b22c
TG
195static void test_dns_name_between_one(const char *a, const char *b, const char *c, int ret) {
196 int r;
197
198 r = dns_name_between(a, b, c);
199 assert_se(r == ret);
200
201 r = dns_name_between(c, b, a);
202 if (ret >= 0)
203 assert_se(r == 0);
204 else
205 assert_se(r == ret);
206}
207
208static void test_dns_name_between(void) {
209 /* see https://tools.ietf.org/html/rfc4034#section-6.1
210 Note that we use "\033.z.example" in stead of "\001.z.example" as we
211 consider the latter invalid */
212 test_dns_name_between_one("example", "a.example", "yljkjljk.a.example", true);
213 test_dns_name_between_one("a.example", "yljkjljk.a.example", "Z.a.example", true);
214 test_dns_name_between_one("yljkjljk.a.example", "Z.a.example", "zABC.a.EXAMPLE", true);
215 test_dns_name_between_one("Z.a.example", "zABC.a.EXAMPLE", "z.example", true);
216 test_dns_name_between_one("zABC.a.EXAMPLE", "z.example", "\\033.z.example", true);
217 test_dns_name_between_one("z.example", "\\033.z.example", "*.z.example", true);
218 test_dns_name_between_one("\\033.z.example", "*.z.example", "\\200.z.example", true);
219 test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
220 test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
221
222 test_dns_name_between_one("example", "a.example", "example", -EINVAL);
223 test_dns_name_between_one("example", "example", "yljkjljk.a.example", false);
224 test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false);
225}
226
74b2466e
LP
227static void test_dns_name_endswith_one(const char *a, const char *b, int ret) {
228 assert_se(dns_name_endswith(a, b) == ret);
229}
230
231static void test_dns_name_endswith(void) {
232 test_dns_name_endswith_one("", "", true);
233 test_dns_name_endswith_one("", "xxx", false);
234 test_dns_name_endswith_one("xxx", "", true);
235 test_dns_name_endswith_one("x", "x", true);
236 test_dns_name_endswith_one("x", "y", false);
237 test_dns_name_endswith_one("x.y", "y", true);
238 test_dns_name_endswith_one("x.y", "Y", true);
239 test_dns_name_endswith_one("x.y", "x", false);
240 test_dns_name_endswith_one("x.y.z", "Z", true);
241 test_dns_name_endswith_one("x.y.z", "y.Z", true);
242 test_dns_name_endswith_one("x.y.z", "x.y.Z", true);
243 test_dns_name_endswith_one("x.y.z", "waldo", false);
244 test_dns_name_endswith_one("x.y.z.u.v.w", "y.z", false);
245 test_dns_name_endswith_one("x.y.z.u.v.w", "u.v.w", true);
246 test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL);
247}
248
dc477e73
LP
249static void test_dns_name_is_root(void) {
250 assert_se(dns_name_is_root(""));
251 assert_se(dns_name_is_root("."));
252 assert_se(!dns_name_is_root("xxx"));
253 assert_se(!dns_name_is_root("xxx."));
254 assert_se(!dns_name_is_root(".."));
74b2466e
LP
255}
256
dc477e73
LP
257static void test_dns_name_is_single_label(void) {
258 assert_se(!dns_name_is_single_label(""));
259 assert_se(!dns_name_is_single_label("."));
260 assert_se(!dns_name_is_single_label(".."));
261 assert_se(dns_name_is_single_label("x"));
262 assert_se(dns_name_is_single_label("x."));
263 assert_se(!dns_name_is_single_label("xx.yy"));
74b2466e
LP
264}
265
b914e211
LP
266static void test_dns_name_reverse_one(const char *address, const char *name) {
267 _cleanup_free_ char *p = NULL;
a7f7d1bd 268 union in_addr_union a, b = {};
b914e211
LP
269 int familya, familyb;
270
271 assert_se(in_addr_from_string_auto(address, &familya, &a) >= 0);
272 assert_se(dns_name_reverse(familya, &a, &p) >= 0);
273 assert_se(streq(p, name));
274 assert_se(dns_name_address(p, &familyb, &b) > 0);
275 assert_se(familya == familyb);
276 assert_se(in_addr_equal(familya, &a, &b));
277}
278
279static void test_dns_name_reverse(void) {
280 test_dns_name_reverse_one("47.11.8.15", "15.8.11.47.in-addr.arpa");
281 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
282 test_dns_name_reverse_one("127.0.0.1", "1.0.0.127.in-addr.arpa");
283 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
284}
285
9ca45586
LP
286static void test_dns_name_concat_one(const char *a, const char *b, int r, const char *result) {
287 _cleanup_free_ char *p = NULL;
288
289 assert_se(dns_name_concat(a, b, &p) == r);
290 assert_se(streq_ptr(p, result));
291}
292
293static void test_dns_name_concat(void) {
294 test_dns_name_concat_one("foo", "bar", 0, "foo.bar");
295 test_dns_name_concat_one("foo.foo", "bar.bar", 0, "foo.foo.bar.bar");
296 test_dns_name_concat_one("foo", NULL, 0, "foo");
297 test_dns_name_concat_one("foo.", "bar.", 0, "foo.bar");
298}
299
300static void test_dns_name_is_valid_one(const char *s, int ret) {
301 assert_se(dns_name_is_valid(s) == ret);
302}
303
304static void test_dns_name_is_valid(void) {
305 test_dns_name_is_valid_one("foo", 1);
306 test_dns_name_is_valid_one("foo.", 1);
307 test_dns_name_is_valid_one("Foo", 1);
308 test_dns_name_is_valid_one("foo.bar", 1);
309 test_dns_name_is_valid_one("foo.bar.baz", 1);
310 test_dns_name_is_valid_one("", 1);
311 test_dns_name_is_valid_one("foo..bar", 0);
312 test_dns_name_is_valid_one(".foo.bar", 0);
313 test_dns_name_is_valid_one("foo.bar.", 1);
314 test_dns_name_is_valid_one("\\zbar", 0);
315 test_dns_name_is_valid_one("ä", 1);
316 test_dns_name_is_valid_one("\n", 0);
317}
318
0a49b6b6
LP
319static void test_dns_service_name_is_valid(void) {
320 assert_se(dns_service_name_is_valid("Lennart's Compüter"));
321 assert_se(dns_service_name_is_valid("piff.paff"));
322
323 assert_se(!dns_service_name_is_valid(NULL));
324 assert_se(!dns_service_name_is_valid(""));
325 assert_se(!dns_service_name_is_valid("foo\nbar"));
326 assert_se(!dns_service_name_is_valid("foo\201bar"));
327 assert_se(!dns_service_name_is_valid("this is an overly long string that is certainly longer than 63 characters"));
328}
329
7e8131e9
LP
330static void test_dns_srv_type_is_valid(void) {
331
332 assert_se(dns_srv_type_is_valid("_http._tcp"));
333 assert_se(dns_srv_type_is_valid("_foo-bar._tcp"));
334 assert_se(dns_srv_type_is_valid("_w._udp"));
335 assert_se(dns_srv_type_is_valid("_a800._tcp"));
336 assert_se(dns_srv_type_is_valid("_a-800._tcp"));
337
338 assert_se(!dns_srv_type_is_valid(NULL));
339 assert_se(!dns_srv_type_is_valid(""));
340 assert_se(!dns_srv_type_is_valid("x"));
341 assert_se(!dns_srv_type_is_valid("_foo"));
342 assert_se(!dns_srv_type_is_valid("_tcp"));
343 assert_se(!dns_srv_type_is_valid("_"));
344 assert_se(!dns_srv_type_is_valid("_foo."));
345 assert_se(!dns_srv_type_is_valid("_föo._tcp"));
346 assert_se(!dns_srv_type_is_valid("_f\no._tcp"));
347 assert_se(!dns_srv_type_is_valid("_800._tcp"));
348 assert_se(!dns_srv_type_is_valid("_-800._tcp"));
349 assert_se(!dns_srv_type_is_valid("_-foo._tcp"));
350 assert_se(!dns_srv_type_is_valid("_piep._foo._udp"));
0e8eedbb
LP
351}
352
353static void test_dns_service_join_one(const char *a, const char *b, const char *c, int r, const char *d) {
354 _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *t = NULL;
355
356 assert_se(dns_service_join(a, b, c, &t) == r);
357 assert_se(streq_ptr(t, d));
358
359 if (r < 0)
360 return;
361
362 assert_se(dns_service_split(t, &x, &y, &z) >= 0);
363 assert_se(streq_ptr(a, x));
364 assert_se(streq_ptr(b, y));
365 assert_se(streq_ptr(c, z));
366}
367
368static void test_dns_service_join(void) {
369 test_dns_service_join_one("", "", "", -EINVAL, NULL);
370 test_dns_service_join_one("", "_http._tcp", "", -EINVAL, NULL);
371 test_dns_service_join_one("", "_http._tcp", "foo", -EINVAL, NULL);
372 test_dns_service_join_one("foo", "", "foo", -EINVAL, NULL);
373 test_dns_service_join_one("foo", "foo", "foo", -EINVAL, NULL);
374
375 test_dns_service_join_one("foo", "_http._tcp", "", 0, "foo._http._tcp");
376 test_dns_service_join_one(NULL, "_http._tcp", "", 0, "_http._tcp");
377 test_dns_service_join_one("foo", "_http._tcp", "foo", 0, "foo._http._tcp.foo");
378 test_dns_service_join_one(NULL, "_http._tcp", "foo", 0, "_http._tcp.foo");
379 test_dns_service_join_one("Lennart's PC", "_pc._tcp", "foo.bar.com", 0, "Lennart\\039s\\032PC._pc._tcp.foo.bar.com");
380 test_dns_service_join_one(NULL, "_pc._tcp", "foo.bar.com", 0, "_pc._tcp.foo.bar.com");
381}
382
383static void test_dns_service_split_one(const char *joined, const char *a, const char *b, const char *c, int r) {
384 _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *t = NULL;
385
386 assert_se(dns_service_split(joined, &x, &y, &z) == r);
387 assert_se(streq_ptr(x, a));
388 assert_se(streq_ptr(y, b));
389 assert_se(streq_ptr(z, c));
390
391 if (r < 0)
392 return;
393
394 if (y) {
395 assert_se(dns_service_join(x, y, z, &t) == 0);
396 assert_se(streq_ptr(joined, t));
397 } else
398 assert_se(!x && streq_ptr(z, joined));
399}
400
401static void test_dns_service_split(void) {
402 test_dns_service_split_one("", NULL, NULL, "", 0);
403 test_dns_service_split_one("foo", NULL, NULL, "foo", 0);
404 test_dns_service_split_one("foo.bar", NULL, NULL, "foo.bar", 0);
405 test_dns_service_split_one("_foo.bar", NULL, NULL, "_foo.bar", 0);
406 test_dns_service_split_one("_foo._bar", NULL, "_foo._bar", "", 0);
407 test_dns_service_split_one("_meh._foo._bar", "_meh", "_foo._bar", "", 0);
408 test_dns_service_split_one("Wuff\\032Wuff._foo._bar.waldo.com", "Wuff Wuff", "_foo._bar", "waldo.com", 0);
0a49b6b6
LP
409}
410
58db254a
LP
411static void test_dns_name_change_suffix_one(const char *name, const char *old_suffix, const char *new_suffix, int r, const char *result) {
412 _cleanup_free_ char *s = NULL;
413
414 assert_se(dns_name_change_suffix(name, old_suffix, new_suffix, &s) == r);
415 assert_se(streq_ptr(s, result));
416}
417
418static void test_dns_name_change_suffix(void) {
419 test_dns_name_change_suffix_one("foo.bar", "bar", "waldo", 1, "foo.waldo");
420 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "foo.bar.waldi.quux", "piff.paff", 1, "piff.paff");
421 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "bar.waldi.quux", "piff.paff", 1, "foo.piff.paff");
422 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "waldi.quux", "piff.paff", 1, "foo.bar.piff.paff");
423 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "quux", "piff.paff", 1, "foo.bar.waldi.piff.paff");
424 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "", "piff.paff", 1, "foo.bar.waldi.quux.piff.paff");
425 test_dns_name_change_suffix_one("", "", "piff.paff", 1, "piff.paff");
426 test_dns_name_change_suffix_one("", "", "", 1, "");
427 test_dns_name_change_suffix_one("a", "b", "c", 0, NULL);
428}
429
74b2466e
LP
430int main(int argc, char *argv[]) {
431
432 test_dns_label_unescape();
642900d3 433 test_dns_label_unescape_suffix();
74b2466e
LP
434 test_dns_label_escape();
435 test_dns_name_normalize();
436 test_dns_name_equal();
437 test_dns_name_endswith();
ae72b22c 438 test_dns_name_between();
dc477e73
LP
439 test_dns_name_is_root();
440 test_dns_name_is_single_label();
b914e211 441 test_dns_name_reverse();
9ca45586
LP
442 test_dns_name_concat();
443 test_dns_name_is_valid();
54adabf7 444 test_dns_name_to_wire_format();
0a49b6b6 445 test_dns_service_name_is_valid();
7e8131e9 446 test_dns_srv_type_is_valid();
0e8eedbb
LP
447 test_dns_service_join();
448 test_dns_service_split();
58db254a 449 test_dns_name_change_suffix();
74b2466e
LP
450
451 return 0;
452}