name_test.c revision 1.3 1 1.1 christos /* $NetBSD: name_test.c,v 1.3 2024/09/22 00:14:11 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 1.1 christos *
6 1.1 christos * SPDX-License-Identifier: MPL-2.0
7 1.1 christos *
8 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public
9 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this
10 1.1 christos * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11 1.1 christos *
12 1.1 christos * See the COPYRIGHT file distributed with this work for additional
13 1.1 christos * information regarding copyright ownership.
14 1.1 christos */
15 1.1 christos
16 1.1 christos #include <inttypes.h>
17 1.1 christos #include <sched.h> /* IWYU pragma: keep */
18 1.1 christos #include <setjmp.h>
19 1.1 christos #include <stdarg.h>
20 1.1 christos #include <stdbool.h>
21 1.1 christos #include <stddef.h>
22 1.1 christos #include <stdlib.h>
23 1.1 christos #include <string.h>
24 1.1 christos #include <unistd.h>
25 1.1 christos
26 1.1 christos #define UNIT_TESTING
27 1.1 christos #include <cmocka.h>
28 1.1 christos
29 1.1 christos #include <isc/buffer.h>
30 1.1 christos #include <isc/commandline.h>
31 1.1 christos #include <isc/mem.h>
32 1.1 christos #include <isc/os.h>
33 1.1 christos #include <isc/print.h>
34 1.1 christos #include <isc/thread.h>
35 1.1 christos #include <isc/util.h>
36 1.1 christos
37 1.1 christos #include <dns/compress.h>
38 1.1 christos #include <dns/fixedname.h>
39 1.1 christos #include <dns/name.h>
40 1.1 christos
41 1.1 christos #include <tests/dns.h>
42 1.1 christos
43 1.1 christos /* Set to true (or use -v option) for verbose output */
44 1.1 christos static bool verbose = false;
45 1.1 christos
46 1.1 christos /* dns_name_fullcompare test */
47 1.1 christos ISC_RUN_TEST_IMPL(fullcompare) {
48 1.1 christos dns_fixedname_t fixed1;
49 1.1 christos dns_fixedname_t fixed2;
50 1.1 christos dns_name_t *name1;
51 1.1 christos dns_name_t *name2;
52 1.1 christos dns_namereln_t relation;
53 1.1 christos int i;
54 1.1 christos isc_result_t result;
55 1.1 christos struct {
56 1.1 christos const char *name1;
57 1.1 christos const char *name2;
58 1.1 christos dns_namereln_t relation;
59 1.1 christos int order;
60 1.1 christos unsigned int nlabels;
61 1.1 christos } data[] = {
62 1.1 christos /* relative */
63 1.1 christos { "", "", dns_namereln_equal, 0, 0 },
64 1.1 christos { "foo", "", dns_namereln_subdomain, 1, 0 },
65 1.1 christos { "", "foo", dns_namereln_contains, -1, 0 },
66 1.1 christos { "foo", "bar", dns_namereln_none, 4, 0 },
67 1.1 christos { "bar", "foo", dns_namereln_none, -4, 0 },
68 1.1 christos { "bar.foo", "foo", dns_namereln_subdomain, 1, 1 },
69 1.1 christos { "foo", "bar.foo", dns_namereln_contains, -1, 1 },
70 1.1 christos { "baz.bar.foo", "bar.foo", dns_namereln_subdomain, 1, 2 },
71 1.1 christos { "bar.foo", "baz.bar.foo", dns_namereln_contains, -1, 2 },
72 1.1 christos { "foo.example", "bar.example", dns_namereln_commonancestor, 4,
73 1.1 christos 1 },
74 1.1 christos
75 1.1 christos /* absolute */
76 1.1 christos { ".", ".", dns_namereln_equal, 0, 1 },
77 1.1 christos { "foo.", "bar.", dns_namereln_commonancestor, 4, 1 },
78 1.1 christos { "bar.", "foo.", dns_namereln_commonancestor, -4, 1 },
79 1.1 christos { "foo.example.", "bar.example.", dns_namereln_commonancestor,
80 1.1 christos 4, 2 },
81 1.1 christos { "bar.foo.", "foo.", dns_namereln_subdomain, 1, 2 },
82 1.1 christos { "foo.", "bar.foo.", dns_namereln_contains, -1, 2 },
83 1.1 christos { "baz.bar.foo.", "bar.foo.", dns_namereln_subdomain, 1, 3 },
84 1.1 christos { "bar.foo.", "baz.bar.foo.", dns_namereln_contains, -1, 3 },
85 1.1 christos { NULL, NULL, dns_namereln_none, 0, 0 }
86 1.1 christos };
87 1.1 christos
88 1.1 christos UNUSED(state);
89 1.1 christos
90 1.1 christos name1 = dns_fixedname_initname(&fixed1);
91 1.1 christos name2 = dns_fixedname_initname(&fixed2);
92 1.1 christos for (i = 0; data[i].name1 != NULL; i++) {
93 1.1 christos int order = 3000;
94 1.1 christos unsigned int nlabels = 3000;
95 1.1 christos
96 1.1 christos if (data[i].name1[0] == 0) {
97 1.1 christos dns_fixedname_init(&fixed1);
98 1.1 christos } else {
99 1.1 christos result = dns_name_fromstring2(name1, data[i].name1,
100 1.1 christos NULL, 0, NULL);
101 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
102 1.1 christos }
103 1.1 christos if (data[i].name2[0] == 0) {
104 1.1 christos dns_fixedname_init(&fixed2);
105 1.1 christos } else {
106 1.1 christos result = dns_name_fromstring2(name2, data[i].name2,
107 1.1 christos NULL, 0, NULL);
108 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
109 1.1 christos }
110 1.1 christos relation = dns_name_fullcompare(name1, name1, &order, &nlabels);
111 1.1 christos assert_int_equal(relation, dns_namereln_equal);
112 1.1 christos assert_int_equal(order, 0);
113 1.1 christos assert_int_equal(nlabels, name1->labels);
114 1.1 christos
115 1.1 christos /* Some random initializer */
116 1.1 christos order = 3001;
117 1.1 christos nlabels = 3001;
118 1.1 christos
119 1.1 christos relation = dns_name_fullcompare(name1, name2, &order, &nlabels);
120 1.1 christos assert_int_equal(relation, data[i].relation);
121 1.1 christos assert_int_equal(order, data[i].order);
122 1.1 christos assert_int_equal(nlabels, data[i].nlabels);
123 1.1 christos }
124 1.1 christos }
125 1.1 christos
126 1.1 christos static void
127 1.1 christos compress_test(dns_name_t *name1, dns_name_t *name2, dns_name_t *name3,
128 1.1 christos unsigned char *expected, unsigned int length,
129 1.1 christos dns_compress_t *cctx, dns_decompress_t *dctx) {
130 1.1 christos isc_buffer_t source;
131 1.1 christos isc_buffer_t target;
132 1.1 christos dns_name_t name;
133 1.1 christos unsigned char buf1[1024];
134 1.1 christos unsigned char buf2[1024];
135 1.1 christos
136 1.1 christos isc_buffer_init(&source, buf1, sizeof(buf1));
137 1.1 christos isc_buffer_init(&target, buf2, sizeof(buf2));
138 1.1 christos
139 1.1 christos assert_int_equal(dns_name_towire(name1, cctx, &source), ISC_R_SUCCESS);
140 1.1 christos
141 1.1 christos assert_int_equal(dns_name_towire(name2, cctx, &source), ISC_R_SUCCESS);
142 1.1 christos assert_int_equal(dns_name_towire(name2, cctx, &source), ISC_R_SUCCESS);
143 1.1 christos assert_int_equal(dns_name_towire(name3, cctx, &source), ISC_R_SUCCESS);
144 1.1 christos
145 1.1 christos isc_buffer_setactive(&source, source.used);
146 1.1 christos
147 1.1 christos dns_name_init(&name, NULL);
148 1.1 christos RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) ==
149 1.1 christos ISC_R_SUCCESS);
150 1.1 christos RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) ==
151 1.1 christos ISC_R_SUCCESS);
152 1.1 christos RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) ==
153 1.1 christos ISC_R_SUCCESS);
154 1.1 christos RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) ==
155 1.1 christos ISC_R_SUCCESS);
156 1.1 christos dns_decompress_invalidate(dctx);
157 1.1 christos
158 1.1 christos assert_int_equal(target.used, length);
159 1.1 christos assert_true(memcmp(target.base, expected, target.used) == 0);
160 1.1 christos }
161 1.1 christos
162 1.1 christos /* name compression test */
163 1.1 christos ISC_RUN_TEST_IMPL(compression) {
164 1.1 christos unsigned int allowed;
165 1.1 christos dns_compress_t cctx;
166 1.1 christos dns_decompress_t dctx;
167 1.1 christos dns_name_t name1;
168 1.1 christos dns_name_t name2;
169 1.1 christos dns_name_t name3;
170 1.1 christos isc_region_t r;
171 1.1 christos unsigned char plain1[] = "\003yyy\003foo";
172 1.1 christos unsigned char plain2[] = "\003bar\003yyy\003foo";
173 1.1 christos unsigned char plain3[] = "\003xxx\003bar\003foo";
174 1.1 christos unsigned char plain[] = "\003yyy\003foo\0\003bar\003yyy\003foo\0\003"
175 1.1 christos "bar\003yyy\003foo\0\003xxx\003bar\003foo";
176 1.1 christos
177 1.1 christos UNUSED(state);
178 1.1 christos
179 1.1 christos dns_name_init(&name1, NULL);
180 1.1 christos r.base = plain1;
181 1.1 christos r.length = sizeof(plain1);
182 1.1 christos dns_name_fromregion(&name1, &r);
183 1.1 christos
184 1.1 christos dns_name_init(&name2, NULL);
185 1.1 christos r.base = plain2;
186 1.1 christos r.length = sizeof(plain2);
187 1.1 christos dns_name_fromregion(&name2, &r);
188 1.1 christos
189 1.1 christos dns_name_init(&name3, NULL);
190 1.1 christos r.base = plain3;
191 1.1 christos r.length = sizeof(plain3);
192 1.1 christos dns_name_fromregion(&name3, &r);
193 1.1 christos
194 1.1 christos /* Test 1: NONE */
195 1.1 christos allowed = DNS_COMPRESS_NONE;
196 1.1 christos assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS);
197 1.1 christos dns_compress_setmethods(&cctx, allowed);
198 1.1 christos dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
199 1.1 christos dns_decompress_setmethods(&dctx, allowed);
200 1.1 christos
201 1.1 christos compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
202 1.1 christos &dctx);
203 1.1 christos
204 1.1 christos dns_compress_rollback(&cctx, 0);
205 1.1 christos dns_compress_invalidate(&cctx);
206 1.1 christos
207 1.1 christos /* Test2: GLOBAL14 */
208 1.1 christos allowed = DNS_COMPRESS_GLOBAL14;
209 1.1 christos assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS);
210 1.1 christos dns_compress_setmethods(&cctx, allowed);
211 1.1 christos dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
212 1.1 christos dns_decompress_setmethods(&dctx, allowed);
213 1.1 christos
214 1.1 christos compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
215 1.1 christos &dctx);
216 1.1 christos
217 1.1 christos dns_compress_rollback(&cctx, 0);
218 1.1 christos dns_compress_invalidate(&cctx);
219 1.1 christos
220 1.1 christos /* Test3: ALL */
221 1.1 christos allowed = DNS_COMPRESS_ALL;
222 1.1 christos assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS);
223 1.1 christos dns_compress_setmethods(&cctx, allowed);
224 1.1 christos dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
225 1.1 christos dns_decompress_setmethods(&dctx, allowed);
226 1.1 christos
227 1.1 christos compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
228 1.1 christos &dctx);
229 1.1 christos
230 1.1 christos dns_compress_rollback(&cctx, 0);
231 1.1 christos dns_compress_invalidate(&cctx);
232 1.1 christos
233 1.1 christos /* Test4: NONE disabled */
234 1.1 christos allowed = DNS_COMPRESS_NONE;
235 1.1 christos assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS);
236 1.1 christos dns_compress_setmethods(&cctx, allowed);
237 1.1 christos dns_compress_disable(&cctx);
238 1.1 christos dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
239 1.1 christos dns_decompress_setmethods(&dctx, allowed);
240 1.1 christos
241 1.1 christos compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
242 1.1 christos &dctx);
243 1.1 christos
244 1.1 christos dns_compress_rollback(&cctx, 0);
245 1.1 christos dns_compress_invalidate(&cctx);
246 1.1 christos
247 1.1 christos /* Test5: GLOBAL14 disabled */
248 1.1 christos allowed = DNS_COMPRESS_GLOBAL14;
249 1.1 christos assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS);
250 1.1 christos dns_compress_setmethods(&cctx, allowed);
251 1.1 christos dns_compress_disable(&cctx);
252 1.1 christos dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
253 1.1 christos dns_decompress_setmethods(&dctx, allowed);
254 1.1 christos
255 1.1 christos compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
256 1.1 christos &dctx);
257 1.1 christos
258 1.1 christos dns_compress_rollback(&cctx, 0);
259 1.1 christos dns_compress_invalidate(&cctx);
260 1.1 christos
261 1.1 christos /* Test6: ALL disabled */
262 1.1 christos allowed = DNS_COMPRESS_ALL;
263 1.1 christos assert_int_equal(dns_compress_init(&cctx, -1, mctx), ISC_R_SUCCESS);
264 1.1 christos dns_compress_setmethods(&cctx, allowed);
265 1.1 christos dns_compress_disable(&cctx);
266 1.1 christos dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
267 1.1 christos dns_decompress_setmethods(&dctx, allowed);
268 1.1 christos
269 1.1 christos compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
270 1.1 christos &dctx);
271 1.1 christos
272 1.1 christos dns_compress_rollback(&cctx, 0);
273 1.1 christos dns_compress_invalidate(&cctx);
274 1.1 christos }
275 1.1 christos
276 1.3 christos ISC_RUN_TEST_IMPL(fromregion) {
277 1.3 christos dns_name_t name;
278 1.3 christos isc_buffer_t b;
279 1.3 christos isc_region_t r;
280 1.3 christos /*
281 1.3 christos * target and source need to be bigger than DNS_NAME_MAXWIRE to
282 1.3 christos * exercise 'len > DNS_NAME_MAXWIRE' test in dns_name_fromwire
283 1.3 christos */
284 1.3 christos unsigned char target[DNS_NAME_MAXWIRE + 10];
285 1.3 christos unsigned char source[DNS_NAME_MAXWIRE + 10] = { '\007', 'e', 'x', 'a',
286 1.3 christos 'm', 'p', 'l', 'e' };
287 1.3 christos /*
288 1.3 christos * Extract the fully qualified name at the beginning of 'source'
289 1.3 christos * into 'name' where 'name.ndata' points to the buffer 'target'.
290 1.3 christos */
291 1.3 christos isc_buffer_init(&b, target, sizeof(target));
292 1.3 christos dns_name_init(&name, NULL);
293 1.3 christos dns_name_setbuffer(&name, &b);
294 1.3 christos r.base = source;
295 1.3 christos r.length = sizeof(source);
296 1.3 christos dns_name_fromregion(&name, &r);
297 1.3 christos assert_int_equal(9, name.length);
298 1.3 christos assert_ptr_equal(target, name.ndata);
299 1.3 christos assert_true(dns_name_isabsolute(&name));
300 1.3 christos
301 1.3 christos /*
302 1.3 christos * Extract the fully qualified name at the beginning of 'source'
303 1.3 christos * into 'name' where 'name.ndata' points to the source.
304 1.3 christos */
305 1.3 christos isc_buffer_init(&b, target, sizeof(target));
306 1.3 christos dns_name_init(&name, NULL);
307 1.3 christos r.base = source;
308 1.3 christos r.length = sizeof(source);
309 1.3 christos dns_name_fromregion(&name, &r);
310 1.3 christos assert_int_equal(9, name.length);
311 1.3 christos assert_ptr_equal(source, name.ndata);
312 1.3 christos assert_true(dns_name_isabsolute(&name));
313 1.3 christos
314 1.3 christos /*
315 1.3 christos * Extract the partially qualified name in 'source' into 'name'
316 1.3 christos * where 'name.ndata' points to the source.
317 1.3 christos */
318 1.3 christos isc_buffer_init(&b, target, sizeof(target));
319 1.3 christos dns_name_init(&name, NULL);
320 1.3 christos r.base = source;
321 1.3 christos r.length = 8;
322 1.3 christos dns_name_fromregion(&name, &r);
323 1.3 christos assert_int_equal(8, name.length);
324 1.3 christos assert_ptr_equal(source, name.ndata);
325 1.3 christos assert_false(dns_name_isabsolute(&name));
326 1.3 christos
327 1.3 christos /*
328 1.3 christos * Extract empty name in 'source' into 'name'.
329 1.3 christos */
330 1.3 christos isc_buffer_init(&b, target, sizeof(target));
331 1.3 christos dns_name_init(&name, NULL);
332 1.3 christos r.base = source;
333 1.3 christos r.length = 0;
334 1.3 christos dns_name_fromregion(&name, &r);
335 1.3 christos assert_int_equal(0, name.length);
336 1.3 christos assert_ptr_equal(source, name.ndata);
337 1.3 christos assert_false(dns_name_isabsolute(&name));
338 1.3 christos }
339 1.3 christos
340 1.1 christos /* is trust-anchor-telemetry test */
341 1.1 christos ISC_RUN_TEST_IMPL(istat) {
342 1.1 christos dns_fixedname_t fixed;
343 1.1 christos dns_name_t *name;
344 1.1 christos isc_result_t result;
345 1.1 christos size_t i;
346 1.1 christos struct {
347 1.1 christos const char *name;
348 1.1 christos bool istat;
349 1.1 christos } data[] = { { ".", false },
350 1.1 christos { "_ta-", false },
351 1.1 christos { "_ta-1234", true },
352 1.1 christos { "_TA-1234", true },
353 1.1 christos { "+TA-1234", false },
354 1.1 christos { "_fa-1234", false },
355 1.1 christos { "_td-1234", false },
356 1.1 christos { "_ta_1234", false },
357 1.1 christos { "_ta-g234", false },
358 1.1 christos { "_ta-1h34", false },
359 1.1 christos { "_ta-12i4", false },
360 1.1 christos { "_ta-123j", false },
361 1.1 christos { "_ta-1234-abcf", true },
362 1.1 christos { "_ta-1234-abcf-ED89", true },
363 1.1 christos { "_ta-12345-abcf-ED89", false },
364 1.1 christos { "_ta-.example", false },
365 1.1 christos { "_ta-1234.example", true },
366 1.1 christos { "_ta-1234-abcf.example", true },
367 1.1 christos { "_ta-1234-abcf-ED89.example", true },
368 1.1 christos { "_ta-12345-abcf-ED89.example", false },
369 1.1 christos { "_ta-1234-abcfe-ED89.example", false },
370 1.1 christos { "_ta-1234-abcf-EcD89.example", false } };
371 1.1 christos
372 1.1 christos UNUSED(state);
373 1.1 christos
374 1.1 christos name = dns_fixedname_initname(&fixed);
375 1.1 christos
376 1.1 christos for (i = 0; i < (sizeof(data) / sizeof(data[0])); i++) {
377 1.1 christos result = dns_name_fromstring(name, data[i].name, 0, NULL);
378 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
379 1.1 christos assert_int_equal(dns_name_istat(name), data[i].istat);
380 1.1 christos }
381 1.1 christos }
382 1.1 christos
383 1.1 christos /* dns_nane_init */
384 1.1 christos ISC_RUN_TEST_IMPL(init) {
385 1.1 christos dns_name_t name;
386 1.1 christos unsigned char offsets[1];
387 1.1 christos
388 1.1 christos UNUSED(state);
389 1.1 christos
390 1.1 christos dns_name_init(&name, offsets);
391 1.1 christos
392 1.1 christos assert_null(name.ndata);
393 1.1 christos assert_int_equal(name.length, 0);
394 1.1 christos assert_int_equal(name.labels, 0);
395 1.1 christos assert_int_equal(name.attributes, 0);
396 1.1 christos assert_ptr_equal(name.offsets, offsets);
397 1.1 christos assert_null(name.buffer);
398 1.1 christos }
399 1.1 christos
400 1.1 christos /* dns_nane_invalidate */
401 1.1 christos ISC_RUN_TEST_IMPL(invalidate) {
402 1.1 christos dns_name_t name;
403 1.1 christos unsigned char offsets[1];
404 1.1 christos
405 1.1 christos UNUSED(state);
406 1.1 christos
407 1.1 christos dns_name_init(&name, offsets);
408 1.1 christos dns_name_invalidate(&name);
409 1.1 christos
410 1.1 christos assert_null(name.ndata);
411 1.1 christos assert_int_equal(name.length, 0);
412 1.1 christos assert_int_equal(name.labels, 0);
413 1.1 christos assert_int_equal(name.attributes, 0);
414 1.1 christos assert_null(name.offsets);
415 1.1 christos assert_null(name.buffer);
416 1.1 christos }
417 1.1 christos
418 1.1 christos /* dns_nane_setbuffer/hasbuffer */
419 1.1 christos ISC_RUN_TEST_IMPL(buffer) {
420 1.1 christos dns_name_t name;
421 1.1 christos unsigned char buf[BUFSIZ];
422 1.1 christos isc_buffer_t b;
423 1.1 christos
424 1.1 christos UNUSED(state);
425 1.1 christos
426 1.1 christos isc_buffer_init(&b, buf, BUFSIZ);
427 1.1 christos dns_name_init(&name, NULL);
428 1.1 christos dns_name_setbuffer(&name, &b);
429 1.1 christos assert_ptr_equal(name.buffer, &b);
430 1.1 christos assert_true(dns_name_hasbuffer(&name));
431 1.1 christos }
432 1.1 christos
433 1.1 christos /* dns_nane_isabsolute */
434 1.1 christos ISC_RUN_TEST_IMPL(isabsolute) {
435 1.1 christos struct {
436 1.1 christos const char *namestr;
437 1.1 christos bool expect;
438 1.1 christos } testcases[] = { { "x", false },
439 1.1 christos { "a.b.c.d.", true },
440 1.1 christos { "x.z", false } };
441 1.1 christos unsigned int i;
442 1.1 christos
443 1.1 christos UNUSED(state);
444 1.1 christos
445 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
446 1.1 christos isc_result_t result;
447 1.1 christos dns_name_t name;
448 1.1 christos unsigned char data[BUFSIZ];
449 1.1 christos isc_buffer_t b, nb;
450 1.1 christos size_t len;
451 1.1 christos
452 1.1 christos len = strlen(testcases[i].namestr);
453 1.1 christos isc_buffer_constinit(&b, testcases[i].namestr, len);
454 1.1 christos isc_buffer_add(&b, len);
455 1.1 christos
456 1.1 christos dns_name_init(&name, NULL);
457 1.1 christos isc_buffer_init(&nb, data, BUFSIZ);
458 1.1 christos dns_name_setbuffer(&name, &nb);
459 1.1 christos result = dns_name_fromtext(&name, &b, NULL, 0, NULL);
460 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
461 1.1 christos
462 1.1 christos assert_int_equal(dns_name_isabsolute(&name),
463 1.1 christos testcases[i].expect);
464 1.1 christos }
465 1.1 christos }
466 1.1 christos
467 1.1 christos /* dns_nane_hash */
468 1.1 christos ISC_RUN_TEST_IMPL(hash) {
469 1.1 christos struct {
470 1.1 christos const char *name1;
471 1.1 christos const char *name2;
472 1.1 christos bool expect;
473 1.1 christos bool expecti;
474 1.1 christos } testcases[] = {
475 1.1 christos { "a.b.c.d", "A.B.C.D", true, false },
476 1.1 christos { "a.b.c.d.", "A.B.C.D.", true, false },
477 1.1 christos { "a.b.c.d", "a.b.c.d", true, true },
478 1.1 christos { "A.B.C.D.", "A.B.C.D.", true, false },
479 1.1 christos { "x.y.z.w", "a.b.c.d", false, false },
480 1.1 christos { "x.y.z.w.", "a.b.c.d.", false, false },
481 1.1 christos };
482 1.1 christos unsigned int i;
483 1.1 christos
484 1.1 christos UNUSED(state);
485 1.1 christos
486 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
487 1.1 christos isc_result_t result;
488 1.1 christos dns_fixedname_t f1, f2;
489 1.1 christos dns_name_t *n1, *n2;
490 1.1 christos unsigned int h1, h2;
491 1.1 christos
492 1.1 christos n1 = dns_fixedname_initname(&f1);
493 1.1 christos n2 = dns_fixedname_initname(&f2);
494 1.1 christos
495 1.1 christos result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0,
496 1.1 christos NULL);
497 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
498 1.1 christos result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0,
499 1.1 christos NULL);
500 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
501 1.1 christos
502 1.1 christos /* Check case-insensitive hashing first */
503 1.1 christos h1 = dns_name_hash(n1, false);
504 1.1 christos h2 = dns_name_hash(n2, false);
505 1.1 christos
506 1.1 christos if (verbose) {
507 1.1 christos print_message("# %s hashes to %u, "
508 1.1 christos "%s to %u, case insensitive\n",
509 1.1 christos testcases[i].name1, h1,
510 1.1 christos testcases[i].name2, h2);
511 1.1 christos }
512 1.1 christos
513 1.1 christos assert_int_equal((h1 == h2), testcases[i].expect);
514 1.1 christos
515 1.1 christos /* Now case-sensitive */
516 1.1 christos h1 = dns_name_hash(n1, false);
517 1.1 christos h2 = dns_name_hash(n2, false);
518 1.1 christos
519 1.1 christos if (verbose) {
520 1.1 christos print_message("# %s hashes to %u, "
521 1.1 christos "%s to %u, case sensitive\n",
522 1.1 christos testcases[i].name1, h1,
523 1.1 christos testcases[i].name2, h2);
524 1.1 christos }
525 1.1 christos
526 1.1 christos assert_int_equal((h1 == h2), testcases[i].expect);
527 1.1 christos }
528 1.1 christos }
529 1.1 christos
530 1.1 christos /* dns_nane_issubdomain */
531 1.1 christos ISC_RUN_TEST_IMPL(issubdomain) {
532 1.1 christos struct {
533 1.1 christos const char *name1;
534 1.1 christos const char *name2;
535 1.1 christos bool expect;
536 1.1 christos } testcases[] = {
537 1.1 christos { "c.d", "a.b.c.d", false }, { "c.d.", "a.b.c.d.", false },
538 1.1 christos { "b.c.d", "c.d", true }, { "a.b.c.d.", "c.d.", true },
539 1.1 christos { "a.b.c", "a.b.c", true }, { "a.b.c.", "a.b.c.", true },
540 1.1 christos { "x.y.z", "a.b.c", false }
541 1.1 christos };
542 1.1 christos unsigned int i;
543 1.1 christos
544 1.1 christos UNUSED(state);
545 1.1 christos
546 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
547 1.1 christos isc_result_t result;
548 1.1 christos dns_fixedname_t f1, f2;
549 1.1 christos dns_name_t *n1, *n2;
550 1.1 christos
551 1.1 christos n1 = dns_fixedname_initname(&f1);
552 1.1 christos n2 = dns_fixedname_initname(&f2);
553 1.1 christos
554 1.1 christos result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0,
555 1.1 christos NULL);
556 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
557 1.1 christos result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0,
558 1.1 christos NULL);
559 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
560 1.1 christos
561 1.1 christos if (verbose) {
562 1.1 christos print_message("# check: %s %s a subdomain of %s\n",
563 1.1 christos testcases[i].name1,
564 1.1 christos testcases[i].expect ? "is" : "is not",
565 1.1 christos testcases[i].name2);
566 1.1 christos }
567 1.1 christos
568 1.1 christos assert_int_equal(dns_name_issubdomain(n1, n2),
569 1.1 christos testcases[i].expect);
570 1.1 christos }
571 1.1 christos }
572 1.1 christos
573 1.1 christos /* dns_nane_countlabels */
574 1.1 christos ISC_RUN_TEST_IMPL(countlabels) {
575 1.1 christos struct {
576 1.1 christos const char *namestr;
577 1.1 christos unsigned int expect;
578 1.1 christos } testcases[] = {
579 1.1 christos { "c.d", 2 }, { "c.d.", 3 }, { "a.b.c.d.", 5 },
580 1.1 christos { "a.b.c.d", 4 }, { "a.b.c", 3 }, { ".", 1 },
581 1.1 christos };
582 1.1 christos unsigned int i;
583 1.1 christos
584 1.1 christos UNUSED(state);
585 1.1 christos
586 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
587 1.1 christos isc_result_t result;
588 1.1 christos dns_fixedname_t fname;
589 1.1 christos dns_name_t *name;
590 1.1 christos
591 1.1 christos name = dns_fixedname_initname(&fname);
592 1.1 christos
593 1.1 christos result = dns_name_fromstring2(name, testcases[i].namestr, NULL,
594 1.1 christos 0, NULL);
595 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
596 1.1 christos
597 1.1 christos if (verbose) {
598 1.1 christos print_message("# %s: expect %u labels\n",
599 1.1 christos testcases[i].namestr,
600 1.1 christos testcases[i].expect);
601 1.1 christos }
602 1.1 christos
603 1.1 christos assert_int_equal(dns_name_countlabels(name),
604 1.1 christos testcases[i].expect);
605 1.1 christos }
606 1.1 christos }
607 1.1 christos
608 1.1 christos /* dns_nane_getlabel */
609 1.1 christos ISC_RUN_TEST_IMPL(getlabel) {
610 1.1 christos struct {
611 1.1 christos const char *name1;
612 1.1 christos unsigned int pos1;
613 1.1 christos const char *name2;
614 1.1 christos unsigned int pos2;
615 1.1 christos } testcases[] = {
616 1.1 christos { "c.d", 1, "a.b.c.d", 3 },
617 1.1 christos { "a.b.c.d", 3, "c.d", 1 },
618 1.1 christos { "a.b.c.", 3, "A.B.C.", 3 },
619 1.1 christos };
620 1.1 christos unsigned int i;
621 1.1 christos
622 1.1 christos UNUSED(state);
623 1.1 christos
624 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
625 1.1 christos isc_result_t result;
626 1.1 christos dns_fixedname_t f1, f2;
627 1.1 christos dns_name_t *n1, *n2;
628 1.1 christos dns_label_t l1, l2;
629 1.1 christos unsigned int j;
630 1.1 christos
631 1.1 christos n1 = dns_fixedname_initname(&f1);
632 1.1 christos n2 = dns_fixedname_initname(&f2);
633 1.1 christos
634 1.1 christos result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0,
635 1.1 christos NULL);
636 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
637 1.1 christos result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0,
638 1.1 christos NULL);
639 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
640 1.1 christos
641 1.1 christos dns_name_getlabel(n1, testcases[i].pos1, &l1);
642 1.1 christos dns_name_getlabel(n2, testcases[i].pos2, &l2);
643 1.1 christos assert_int_equal(l1.length, l2.length);
644 1.1 christos
645 1.1 christos for (j = 0; j < l1.length; j++) {
646 1.1 christos assert_int_equal(l1.base[j], l2.base[j]);
647 1.1 christos }
648 1.1 christos }
649 1.1 christos }
650 1.1 christos
651 1.1 christos /* dns_nane_getlabelsequence */
652 1.1 christos ISC_RUN_TEST_IMPL(getlabelsequence) {
653 1.1 christos struct {
654 1.1 christos const char *name1;
655 1.1 christos unsigned int pos1;
656 1.1 christos const char *name2;
657 1.1 christos unsigned int pos2;
658 1.1 christos unsigned int range;
659 1.1 christos } testcases[] = {
660 1.1 christos { "c.d", 1, "a.b.c.d", 3, 1 },
661 1.1 christos { "a.b.c.d.e", 2, "c.d", 0, 2 },
662 1.1 christos { "a.b.c", 0, "a.b.c", 0, 3 },
663 1.1 christos };
664 1.1 christos unsigned int i;
665 1.1 christos
666 1.1 christos UNUSED(state);
667 1.1 christos
668 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
669 1.1 christos isc_result_t result;
670 1.1 christos dns_name_t t1, t2;
671 1.1 christos dns_fixedname_t f1, f2;
672 1.1 christos dns_name_t *n1, *n2;
673 1.1 christos
674 1.1 christos /* target names */
675 1.1 christos dns_name_init(&t1, NULL);
676 1.1 christos dns_name_init(&t2, NULL);
677 1.1 christos
678 1.1 christos /* source names */
679 1.1 christos n1 = dns_fixedname_initname(&f1);
680 1.1 christos n2 = dns_fixedname_initname(&f2);
681 1.1 christos
682 1.1 christos result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0,
683 1.1 christos NULL);
684 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
685 1.1 christos result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0,
686 1.1 christos NULL);
687 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
688 1.1 christos
689 1.1 christos dns_name_getlabelsequence(n1, testcases[i].pos1,
690 1.1 christos testcases[i].range, &t1);
691 1.1 christos dns_name_getlabelsequence(n2, testcases[i].pos2,
692 1.1 christos testcases[i].range, &t2);
693 1.1 christos
694 1.1 christos assert_true(dns_name_equal(&t1, &t2));
695 1.1 christos }
696 1.1 christos }
697 1.1 christos
698 1.1 christos #ifdef DNS_BENCHMARK_TESTS
699 1.1 christos
700 1.1 christos /*
701 1.1 christos * XXXMUKS: Don't delete this code. It is useful in benchmarking the
702 1.1 christos * name parser, but we don't require it as part of the unit test runs.
703 1.1 christos */
704 1.1 christos
705 1.1 christos /* Benchmark dns_name_fromwire() implementation */
706 1.1 christos
707 1.1 christos ISC_RUN_TEST_IMPL(fromwire_thread(void *arg) {
708 1.1 christos unsigned int maxval = 32000000;
709 1.1 christos uint8_t data[] = { 3, 'w', 'w', 'w', 7, 'e', 'x',
710 1.1 christos 'a', 'm', 'p', 'l', 'e', 7, 'i',
711 1.1 christos 'n', 'v', 'a', 'l', 'i', 'd', 0 };
712 1.1 christos unsigned char output_data[DNS_NAME_MAXWIRE];
713 1.1 christos isc_buffer_t source, target;
714 1.1 christos unsigned int i;
715 1.1 christos dns_decompress_t dctx;
716 1.1 christos
717 1.1 christos UNUSED(arg);
718 1.1 christos
719 1.1 christos dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
720 1.1 christos dns_decompress_setmethods(&dctx, DNS_COMPRESS_NONE);
721 1.1 christos
722 1.1 christos isc_buffer_init(&source, data, sizeof(data));
723 1.1 christos isc_buffer_add(&source, sizeof(data));
724 1.1 christos isc_buffer_init(&target, output_data, sizeof(output_data));
725 1.1 christos
726 1.1 christos /* Parse 32 million names in each thread */
727 1.1 christos for (i = 0; i < maxval; i++) {
728 1.1 christos dns_name_t name;
729 1.1 christos
730 1.1 christos isc_buffer_clear(&source);
731 1.1 christos isc_buffer_clear(&target);
732 1.1 christos isc_buffer_add(&source, sizeof(data));
733 1.1 christos isc_buffer_setactive(&source, sizeof(data));
734 1.1 christos
735 1.1 christos dns_name_init(&name, NULL);
736 1.1 christos (void)dns_name_fromwire(&name, &source, &dctx, 0, &target);
737 1.1 christos }
738 1.1 christos
739 1.1 christos return (NULL);
740 1.1 christos }
741 1.1 christos
742 1.1 christos ISC_RUN_TEST_IMPL(benchmark) {
743 1.1 christos isc_result_t result;
744 1.1 christos unsigned int i;
745 1.1 christos isc_time_t ts1, ts2;
746 1.1 christos double t;
747 1.1 christos unsigned int nthreads;
748 1.1 christos isc_thread_t threads[32];
749 1.1 christos
750 1.1 christos UNUSED(state);
751 1.1 christos
752 1.1 christos debug_mem_record = false;
753 1.1 christos
754 1.1 christos result = isc_time_now(&ts1);
755 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
756 1.1 christos
757 1.1 christos nthreads = ISC_MIN(isc_os_ncpus(), 32);
758 1.1 christos nthreads = ISC_MAX(nthreads, 1);
759 1.1 christos for (i = 0; i < nthreads; i++) {
760 1.1 christos isc_thread_create(fromwire_thread, NULL, &threads[i]);
761 1.1 christos }
762 1.1 christos
763 1.1 christos for (i = 0; i < nthreads; i++) {
764 1.1 christos isc_thread_join(threads[i], NULL);
765 1.1 christos }
766 1.1 christos
767 1.1 christos result = isc_time_now(&ts2);
768 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
769 1.1 christos
770 1.1 christos t = isc_time_microdiff(&ts2, &ts1);
771 1.1 christos
772 1.1 christos printf("%u dns_name_fromwire() calls, %f seconds, %f calls/second\n",
773 1.1 christos nthreads * 32000000, t / 1000000.0,
774 1.1 christos (nthreads * 32000000) / (t / 1000000.0));
775 1.1 christos }
776 1.1 christos
777 1.1 christos #endif /* DNS_BENCHMARK_TESTS */
778 1.1 christos
779 1.1 christos ISC_TEST_LIST_START
780 1.1 christos ISC_TEST_ENTRY(fullcompare)
781 1.1 christos ISC_TEST_ENTRY(compression)
782 1.3 christos ISC_TEST_ENTRY(fromregion)
783 1.1 christos ISC_TEST_ENTRY(istat)
784 1.1 christos ISC_TEST_ENTRY(init)
785 1.1 christos ISC_TEST_ENTRY(invalidate)
786 1.1 christos ISC_TEST_ENTRY(buffer)
787 1.1 christos ISC_TEST_ENTRY(isabsolute)
788 1.1 christos ISC_TEST_ENTRY(hash)
789 1.1 christos ISC_TEST_ENTRY(issubdomain)
790 1.1 christos ISC_TEST_ENTRY(countlabels)
791 1.1 christos ISC_TEST_ENTRY(getlabel)
792 1.1 christos ISC_TEST_ENTRY(getlabelsequence)
793 1.1 christos #ifdef DNS_BENCHMARK_TESTS
794 1.1 christos ISC_TEST_ENTRY(benchmark)
795 1.1 christos #endif /* DNS_BENCHMARK_TESTS */
796 1.1 christos ISC_TEST_LIST_END
797 1.1 christos
798 1.1 christos ISC_TEST_MAIN
799