1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "alloc-util.h"
4 #include "dns-domain.h"
5 #include "in-addr-util.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_name_from_wire_format_one(const char *expect
, const uint8_t *what
, size_t len
, int ret
) {
123 _cleanup_free_
char *name
= NULL
;
126 log_info("%s, %s, %zu, →%d", what
, strnull(expect
), len
, ret
);
128 r
= dns_name_from_wire_format(&what
, &len
, &name
);
132 assert(expect
); /* for gcc */
133 assert_se(memcmp(name
, expect
, r
) == 0);
137 TEST(dns_name_from_wire_format
) {
138 static const uint8_t in0
[] = { 0 };
139 static const uint8_t in1
[] = { 3, 'f', 'o', 'o', 0 };
140 static const uint8_t in2
[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
141 static const uint8_t in2_1
[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 0, 'b', 'a', 'r', 0 };
142 static const uint8_t in3
[] = { 4, ' ', 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
143 static const uint8_t in4
[] = { 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
144 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
145 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
146 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
147 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
148 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
149 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
150 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
151 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
152 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
153 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
154 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
155 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
156 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
157 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
158 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
159 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
160 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
161 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
162 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
163 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
164 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
165 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
166 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
167 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
168 3, 'a', '1', '2', 0 }; /* 255 octets */
169 static const uint8_t in5
[] = { 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
170 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
171 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
172 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
173 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
174 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
175 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
176 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
177 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
178 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
179 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
180 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
181 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
182 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
183 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
184 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
185 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
186 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
187 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
188 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
189 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
190 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
191 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
192 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
193 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
194 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
195 3, 'a', '1', '2', 0 }; /* 265 octets */
197 test_dns_name_from_wire_format_one("", in0
, sizeof(in0
), strlen(""));
199 test_dns_name_from_wire_format_one("foo", in1
, sizeof(in1
), strlen("foo"));
200 test_dns_name_from_wire_format_one("foo", in1
, sizeof(in1
) - 1, strlen("foo"));
202 test_dns_name_from_wire_format_one("hallo.foo.bar", in2
, sizeof(in2
), strlen("hallo.foo.bar"));
203 test_dns_name_from_wire_format_one("hallo.foo", in2_1
, sizeof(in2_1
), strlen("hallo.foo"));
205 test_dns_name_from_wire_format_one("\\032foo.bar", in3
, sizeof(in3
), strlen("\\032foo.bar"));
207 test_dns_name_from_wire_format_one(NULL
, in5
, sizeof(in5
), -EMSGSIZE
);
208 test_dns_name_from_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", in4
, sizeof(in4
), 253);
211 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
) {
212 char buffer
[buffer_sz
];
216 log_info("%s, %s, %s, %zu, %d, %d", what
, expect1
, expect2
, buffer_sz
, ret1
, ret2
);
218 label
= what
+ strlen(what
);
220 r
= dns_label_unescape_suffix(what
, &label
, buffer
, buffer_sz
);
221 assert_se(r
== ret1
);
223 ASSERT_STREQ(buffer
, expect1
);
225 r
= dns_label_unescape_suffix(what
, &label
, buffer
, buffer_sz
);
226 assert_se(r
== ret2
);
228 ASSERT_STREQ(buffer
, expect2
);
231 TEST(dns_label_unescape_suffix
) {
232 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 6, 5, 0);
233 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOBUFS
, -ENOBUFS
);
234 test_dns_label_unescape_suffix_one("", "", "", 10, 0, 0);
235 test_dns_label_unescape_suffix_one("hallo\\.foobar", "hallo.foobar", "", 20, 12, 0);
236 test_dns_label_unescape_suffix_one("hallo.foobar", "foobar", "hallo", 10, 6, 5);
237 test_dns_label_unescape_suffix_one("hallo.foobar\n", "foobar", "foobar", 20, -EINVAL
, -EINVAL
);
238 test_dns_label_unescape_suffix_one("hallo\\", "hallo", "hallo", 20, -EINVAL
, -EINVAL
);
239 test_dns_label_unescape_suffix_one("hallo\\032 ", "hallo ", "", 20, 7, 0);
240 test_dns_label_unescape_suffix_one(".", "", "", 20, 0, 0);
241 test_dns_label_unescape_suffix_one("..", "", "", 20, 0, -EINVAL
);
242 test_dns_label_unescape_suffix_one(".foobar", "foobar", "", 20, 6, -EINVAL
);
243 test_dns_label_unescape_suffix_one("foobar.", "foobar", "", 20, 6, 0);
244 test_dns_label_unescape_suffix_one("foo\\\\bar", "foo\\bar", "", 20, 7, 0);
245 test_dns_label_unescape_suffix_one("foo.bar", "bar", "foo", 20, 3, 3);
246 test_dns_label_unescape_suffix_one("foo..bar", "bar", "", 20, 3, -EINVAL
);
247 test_dns_label_unescape_suffix_one("foo...bar", "bar", "", 20, 3, -EINVAL
);
248 test_dns_label_unescape_suffix_one("foo\\.bar", "foo.bar", "", 20, 7, 0);
249 test_dns_label_unescape_suffix_one("foo\\\\.bar", "bar", "foo\\", 20, 3, 4);
250 test_dns_label_unescape_suffix_one("foo\\\\\\.bar", "foo\\.bar", "", 20, 8, 0);
253 static void test_dns_label_escape_one(const char *what
, size_t l
, const char *expect
, int ret
) {
254 _cleanup_free_
char *t
= NULL
;
257 log_info("%s, %zu, %s, →%d", what
, l
, strnull(expect
), ret
);
259 r
= dns_label_escape_new(what
, l
, &t
);
265 ASSERT_STREQ(expect
, t
);
268 TEST(dns_label_escape
) {
269 test_dns_label_escape_one("", 0, NULL
, -EINVAL
);
270 test_dns_label_escape_one("hallo", 5, "hallo", 5);
271 test_dns_label_escape_one("hallo", 6, "hallo\\000", 9);
272 test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
275 static void test_dns_name_normalize_one(const char *what
, const char *expect
, int ret
) {
276 _cleanup_free_
char *t
= NULL
;
279 r
= dns_name_normalize(what
, 0, &t
);
285 ASSERT_STREQ(expect
, t
);
288 TEST(dns_name_normalize
) {
289 test_dns_name_normalize_one("", ".", 0);
290 test_dns_name_normalize_one("f", "f", 0);
291 test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
292 test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
293 test_dns_name_normalize_one("\\000", "\\000", 0);
294 test_dns_name_normalize_one("..", NULL
, -EINVAL
);
295 test_dns_name_normalize_one(".foobar", NULL
, -EINVAL
);
296 test_dns_name_normalize_one("foobar.", "foobar", 0);
297 test_dns_name_normalize_one(".", ".", 0);
300 static void test_dns_name_equal_one(const char *a
, const char *b
, int ret
) {
303 r
= dns_name_equal(a
, b
);
306 r
= dns_name_equal(b
, a
);
310 TEST(dns_name_equal
) {
311 test_dns_name_equal_one("", "", true);
312 test_dns_name_equal_one("x", "x", true);
313 test_dns_name_equal_one("x", "x.", true);
314 test_dns_name_equal_one("abc.def", "abc.def", true);
315 test_dns_name_equal_one("abc.def", "ABC.def", true);
316 test_dns_name_equal_one("abc.def", "CBA.def", false);
317 test_dns_name_equal_one("", "xxx", false);
318 test_dns_name_equal_one("ab", "a", false);
319 test_dns_name_equal_one("\\000", "\\000", true);
320 test_dns_name_equal_one(".", "", true);
321 test_dns_name_equal_one(".", ".", true);
322 test_dns_name_equal_one("..", "..", -EINVAL
);
325 static void test_dns_name_between_one(const char *a
, const char *b
, const char *c
, int ret
) {
328 r
= dns_name_between(a
, b
, c
);
331 r
= dns_name_between(c
, b
, a
);
333 assert_se(r
== 0 || dns_name_equal(a
, c
) > 0);
338 TEST(dns_name_between
) {
339 /* see https://tools.ietf.org/html/rfc4034#section-6.1
340 Note that we use "\033.z.example" in stead of "\001.z.example" as we
341 consider the latter invalid */
342 test_dns_name_between_one("example", "a.example", "yljkjljk.a.example", true);
343 test_dns_name_between_one("a.example", "yljkjljk.a.example", "Z.a.example", true);
344 test_dns_name_between_one("yljkjljk.a.example", "Z.a.example", "zABC.a.EXAMPLE", true);
345 test_dns_name_between_one("Z.a.example", "zABC.a.EXAMPLE", "z.example", true);
346 test_dns_name_between_one("zABC.a.EXAMPLE", "z.example", "\\033.z.example", true);
347 test_dns_name_between_one("z.example", "\\033.z.example", "*.z.example", true);
348 test_dns_name_between_one("\\033.z.example", "*.z.example", "\\200.z.example", true);
349 test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
350 test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
352 test_dns_name_between_one("example", "a.example", "example", true);
353 test_dns_name_between_one("example", "example", "example", false);
354 test_dns_name_between_one("example", "example", "yljkjljk.a.example", false);
355 test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false);
356 test_dns_name_between_one("hkps.pool.sks-keyservers.net", "_pgpkey-https._tcp.hkps.pool.sks-keyservers.net", "ipv4.pool.sks-keyservers.net", true);
359 static void test_dns_name_endswith_one(const char *a
, const char *b
, int ret
) {
360 assert_se(dns_name_endswith(a
, b
) == ret
);
363 TEST(dns_name_endswith
) {
364 test_dns_name_endswith_one("", "", true);
365 test_dns_name_endswith_one("", "xxx", false);
366 test_dns_name_endswith_one("xxx", "", true);
367 test_dns_name_endswith_one("x", "x", true);
368 test_dns_name_endswith_one("x", "y", false);
369 test_dns_name_endswith_one("x.y", "y", true);
370 test_dns_name_endswith_one("x.y", "Y", true);
371 test_dns_name_endswith_one("x.y", "x", false);
372 test_dns_name_endswith_one("x.y.z", "Z", true);
373 test_dns_name_endswith_one("x.y.z", "y.Z", true);
374 test_dns_name_endswith_one("x.y.z", "x.y.Z", true);
375 test_dns_name_endswith_one("x.y.z", "waldo", false);
376 test_dns_name_endswith_one("x.y.z.u.v.w", "y.z", false);
377 test_dns_name_endswith_one("x.y.z.u.v.w", "u.v.w", true);
378 test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL
);
381 static void test_dns_name_startswith_one(const char *a
, const char *b
, int ret
) {
382 assert_se(dns_name_startswith(a
, b
) == ret
);
385 TEST(dns_name_startswith
) {
386 test_dns_name_startswith_one("", "", true);
387 test_dns_name_startswith_one("", "xxx", false);
388 test_dns_name_startswith_one("xxx", "", true);
389 test_dns_name_startswith_one("x", "x", true);
390 test_dns_name_startswith_one("x", "y", false);
391 test_dns_name_startswith_one("x.y", "x.y", true);
392 test_dns_name_startswith_one("x.y", "y.x", false);
393 test_dns_name_startswith_one("x.y", "x", true);
394 test_dns_name_startswith_one("x.y", "X", true);
395 test_dns_name_startswith_one("x.y", "y", false);
396 test_dns_name_startswith_one("x.y", "", true);
397 test_dns_name_startswith_one("x.y", "X", true);
400 TEST(dns_name_is_root
) {
401 assert_se(dns_name_is_root(""));
402 assert_se(dns_name_is_root("."));
403 assert_se(!dns_name_is_root("xxx"));
404 assert_se(!dns_name_is_root("xxx."));
405 assert_se(!dns_name_is_root(".."));
408 TEST(dns_name_is_single_label
) {
409 assert_se(!dns_name_is_single_label(""));
410 assert_se(!dns_name_is_single_label("."));
411 assert_se(!dns_name_is_single_label(".."));
412 assert_se(dns_name_is_single_label("x"));
413 assert_se(dns_name_is_single_label("x."));
414 assert_se(!dns_name_is_single_label("xx.yy"));
417 static void test_dns_name_reverse_one(const char *address
, const char *name
) {
418 _cleanup_free_
char *p
= NULL
;
419 union in_addr_union a
, b
= {};
420 int familya
, familyb
;
422 assert_se(in_addr_from_string_auto(address
, &familya
, &a
) >= 0);
423 assert_se(dns_name_reverse(familya
, &a
, &p
) >= 0);
424 ASSERT_STREQ(p
, name
);
425 assert_se(dns_name_address(p
, &familyb
, &b
) > 0);
426 assert_se(familya
== familyb
);
427 assert_se(in_addr_equal(familya
, &a
, &b
));
430 TEST(dns_name_reverse
) {
431 test_dns_name_reverse_one("47.11.8.15", "15.8.11.47.in-addr.arpa");
432 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");
433 test_dns_name_reverse_one("127.0.0.1", "1.0.0.127.in-addr.arpa");
434 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");
437 static void test_dns_name_concat_one(const char *a
, const char *b
, int r
, const char *result
) {
438 _cleanup_free_
char *p
= NULL
;
440 assert_se(dns_name_concat(a
, b
, 0, &p
) == r
);
441 ASSERT_STREQ(p
, result
);
444 TEST(dns_name_concat
) {
445 test_dns_name_concat_one("", "", 0, ".");
446 test_dns_name_concat_one(".", "", 0, ".");
447 test_dns_name_concat_one("", ".", 0, ".");
448 test_dns_name_concat_one(".", ".", 0, ".");
449 test_dns_name_concat_one("foo", "bar", 0, "foo.bar");
450 test_dns_name_concat_one("foo.foo", "bar.bar", 0, "foo.foo.bar.bar");
451 test_dns_name_concat_one("foo", NULL
, 0, "foo");
452 test_dns_name_concat_one("foo", ".", 0, "foo");
453 test_dns_name_concat_one("foo.", "bar.", 0, "foo.bar");
454 test_dns_name_concat_one(NULL
, NULL
, 0, ".");
455 test_dns_name_concat_one(NULL
, ".", 0, ".");
456 test_dns_name_concat_one(NULL
, "foo", 0, "foo");
459 static void test_dns_name_is_valid_one(const char *s
, int ret
, int ret_ldh
) {
460 log_info("%s, →%d", s
, ret
);
462 assert_se(dns_name_is_valid(s
) == ret
);
463 assert_se(dns_name_is_valid_ldh(s
) == ret_ldh
);
466 TEST(dns_name_is_valid
) {
467 test_dns_name_is_valid_one("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[._qotd._tcp.local", 1, 0);
468 test_dns_name_is_valid_one("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]._qotd._tcp.local", 0, 0);
470 test_dns_name_is_valid_one("foo", 1, 1);
471 test_dns_name_is_valid_one("foo.", 1, 1);
472 test_dns_name_is_valid_one("foo..", 0, 0);
473 test_dns_name_is_valid_one("Foo", 1, 1);
474 test_dns_name_is_valid_one("foo.bar", 1, 1);
475 test_dns_name_is_valid_one("foo.bar.baz", 1, 1);
476 test_dns_name_is_valid_one("", 1, 1);
477 test_dns_name_is_valid_one("foo..bar", 0, 0);
478 test_dns_name_is_valid_one(".foo.bar", 0, 0);
479 test_dns_name_is_valid_one("foo.bar.", 1, 1);
480 test_dns_name_is_valid_one("foo.bar..", 0, 0);
481 test_dns_name_is_valid_one("\\zbar", 0, 0);
482 test_dns_name_is_valid_one("ä", 1, 0);
483 test_dns_name_is_valid_one("\n", 0, 0);
485 test_dns_name_is_valid_one("dash-", 1, 0);
486 test_dns_name_is_valid_one("-dash", 1, 0);
487 test_dns_name_is_valid_one("dash-dash", 1, 1);
488 test_dns_name_is_valid_one("foo.dash-", 1, 0);
489 test_dns_name_is_valid_one("foo.-dash", 1, 0);
490 test_dns_name_is_valid_one("foo.dash-dash", 1, 1);
491 test_dns_name_is_valid_one("foo.dash-.bar", 1, 0);
492 test_dns_name_is_valid_one("foo.-dash.bar", 1, 0);
493 test_dns_name_is_valid_one("foo.dash-dash.bar", 1, 1);
494 test_dns_name_is_valid_one("dash-.bar", 1, 0);
495 test_dns_name_is_valid_one("-dash.bar", 1, 0);
496 test_dns_name_is_valid_one("dash-dash.bar", 1, 1);
497 test_dns_name_is_valid_one("-.bar", 1, 0);
498 test_dns_name_is_valid_one("foo.-", 1, 0);
501 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);
504 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);
507 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);
510 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);
512 /* label of 64 chars length */
513 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a123", 0, 0);
515 /* label of 63 chars length */
516 test_dns_name_is_valid_one("a123456789a123456789a123456789a123456789a123456789a123456789a12", 1, 1);
519 TEST(dns_service_name_is_valid
) {
520 assert_se(dns_service_name_is_valid("Lennart's Compüter"));
521 assert_se(dns_service_name_is_valid("piff.paff"));
523 assert_se(!dns_service_name_is_valid(NULL
));
524 assert_se(!dns_service_name_is_valid(""));
525 assert_se(!dns_service_name_is_valid("foo\nbar"));
526 assert_se(!dns_service_name_is_valid("foo\201bar"));
527 assert_se(!dns_service_name_is_valid("this is an overly long string that is certainly longer than 63 characters"));
530 TEST(dns_srv_type_is_valid
) {
531 assert_se(dns_srv_type_is_valid("_http._tcp"));
532 assert_se(dns_srv_type_is_valid("_foo-bar._tcp"));
533 assert_se(dns_srv_type_is_valid("_w._udp"));
534 assert_se(dns_srv_type_is_valid("_a800._tcp"));
535 assert_se(dns_srv_type_is_valid("_a-800._tcp"));
537 assert_se(!dns_srv_type_is_valid(NULL
));
538 assert_se(!dns_srv_type_is_valid(""));
539 assert_se(!dns_srv_type_is_valid("x"));
540 assert_se(!dns_srv_type_is_valid("_foo"));
541 assert_se(!dns_srv_type_is_valid("_tcp"));
542 assert_se(!dns_srv_type_is_valid("_"));
543 assert_se(!dns_srv_type_is_valid("_foo."));
544 assert_se(!dns_srv_type_is_valid("_föo._tcp"));
545 assert_se(!dns_srv_type_is_valid("_f\no._tcp"));
546 assert_se(!dns_srv_type_is_valid("_800._tcp"));
547 assert_se(!dns_srv_type_is_valid("_-800._tcp"));
548 assert_se(!dns_srv_type_is_valid("_-foo._tcp"));
549 assert_se(!dns_srv_type_is_valid("_piep._foo._udp"));
552 TEST(dnssd_srv_type_is_valid
) {
553 assert_se(dnssd_srv_type_is_valid("_http._tcp"));
554 assert_se(dnssd_srv_type_is_valid("_foo-bar._tcp"));
555 assert_se(dnssd_srv_type_is_valid("_w._udp"));
556 assert_se(dnssd_srv_type_is_valid("_a800._tcp"));
557 assert_se(dnssd_srv_type_is_valid("_a-800._tcp"));
559 assert_se(!dnssd_srv_type_is_valid(NULL
));
560 assert_se(!dnssd_srv_type_is_valid(""));
561 assert_se(!dnssd_srv_type_is_valid("x"));
562 assert_se(!dnssd_srv_type_is_valid("_foo"));
563 assert_se(!dnssd_srv_type_is_valid("_tcp"));
564 assert_se(!dnssd_srv_type_is_valid("_"));
565 assert_se(!dnssd_srv_type_is_valid("_foo."));
566 assert_se(!dnssd_srv_type_is_valid("_föo._tcp"));
567 assert_se(!dnssd_srv_type_is_valid("_f\no._tcp"));
568 assert_se(!dnssd_srv_type_is_valid("_800._tcp"));
569 assert_se(!dnssd_srv_type_is_valid("_-800._tcp"));
570 assert_se(!dnssd_srv_type_is_valid("_-foo._tcp"));
571 assert_se(!dnssd_srv_type_is_valid("_piep._foo._udp"));
572 assert_se(!dnssd_srv_type_is_valid("_foo._unknown"));
575 static void test_dns_service_join_one(const char *a
, const char *b
, const char *c
, int r
, const char *d
) {
576 _cleanup_free_
char *x
= NULL
, *y
= NULL
, *z
= NULL
, *t
= NULL
;
578 log_info("%s, %s, %s, →%d, %s", strnull(a
), strnull(b
), strnull(c
), r
, strnull(d
));
580 assert_se(dns_service_join(a
, b
, c
, &t
) == r
);
586 assert_se(dns_service_split(t
, &x
, &y
, &z
) >= 0);
589 assert_se(dns_name_equal(c
, z
) > 0);
592 TEST(dns_service_join
) {
593 test_dns_service_join_one("", "", "", -EINVAL
, NULL
);
594 test_dns_service_join_one("", "_http._tcp", "", -EINVAL
, NULL
);
595 test_dns_service_join_one("", "_http._tcp", "foo", -EINVAL
, NULL
);
596 test_dns_service_join_one("foo", "", "foo", -EINVAL
, NULL
);
597 test_dns_service_join_one("foo", "foo", "foo", -EINVAL
, NULL
);
599 test_dns_service_join_one("foo", "_http._tcp", "", 0, "foo._http._tcp");
600 test_dns_service_join_one(NULL
, "_http._tcp", "", 0, "_http._tcp");
601 test_dns_service_join_one("foo", "_http._tcp", "foo", 0, "foo._http._tcp.foo");
602 test_dns_service_join_one(NULL
, "_http._tcp", "foo", 0, "_http._tcp.foo");
603 test_dns_service_join_one("Lennart's PC", "_pc._tcp", "foo.bar.com", 0, "Lennart\\039s\\032PC._pc._tcp.foo.bar.com");
604 test_dns_service_join_one(NULL
, "_pc._tcp", "foo.bar.com", 0, "_pc._tcp.foo.bar.com");
607 static void test_dns_service_split_one(const char *joined
, const char *a
, const char *b
, const char *c
, int r
) {
608 _cleanup_free_
char *x
= NULL
, *y
= NULL
, *z
= NULL
, *t
= NULL
;
610 log_info("%s, %s, %s, %s, →%d", joined
, strnull(a
), strnull(b
), strnull(c
), r
);
612 assert_se(dns_service_split(joined
, &x
, &y
, &z
) == r
);
621 assert_se(dns_service_join(x
, y
, z
, &t
) == 0);
622 assert_se(dns_name_equal(joined
, t
) > 0);
624 assert_se(!x
&& dns_name_equal(z
, joined
) > 0);
627 TEST(dns_service_split
) {
628 test_dns_service_split_one("", NULL
, NULL
, ".", 0);
629 test_dns_service_split_one("foo", NULL
, NULL
, "foo", 0);
630 test_dns_service_split_one("foo.bar", NULL
, NULL
, "foo.bar", 0);
631 test_dns_service_split_one("_foo.bar", NULL
, NULL
, "_foo.bar", 0);
632 test_dns_service_split_one("_foo._bar", NULL
, "_foo._bar", ".", 0);
633 test_dns_service_split_one("_meh._foo._bar", "_meh", "_foo._bar", ".", 0);
634 test_dns_service_split_one("Wuff\\032Wuff._foo._bar.waldo.com", "Wuff Wuff", "_foo._bar", "waldo.com", 0);
635 test_dns_service_split_one("_Q._Q-------------------------------------------------------------", NULL
, "_Q._Q-------------------------------------------------------------", ".", 0);
638 static void test_dns_name_change_suffix_one(const char *name
, const char *old_suffix
, const char *new_suffix
, int r
, const char *result
) {
639 _cleanup_free_
char *s
= NULL
;
641 log_info("%s, %s, %s, →%s", name
, old_suffix
, new_suffix
, strnull(result
));
643 assert_se(dns_name_change_suffix(name
, old_suffix
, new_suffix
, &s
) == r
);
644 ASSERT_STREQ(s
, result
);
647 TEST(dns_name_change_suffix
) {
648 test_dns_name_change_suffix_one("foo.bar", "bar", "waldo", 1, "foo.waldo");
649 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "foo.bar.waldi.quux", "piff.paff", 1, "piff.paff");
650 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "bar.waldi.quux", "piff.paff", 1, "foo.piff.paff");
651 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "waldi.quux", "piff.paff", 1, "foo.bar.piff.paff");
652 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "quux", "piff.paff", 1, "foo.bar.waldi.piff.paff");
653 test_dns_name_change_suffix_one("foo.bar.waldi.quux", "", "piff.paff", 1, "foo.bar.waldi.quux.piff.paff");
654 test_dns_name_change_suffix_one("", "", "piff.paff", 1, "piff.paff");
655 test_dns_name_change_suffix_one("", "", "", 1, ".");
656 test_dns_name_change_suffix_one("a", "b", "c", 0, NULL
);
659 static void test_dns_name_suffix_one(const char *name
, unsigned n_labels
, const char *result
, int ret
) {
660 const char *p
= NULL
;
662 log_info("%s, %u, → %s, %d", name
, n_labels
, strnull(result
), ret
);
664 assert_se(ret
== dns_name_suffix(name
, n_labels
, &p
));
665 ASSERT_STREQ(p
, result
);
668 TEST(dns_name_suffix
) {
669 test_dns_name_suffix_one("foo.bar", 2, "foo.bar", 0);
670 test_dns_name_suffix_one("foo.bar", 1, "bar", 1);
671 test_dns_name_suffix_one("foo.bar", 0, "", 2);
672 test_dns_name_suffix_one("foo.bar", 3, NULL
, -EINVAL
);
673 test_dns_name_suffix_one("foo.bar", 4, NULL
, -EINVAL
);
675 test_dns_name_suffix_one("bar", 1, "bar", 0);
676 test_dns_name_suffix_one("bar", 0, "", 1);
677 test_dns_name_suffix_one("bar", 2, NULL
, -EINVAL
);
678 test_dns_name_suffix_one("bar", 3, NULL
, -EINVAL
);
680 test_dns_name_suffix_one("", 0, "", 0);
681 test_dns_name_suffix_one("", 1, NULL
, -EINVAL
);
682 test_dns_name_suffix_one("", 2, NULL
, -EINVAL
);
685 static void test_dns_name_count_labels_one(const char *name
, int n
) {
686 log_info("%s, →%d", name
, n
);
688 assert_se(dns_name_count_labels(name
) == n
);
691 TEST(dns_name_count_labels
) {
692 test_dns_name_count_labels_one("foo.bar.quux.", 3);
693 test_dns_name_count_labels_one("foo.bar.quux", 3);
694 test_dns_name_count_labels_one("foo.bar.", 2);
695 test_dns_name_count_labels_one("foo.bar", 2);
696 test_dns_name_count_labels_one("foo.", 1);
697 test_dns_name_count_labels_one("foo", 1);
698 test_dns_name_count_labels_one("", 0);
699 test_dns_name_count_labels_one(".", 0);
700 test_dns_name_count_labels_one("..", -EINVAL
);
703 static void test_dns_name_equal_skip_one(const char *a
, unsigned n_labels
, const char *b
, int ret
) {
704 log_info("%s, %u, %s, →%d", a
, n_labels
, b
, ret
);
706 assert_se(dns_name_equal_skip(a
, n_labels
, b
) == ret
);
709 TEST(dns_name_equal_skip
) {
710 test_dns_name_equal_skip_one("foo", 0, "bar", 0);
711 test_dns_name_equal_skip_one("foo", 0, "foo", 1);
712 test_dns_name_equal_skip_one("foo", 1, "foo", 0);
713 test_dns_name_equal_skip_one("foo", 2, "foo", 0);
715 test_dns_name_equal_skip_one("foo.bar", 0, "foo.bar", 1);
716 test_dns_name_equal_skip_one("foo.bar", 1, "foo.bar", 0);
717 test_dns_name_equal_skip_one("foo.bar", 2, "foo.bar", 0);
718 test_dns_name_equal_skip_one("foo.bar", 3, "foo.bar", 0);
720 test_dns_name_equal_skip_one("foo.bar", 0, "bar", 0);
721 test_dns_name_equal_skip_one("foo.bar", 1, "bar", 1);
722 test_dns_name_equal_skip_one("foo.bar", 2, "bar", 0);
723 test_dns_name_equal_skip_one("foo.bar", 3, "bar", 0);
725 test_dns_name_equal_skip_one("foo.bar", 0, "", 0);
726 test_dns_name_equal_skip_one("foo.bar", 1, "", 0);
727 test_dns_name_equal_skip_one("foo.bar", 2, "", 1);
728 test_dns_name_equal_skip_one("foo.bar", 3, "", 0);
730 test_dns_name_equal_skip_one("", 0, "", 1);
731 test_dns_name_equal_skip_one("", 1, "", 0);
732 test_dns_name_equal_skip_one("", 1, "foo", 0);
733 test_dns_name_equal_skip_one("", 2, "foo", 0);
736 TEST(dns_name_compare_func
) {
737 assert_se(dns_name_compare_func("", "") == 0);
738 assert_se(dns_name_compare_func("", ".") == 0);
739 assert_se(dns_name_compare_func(".", "") == 0);
740 assert_se(dns_name_compare_func("foo", "foo.") == 0);
741 assert_se(dns_name_compare_func("foo.", "foo") == 0);
742 assert_se(dns_name_compare_func("foo", "foo") == 0);
743 assert_se(dns_name_compare_func("foo.", "foo.") == 0);
744 assert_se(dns_name_compare_func("heise.de", "HEISE.DE.") == 0);
746 assert_se(dns_name_compare_func("de.", "heise.de") != 0);
749 static void test_dns_name_common_suffix_one(const char *a
, const char *b
, const char *result
) {
752 log_info("%s, %s, →%s", a
, b
, result
);
754 assert_se(dns_name_common_suffix(a
, b
, &c
) >= 0);
755 ASSERT_STREQ(c
, result
);
758 TEST(dns_name_common_suffix
) {
759 test_dns_name_common_suffix_one("", "", "");
760 test_dns_name_common_suffix_one("foo", "", "");
761 test_dns_name_common_suffix_one("", "foo", "");
762 test_dns_name_common_suffix_one("foo", "bar", "");
763 test_dns_name_common_suffix_one("bar", "foo", "");
764 test_dns_name_common_suffix_one("foo", "foo", "foo");
765 test_dns_name_common_suffix_one("quux.foo", "foo", "foo");
766 test_dns_name_common_suffix_one("foo", "quux.foo", "foo");
767 test_dns_name_common_suffix_one("this.is.a.short.sentence", "this.is.another.short.sentence", "short.sentence");
768 test_dns_name_common_suffix_one("FOO.BAR", "tEST.bAR", "BAR");
771 static void test_dns_name_apply_idna_one(const char *s
, int expected
, const char *result
) {
772 _cleanup_free_
char *buf
= NULL
;
775 r
= dns_name_apply_idna(s
, &buf
);
776 log_debug("dns_name_apply_idna: \"%s\" → %d/\"%s\" (expected %d/\"%s\")",
777 s
, r
, strnull(buf
), expected
, strnull(result
));
779 /* Different libidn2 versions are more and less accepting
780 * of underscore-prefixed names. So let's list the lowest
781 * expected return value. */
782 assert_se(r
>= expected
);
784 assert_se(dns_name_equal(buf
, result
) == 1);
787 TEST(dns_name_apply_idna
) {
788 const int ret
= HAVE_LIBIDN2
| HAVE_LIBIDN
;
790 /* IDNA2008 forbids names with hyphens in third and fourth positions
791 * (https://tools.ietf.org/html/rfc5891#section-4.2.3.1).
792 * IDNA2003 does not have this restriction
793 * (https://tools.ietf.org/html/rfc3490#section-5).
794 * This means that when using libidn we will transform and test more
795 * labels. If registrars follow IDNA2008 we'll just be performing a
798 const int ret2
= HAVE_LIBIDN
;
800 test_dns_name_apply_idna_one("", ret
, "");
801 test_dns_name_apply_idna_one("foo", ret
, "foo");
802 test_dns_name_apply_idna_one("foo.", ret
, "foo");
803 test_dns_name_apply_idna_one("foo.bar", ret
, "foo.bar");
804 test_dns_name_apply_idna_one("foo.bar.", ret
, "foo.bar");
805 test_dns_name_apply_idna_one("föö", ret
, "xn--f-1gaa");
806 test_dns_name_apply_idna_one("föö.", ret
, "xn--f-1gaa");
807 test_dns_name_apply_idna_one("föö.bär", ret
, "xn--f-1gaa.xn--br-via");
808 test_dns_name_apply_idna_one("föö.bär.", ret
, "xn--f-1gaa.xn--br-via");
809 test_dns_name_apply_idna_one("xn--f-1gaa.xn--br-via", ret
, "xn--f-1gaa.xn--br-via");
811 test_dns_name_apply_idna_one("_443._tcp.fedoraproject.org", ret2
,
812 "_443._tcp.fedoraproject.org");
813 test_dns_name_apply_idna_one("_443", ret2
, "_443");
814 test_dns_name_apply_idna_one("gateway", ret
, "gateway");
815 test_dns_name_apply_idna_one("_gateway", ret2
, "_gateway");
817 test_dns_name_apply_idna_one("r3---sn-ab5l6ne7.googlevideo.com", ret2
,
818 ret2
? "r3---sn-ab5l6ne7.googlevideo.com" : "");
821 TEST(dns_name_is_valid_or_address
) {
822 assert_se(dns_name_is_valid_or_address(NULL
) == 0);
823 assert_se(dns_name_is_valid_or_address("") == 0);
824 assert_se(dns_name_is_valid_or_address("foobar") > 0);
825 assert_se(dns_name_is_valid_or_address("foobar.com") > 0);
826 assert_se(dns_name_is_valid_or_address("foobar..com") == 0);
827 assert_se(dns_name_is_valid_or_address("foobar.com.") > 0);
828 assert_se(dns_name_is_valid_or_address("127.0.0.1") > 0);
829 assert_se(dns_name_is_valid_or_address("::") > 0);
830 assert_se(dns_name_is_valid_or_address("::1") > 0);
833 TEST(dns_name_dot_suffixed
) {
834 assert_se(dns_name_dot_suffixed("") == 0);
835 assert_se(dns_name_dot_suffixed(".") > 0);
836 assert_se(dns_name_dot_suffixed("foo") == 0);
837 assert_se(dns_name_dot_suffixed("foo.") > 0);
838 assert_se(dns_name_dot_suffixed("foo\\..") > 0);
839 assert_se(dns_name_dot_suffixed("foo\\.") == 0);
840 assert_se(dns_name_dot_suffixed("foo.bar.") > 0);
841 assert_se(dns_name_dot_suffixed("foo.bar\\.\\.\\..") > 0);
842 assert_se(dns_name_dot_suffixed("foo.bar\\.\\.\\.\\.") == 0);
845 DEFINE_TEST_MAIN(LOG_DEBUG
);