name_test.c revision 1.6 1 1.6 christos /* $NetBSD: name_test.c,v 1.6 2025/07/17 19:01:47 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/thread.h>
34 1.1 christos #include <isc/util.h>
35 1.1 christos
36 1.1 christos #include <dns/compress.h>
37 1.1 christos #include <dns/fixedname.h>
38 1.1 christos #include <dns/name.h>
39 1.1 christos
40 1.1 christos #include <tests/dns.h>
41 1.1 christos
42 1.1 christos /* Set to true (or use -v option) for verbose output */
43 1.1 christos static bool verbose = false;
44 1.1 christos
45 1.1 christos /* dns_name_fullcompare test */
46 1.1 christos ISC_RUN_TEST_IMPL(fullcompare) {
47 1.1 christos dns_fixedname_t fixed1;
48 1.1 christos dns_fixedname_t fixed2;
49 1.1 christos dns_name_t *name1;
50 1.1 christos dns_name_t *name2;
51 1.1 christos dns_namereln_t relation;
52 1.1 christos int i;
53 1.1 christos isc_result_t result;
54 1.1 christos struct {
55 1.1 christos const char *name1;
56 1.1 christos const char *name2;
57 1.1 christos dns_namereln_t relation;
58 1.1 christos int order;
59 1.1 christos unsigned int nlabels;
60 1.1 christos } data[] = {
61 1.1 christos /* relative */
62 1.1 christos { "", "", dns_namereln_equal, 0, 0 },
63 1.1 christos { "foo", "", dns_namereln_subdomain, 1, 0 },
64 1.1 christos { "", "foo", dns_namereln_contains, -1, 0 },
65 1.4 christos { "foo", "bar", dns_namereln_none, 1, 0 },
66 1.4 christos { "bar", "foo", dns_namereln_none, -1, 0 },
67 1.1 christos { "bar.foo", "foo", dns_namereln_subdomain, 1, 1 },
68 1.1 christos { "foo", "bar.foo", dns_namereln_contains, -1, 1 },
69 1.1 christos { "baz.bar.foo", "bar.foo", dns_namereln_subdomain, 1, 2 },
70 1.1 christos { "bar.foo", "baz.bar.foo", dns_namereln_contains, -1, 2 },
71 1.4 christos { "foo.example", "bar.example", dns_namereln_commonancestor, 1,
72 1.1 christos 1 },
73 1.1 christos
74 1.1 christos /* absolute */
75 1.1 christos { ".", ".", dns_namereln_equal, 0, 1 },
76 1.4 christos { "foo.", "bar.", dns_namereln_commonancestor, 1, 1 },
77 1.4 christos { "bar.", "foo.", dns_namereln_commonancestor, -1, 1 },
78 1.1 christos { "foo.example.", "bar.example.", dns_namereln_commonancestor,
79 1.4 christos 1, 2 },
80 1.1 christos { "bar.foo.", "foo.", dns_namereln_subdomain, 1, 2 },
81 1.1 christos { "foo.", "bar.foo.", dns_namereln_contains, -1, 2 },
82 1.1 christos { "baz.bar.foo.", "bar.foo.", dns_namereln_subdomain, 1, 3 },
83 1.1 christos { "bar.foo.", "baz.bar.foo.", dns_namereln_contains, -1, 3 },
84 1.1 christos { NULL, NULL, dns_namereln_none, 0, 0 }
85 1.1 christos };
86 1.1 christos
87 1.1 christos UNUSED(state);
88 1.1 christos
89 1.1 christos name1 = dns_fixedname_initname(&fixed1);
90 1.1 christos name2 = dns_fixedname_initname(&fixed2);
91 1.1 christos for (i = 0; data[i].name1 != NULL; i++) {
92 1.1 christos int order = 3000;
93 1.1 christos unsigned int nlabels = 3000;
94 1.1 christos
95 1.1 christos if (data[i].name1[0] == 0) {
96 1.1 christos dns_fixedname_init(&fixed1);
97 1.1 christos } else {
98 1.4 christos result = dns_name_fromstring(name1, data[i].name1, NULL,
99 1.4 christos 0, NULL);
100 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
101 1.1 christos }
102 1.1 christos if (data[i].name2[0] == 0) {
103 1.1 christos dns_fixedname_init(&fixed2);
104 1.1 christos } else {
105 1.4 christos result = dns_name_fromstring(name2, data[i].name2, NULL,
106 1.4 christos 0, NULL);
107 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
108 1.1 christos }
109 1.1 christos relation = dns_name_fullcompare(name1, name1, &order, &nlabels);
110 1.1 christos assert_int_equal(relation, dns_namereln_equal);
111 1.1 christos assert_int_equal(order, 0);
112 1.1 christos assert_int_equal(nlabels, name1->labels);
113 1.1 christos
114 1.1 christos /* Some random initializer */
115 1.1 christos order = 3001;
116 1.1 christos nlabels = 3001;
117 1.1 christos
118 1.1 christos relation = dns_name_fullcompare(name1, name2, &order, &nlabels);
119 1.1 christos assert_int_equal(relation, data[i].relation);
120 1.1 christos assert_int_equal(order, data[i].order);
121 1.1 christos assert_int_equal(nlabels, data[i].nlabels);
122 1.1 christos }
123 1.1 christos }
124 1.1 christos
125 1.1 christos static void
126 1.4 christos compress_test(const dns_name_t *name1, const dns_name_t *name2,
127 1.4 christos const dns_name_t *name3, unsigned char *compressed,
128 1.4 christos unsigned int compressed_length, unsigned char *expanded,
129 1.4 christos unsigned int expanded_length, dns_compress_t *cctx,
130 1.4 christos dns_decompress_t dctx, bool rdata) {
131 1.1 christos isc_buffer_t source;
132 1.1 christos isc_buffer_t target;
133 1.1 christos dns_name_t name;
134 1.1 christos unsigned char buf1[1024];
135 1.1 christos unsigned char buf2[1024];
136 1.1 christos
137 1.1 christos isc_buffer_init(&source, buf1, sizeof(buf1));
138 1.1 christos isc_buffer_init(&target, buf2, sizeof(buf2));
139 1.1 christos
140 1.4 christos /*
141 1.4 christos * compression offsets are not allowed to be zero so our
142 1.4 christos * names need to start after a little fake header
143 1.4 christos */
144 1.4 christos isc_buffer_putuint16(&source, 0xEAD);
145 1.4 christos isc_buffer_putuint16(&target, 0xEAD);
146 1.1 christos
147 1.4 christos if (rdata) {
148 1.4 christos /* RDATA compression */
149 1.4 christos assert_int_equal(dns_name_towire(name1, cctx, &source, NULL),
150 1.4 christos ISC_R_SUCCESS);
151 1.4 christos assert_int_equal(dns_name_towire(name2, cctx, &source, NULL),
152 1.4 christos ISC_R_SUCCESS);
153 1.4 christos assert_int_equal(dns_name_towire(name2, cctx, &source, NULL),
154 1.4 christos ISC_R_SUCCESS);
155 1.4 christos assert_int_equal(dns_name_towire(name3, cctx, &source, NULL),
156 1.4 christos ISC_R_SUCCESS);
157 1.4 christos } else {
158 1.4 christos /* Owner name compression */
159 1.4 christos uint16_t offset = 0xffff;
160 1.4 christos assert_int_equal(dns_name_towire(name1, cctx, &source, &offset),
161 1.4 christos ISC_R_SUCCESS);
162 1.4 christos
163 1.4 christos offset = 0xffff;
164 1.4 christos assert_int_equal(dns_name_towire(name2, cctx, &source, &offset),
165 1.4 christos ISC_R_SUCCESS);
166 1.4 christos assert_int_equal(dns_name_towire(name2, cctx, &source, &offset),
167 1.4 christos ISC_R_SUCCESS);
168 1.4 christos
169 1.4 christos offset = 0xffff;
170 1.4 christos assert_int_equal(dns_name_towire(name3, cctx, &source, &offset),
171 1.4 christos ISC_R_SUCCESS);
172 1.4 christos }
173 1.4 christos assert_int_equal(source.used, compressed_length);
174 1.4 christos assert_true(memcmp(source.base, compressed, source.used) == 0);
175 1.1 christos
176 1.1 christos isc_buffer_setactive(&source, source.used);
177 1.1 christos
178 1.1 christos dns_name_init(&name, NULL);
179 1.4 christos RUNTIME_CHECK(isc_buffer_getuint16(&source) == 0xEAD);
180 1.4 christos RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, &target) ==
181 1.1 christos ISC_R_SUCCESS);
182 1.4 christos RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, &target) ==
183 1.1 christos ISC_R_SUCCESS);
184 1.4 christos RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, &target) ==
185 1.1 christos ISC_R_SUCCESS);
186 1.4 christos RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, &target) ==
187 1.1 christos ISC_R_SUCCESS);
188 1.1 christos
189 1.4 christos assert_int_equal(target.used, expanded_length);
190 1.4 christos assert_true(memcmp(target.base, expanded, target.used) == 0);
191 1.1 christos }
192 1.1 christos
193 1.1 christos /* name compression test */
194 1.1 christos ISC_RUN_TEST_IMPL(compression) {
195 1.4 christos bool permitted;
196 1.1 christos dns_compress_t cctx;
197 1.1 christos dns_decompress_t dctx;
198 1.1 christos dns_name_t name1;
199 1.1 christos dns_name_t name2;
200 1.1 christos dns_name_t name3;
201 1.4 christos dns_name_t name4;
202 1.1 christos isc_region_t r;
203 1.1 christos unsigned char plain1[] = "\003yyy\003foo";
204 1.1 christos unsigned char plain2[] = "\003bar\003yyy\003foo";
205 1.1 christos unsigned char plain3[] = "\003xxx\003bar\003foo";
206 1.4 christos unsigned char plain4[] = "\003xxx\003bar\003zzz";
207 1.4 christos
208 1.4 christos unsigned char plain[] = "\x0E\xAD"
209 1.4 christos "\003yyy\003foo\0"
210 1.4 christos "\003bar\003yyy\003foo\0"
211 1.4 christos "\003bar\003yyy\003foo\0"
212 1.4 christos "\003xxx\003bar\003foo";
213 1.4 christos
214 1.5 christos unsigned char compressed[] = "\x0E\xAD"
215 1.5 christos "\003yyy\003foo\0"
216 1.5 christos "\003bar\xc0\x02"
217 1.5 christos "\xc0\x0B"
218 1.5 christos "\003xxx\003bar\xc0\x06";
219 1.5 christos const size_t compressed_len = sizeof(compressed) - 1;
220 1.5 christos
221 1.4 christos /*
222 1.4 christos * Only the second owner name is compressed.
223 1.4 christos */
224 1.4 christos unsigned char disabled_owner[] = "\x0E\xAD"
225 1.4 christos "\003yyy\003foo\0"
226 1.4 christos "\003bar\003yyy\003foo\0"
227 1.4 christos "\xc0\x0B"
228 1.4 christos "\003xxx\003bar\003foo";
229 1.4 christos
230 1.4 christos unsigned char root_plain[] = "\x0E\xAD"
231 1.4 christos "\003yyy\003foo\0"
232 1.4 christos "\0\0"
233 1.4 christos "\003xxx\003bar\003zzz";
234 1.1 christos
235 1.1 christos UNUSED(state);
236 1.1 christos
237 1.1 christos dns_name_init(&name1, NULL);
238 1.1 christos r.base = plain1;
239 1.1 christos r.length = sizeof(plain1);
240 1.1 christos dns_name_fromregion(&name1, &r);
241 1.1 christos
242 1.1 christos dns_name_init(&name2, NULL);
243 1.1 christos r.base = plain2;
244 1.1 christos r.length = sizeof(plain2);
245 1.1 christos dns_name_fromregion(&name2, &r);
246 1.1 christos
247 1.1 christos dns_name_init(&name3, NULL);
248 1.1 christos r.base = plain3;
249 1.1 christos r.length = sizeof(plain3);
250 1.1 christos dns_name_fromregion(&name3, &r);
251 1.1 christos
252 1.4 christos dns_name_init(&name4, NULL);
253 1.4 christos r.base = plain4;
254 1.4 christos r.length = sizeof(plain3);
255 1.4 christos dns_name_fromregion(&name4, &r);
256 1.4 christos
257 1.4 christos /* Test 1: off, rdata */
258 1.4 christos permitted = false;
259 1.4 christos dns_compress_init(&cctx, mctx, 0);
260 1.4 christos dns_compress_setpermitted(&cctx, permitted);
261 1.4 christos dctx = dns_decompress_setpermitted(DNS_DECOMPRESS_DEFAULT, permitted);
262 1.1 christos
263 1.4 christos compress_test(&name1, &name2, &name3, plain, sizeof(plain), plain,
264 1.4 christos sizeof(plain), &cctx, dctx, true);
265 1.1 christos
266 1.1 christos dns_compress_rollback(&cctx, 0);
267 1.1 christos dns_compress_invalidate(&cctx);
268 1.1 christos
269 1.4 christos /* Test2: on, rdata */
270 1.4 christos permitted = true;
271 1.4 christos dns_compress_init(&cctx, mctx, 0);
272 1.4 christos dns_compress_setpermitted(&cctx, permitted);
273 1.4 christos dctx = dns_decompress_setpermitted(DNS_DECOMPRESS_DEFAULT, permitted);
274 1.1 christos
275 1.5 christos compress_test(&name1, &name2, &name3, compressed, compressed_len, plain,
276 1.5 christos sizeof(plain), &cctx, dctx, true);
277 1.1 christos
278 1.1 christos dns_compress_rollback(&cctx, 0);
279 1.1 christos dns_compress_invalidate(&cctx);
280 1.1 christos
281 1.4 christos /* Test3: off, disabled, rdata */
282 1.4 christos permitted = false;
283 1.4 christos dns_compress_init(&cctx, mctx, DNS_COMPRESS_DISABLED);
284 1.4 christos dns_compress_setpermitted(&cctx, permitted);
285 1.4 christos dctx = dns_decompress_setpermitted(DNS_DECOMPRESS_DEFAULT, permitted);
286 1.1 christos
287 1.4 christos compress_test(&name1, &name2, &name3, plain, sizeof(plain), plain,
288 1.4 christos sizeof(plain), &cctx, dctx, true);
289 1.1 christos
290 1.1 christos dns_compress_rollback(&cctx, 0);
291 1.1 christos dns_compress_invalidate(&cctx);
292 1.1 christos
293 1.4 christos /* Test4: on, disabled, rdata */
294 1.4 christos permitted = true;
295 1.4 christos dns_compress_init(&cctx, mctx, DNS_COMPRESS_DISABLED);
296 1.4 christos dns_compress_setpermitted(&cctx, permitted);
297 1.4 christos dctx = dns_decompress_setpermitted(DNS_DECOMPRESS_DEFAULT, permitted);
298 1.1 christos
299 1.4 christos compress_test(&name1, &name2, &name3, plain, sizeof(plain), plain,
300 1.4 christos sizeof(plain), &cctx, dctx, true);
301 1.1 christos
302 1.1 christos dns_compress_rollback(&cctx, 0);
303 1.1 christos dns_compress_invalidate(&cctx);
304 1.1 christos
305 1.4 christos /* Test5: on, rdata */
306 1.4 christos permitted = true;
307 1.4 christos dns_compress_init(&cctx, mctx, 0);
308 1.4 christos dns_compress_setpermitted(&cctx, permitted);
309 1.4 christos dctx = dns_decompress_setpermitted(DNS_DECOMPRESS_DEFAULT, permitted);
310 1.4 christos
311 1.4 christos compress_test(&name1, dns_rootname, &name4, root_plain,
312 1.4 christos sizeof(root_plain), root_plain, sizeof(root_plain), &cctx,
313 1.4 christos dctx, true);
314 1.1 christos
315 1.4 christos dns_compress_rollback(&cctx, 0);
316 1.4 christos dns_compress_invalidate(&cctx);
317 1.4 christos
318 1.4 christos /* Test 6: off, owner */
319 1.4 christos permitted = false;
320 1.4 christos dns_compress_init(&cctx, mctx, 0);
321 1.4 christos dns_compress_setpermitted(&cctx, permitted);
322 1.4 christos dctx = dns_decompress_setpermitted(DNS_DECOMPRESS_DEFAULT, permitted);
323 1.4 christos
324 1.4 christos compress_test(&name1, &name2, &name3, plain, sizeof(plain), plain,
325 1.4 christos sizeof(plain), &cctx, dctx, false);
326 1.1 christos
327 1.1 christos dns_compress_rollback(&cctx, 0);
328 1.1 christos dns_compress_invalidate(&cctx);
329 1.1 christos
330 1.4 christos /* Test7: on, owner */
331 1.4 christos permitted = true;
332 1.4 christos dns_compress_init(&cctx, mctx, 0);
333 1.4 christos dns_compress_setpermitted(&cctx, permitted);
334 1.4 christos dctx = dns_decompress_setpermitted(DNS_DECOMPRESS_DEFAULT, permitted);
335 1.1 christos
336 1.5 christos compress_test(&name1, &name2, &name3, compressed, compressed_len, plain,
337 1.5 christos sizeof(plain), &cctx, dctx, false);
338 1.4 christos
339 1.4 christos dns_compress_rollback(&cctx, 0);
340 1.4 christos dns_compress_invalidate(&cctx);
341 1.4 christos
342 1.4 christos /* Test8: off, disabled, owner */
343 1.4 christos permitted = false;
344 1.4 christos dns_compress_init(&cctx, mctx, DNS_COMPRESS_DISABLED);
345 1.4 christos dns_compress_setpermitted(&cctx, permitted);
346 1.4 christos dctx = dns_decompress_setpermitted(DNS_DECOMPRESS_DEFAULT, permitted);
347 1.4 christos
348 1.4 christos compress_test(&name1, &name2, &name3, plain, sizeof(plain), plain,
349 1.4 christos sizeof(plain), &cctx, dctx, false);
350 1.4 christos
351 1.4 christos dns_compress_rollback(&cctx, 0);
352 1.4 christos dns_compress_invalidate(&cctx);
353 1.4 christos
354 1.4 christos /* Test9: on, disabled, owner */
355 1.4 christos permitted = true;
356 1.4 christos dns_compress_init(&cctx, mctx, DNS_COMPRESS_DISABLED);
357 1.4 christos dns_compress_setpermitted(&cctx, permitted);
358 1.4 christos dctx = dns_decompress_setpermitted(DNS_DECOMPRESS_DEFAULT, permitted);
359 1.4 christos
360 1.4 christos compress_test(&name1, &name2, &name3, disabled_owner,
361 1.4 christos sizeof(disabled_owner), plain, sizeof(plain), &cctx, dctx,
362 1.4 christos false);
363 1.4 christos
364 1.4 christos dns_compress_rollback(&cctx, 0);
365 1.4 christos dns_compress_invalidate(&cctx);
366 1.4 christos
367 1.4 christos /* Test10: on, owner */
368 1.4 christos permitted = true;
369 1.4 christos dns_compress_init(&cctx, mctx, 0);
370 1.4 christos dns_compress_setpermitted(&cctx, permitted);
371 1.4 christos dctx = dns_decompress_setpermitted(DNS_DECOMPRESS_DEFAULT, permitted);
372 1.4 christos
373 1.4 christos compress_test(&name1, dns_rootname, &name4, root_plain,
374 1.4 christos sizeof(root_plain), root_plain, sizeof(root_plain), &cctx,
375 1.4 christos dctx, false);
376 1.1 christos
377 1.1 christos dns_compress_rollback(&cctx, 0);
378 1.1 christos dns_compress_invalidate(&cctx);
379 1.1 christos }
380 1.1 christos
381 1.4 christos #define NAME_LO 25
382 1.4 christos #define NAME_HI 250000
383 1.4 christos
384 1.4 christos /*
385 1.4 christos * test compression context hash set collisions and rollbacks
386 1.4 christos */
387 1.4 christos ISC_RUN_TEST_IMPL(collision) {
388 1.4 christos isc_result_t result;
389 1.4 christos isc_region_t r;
390 1.4 christos dns_compress_t cctx;
391 1.4 christos isc_buffer_t message;
392 1.4 christos uint8_t msgbuf[65536];
393 1.4 christos dns_name_t name;
394 1.4 christos char namebuf[256];
395 1.4 christos uint8_t offsets[128];
396 1.4 christos
397 1.4 christos dns_compress_init(&cctx, mctx, DNS_COMPRESS_LARGE);
398 1.4 christos isc_buffer_init(&message, msgbuf, sizeof(msgbuf));
399 1.4 christos dns_name_init(&name, offsets);
400 1.4 christos
401 1.4 christos /*
402 1.4 christos * compression offsets are not allowed to be zero so our
403 1.4 christos * names need to start after a little fake header
404 1.4 christos */
405 1.4 christos isc_buffer_putuint16(&message, 0xEAD);
406 1.4 christos
407 1.4 christos static const char zone[] = "test";
408 1.4 christos const int zonelen = sizeof(zone) - 1;
409 1.4 christos unsigned int zone_coff = 0;
410 1.4 christos
411 1.4 christos for (int i = NAME_LO; i < NAME_HI; i++) {
412 1.4 christos unsigned int prefix_len, suffix_coff;
413 1.4 christos unsigned int coff = isc_buffer_usedlength(&message);
414 1.4 christos
415 1.4 christos int len = snprintf(namebuf, sizeof(namebuf), ".%d%c%s", i,
416 1.4 christos zonelen, zone);
417 1.4 christos namebuf[0] = len - zonelen - 2;
418 1.4 christos r = (isc_region_t){ .base = (uint8_t *)namebuf,
419 1.4 christos .length = len + 1 };
420 1.4 christos dns_name_fromregion(&name, &r);
421 1.4 christos
422 1.4 christos /* the name we are about to add must partially match */
423 1.4 christos prefix_len = name.length;
424 1.4 christos suffix_coff = 0;
425 1.4 christos dns_compress_name(&cctx, &message, &name, &prefix_len,
426 1.4 christos &suffix_coff);
427 1.4 christos if (i == NAME_LO) {
428 1.4 christos assert_int_equal(prefix_len, name.length);
429 1.4 christos assert_int_equal(suffix_coff, 0);
430 1.4 christos zone_coff = 2 + len - zonelen - 1;
431 1.4 christos } else {
432 1.4 christos assert_int_equal(prefix_len, len - zonelen - 1);
433 1.4 christos assert_int_equal(suffix_coff, zone_coff);
434 1.4 christos }
435 1.4 christos dns_compress_rollback(&cctx, coff);
436 1.4 christos
437 1.4 christos result = dns_name_towire(&name, &cctx, &message, NULL);
438 1.4 christos assert_int_equal(result, ISC_R_SUCCESS);
439 1.4 christos
440 1.4 christos /* we must be able to find the name we just added */
441 1.4 christos prefix_len = name.length;
442 1.4 christos suffix_coff = 0;
443 1.4 christos dns_compress_name(&cctx, &message, &name, &prefix_len,
444 1.4 christos &suffix_coff);
445 1.4 christos assert_int_equal(prefix_len, 0);
446 1.4 christos assert_int_equal(suffix_coff, coff);
447 1.4 christos
448 1.4 christos /* don't let the hash set get too full */
449 1.4 christos if (cctx.count > cctx.mask * 3 / 5) {
450 1.4 christos dns_compress_rollback(&cctx, zone_coff + zonelen + 2);
451 1.4 christos isc_buffer_clear(&message);
452 1.4 christos isc_buffer_add(&message, zone_coff + zonelen + 2);
453 1.4 christos }
454 1.4 christos }
455 1.4 christos
456 1.4 christos dns_compress_invalidate(&cctx);
457 1.4 christos }
458 1.4 christos
459 1.3 christos ISC_RUN_TEST_IMPL(fromregion) {
460 1.3 christos dns_name_t name;
461 1.3 christos isc_buffer_t b;
462 1.3 christos isc_region_t r;
463 1.3 christos /*
464 1.3 christos * target and source need to be bigger than DNS_NAME_MAXWIRE to
465 1.3 christos * exercise 'len > DNS_NAME_MAXWIRE' test in dns_name_fromwire
466 1.3 christos */
467 1.3 christos unsigned char target[DNS_NAME_MAXWIRE + 10];
468 1.3 christos unsigned char source[DNS_NAME_MAXWIRE + 10] = { '\007', 'e', 'x', 'a',
469 1.3 christos 'm', 'p', 'l', 'e' };
470 1.3 christos /*
471 1.3 christos * Extract the fully qualified name at the beginning of 'source'
472 1.3 christos * into 'name' where 'name.ndata' points to the buffer 'target'.
473 1.3 christos */
474 1.3 christos isc_buffer_init(&b, target, sizeof(target));
475 1.3 christos dns_name_init(&name, NULL);
476 1.3 christos dns_name_setbuffer(&name, &b);
477 1.3 christos r.base = source;
478 1.3 christos r.length = sizeof(source);
479 1.3 christos dns_name_fromregion(&name, &r);
480 1.3 christos assert_int_equal(9, name.length);
481 1.3 christos assert_ptr_equal(target, name.ndata);
482 1.3 christos assert_true(dns_name_isabsolute(&name));
483 1.3 christos
484 1.3 christos /*
485 1.3 christos * Extract the fully qualified name at the beginning of 'source'
486 1.3 christos * into 'name' where 'name.ndata' points to the source.
487 1.3 christos */
488 1.3 christos isc_buffer_init(&b, target, sizeof(target));
489 1.3 christos dns_name_init(&name, NULL);
490 1.3 christos r.base = source;
491 1.3 christos r.length = sizeof(source);
492 1.3 christos dns_name_fromregion(&name, &r);
493 1.3 christos assert_int_equal(9, name.length);
494 1.3 christos assert_ptr_equal(source, name.ndata);
495 1.3 christos assert_true(dns_name_isabsolute(&name));
496 1.3 christos
497 1.3 christos /*
498 1.3 christos * Extract the partially qualified name in 'source' into 'name'
499 1.3 christos * where 'name.ndata' points to the source.
500 1.3 christos */
501 1.3 christos isc_buffer_init(&b, target, sizeof(target));
502 1.3 christos dns_name_init(&name, NULL);
503 1.3 christos r.base = source;
504 1.3 christos r.length = 8;
505 1.3 christos dns_name_fromregion(&name, &r);
506 1.3 christos assert_int_equal(8, name.length);
507 1.3 christos assert_ptr_equal(source, name.ndata);
508 1.3 christos assert_false(dns_name_isabsolute(&name));
509 1.3 christos
510 1.3 christos /*
511 1.3 christos * Extract empty name in 'source' into 'name'.
512 1.3 christos */
513 1.3 christos isc_buffer_init(&b, target, sizeof(target));
514 1.3 christos dns_name_init(&name, NULL);
515 1.3 christos r.base = source;
516 1.3 christos r.length = 0;
517 1.3 christos dns_name_fromregion(&name, &r);
518 1.3 christos assert_int_equal(0, name.length);
519 1.3 christos assert_ptr_equal(source, name.ndata);
520 1.3 christos assert_false(dns_name_isabsolute(&name));
521 1.3 christos }
522 1.3 christos
523 1.1 christos /* is trust-anchor-telemetry test */
524 1.1 christos ISC_RUN_TEST_IMPL(istat) {
525 1.1 christos dns_fixedname_t fixed;
526 1.1 christos dns_name_t *name;
527 1.1 christos isc_result_t result;
528 1.1 christos size_t i;
529 1.1 christos struct {
530 1.1 christos const char *name;
531 1.1 christos bool istat;
532 1.1 christos } data[] = { { ".", false },
533 1.1 christos { "_ta-", false },
534 1.1 christos { "_ta-1234", true },
535 1.1 christos { "_TA-1234", true },
536 1.1 christos { "+TA-1234", false },
537 1.1 christos { "_fa-1234", false },
538 1.1 christos { "_td-1234", false },
539 1.1 christos { "_ta_1234", false },
540 1.1 christos { "_ta-g234", false },
541 1.1 christos { "_ta-1h34", false },
542 1.1 christos { "_ta-12i4", false },
543 1.1 christos { "_ta-123j", false },
544 1.1 christos { "_ta-1234-abcf", true },
545 1.1 christos { "_ta-1234-abcf-ED89", true },
546 1.1 christos { "_ta-12345-abcf-ED89", false },
547 1.1 christos { "_ta-.example", false },
548 1.1 christos { "_ta-1234.example", true },
549 1.1 christos { "_ta-1234-abcf.example", true },
550 1.1 christos { "_ta-1234-abcf-ED89.example", true },
551 1.1 christos { "_ta-12345-abcf-ED89.example", false },
552 1.1 christos { "_ta-1234-abcfe-ED89.example", false },
553 1.1 christos { "_ta-1234-abcf-EcD89.example", false } };
554 1.1 christos
555 1.1 christos UNUSED(state);
556 1.1 christos
557 1.1 christos name = dns_fixedname_initname(&fixed);
558 1.1 christos
559 1.1 christos for (i = 0; i < (sizeof(data) / sizeof(data[0])); i++) {
560 1.4 christos result = dns_name_fromstring(name, data[i].name, dns_rootname,
561 1.4 christos 0, NULL);
562 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
563 1.1 christos assert_int_equal(dns_name_istat(name), data[i].istat);
564 1.1 christos }
565 1.1 christos }
566 1.1 christos
567 1.4 christos static bool
568 1.4 christos name_attr_zero(struct dns_name_attrs attributes) {
569 1.4 christos return !(attributes.absolute | attributes.readonly |
570 1.4 christos attributes.dynamic | attributes.dynoffsets |
571 1.4 christos attributes.nocompress | attributes.cache | attributes.answer |
572 1.4 christos attributes.ncache | attributes.chaining | attributes.chase |
573 1.4 christos attributes.wildcard | attributes.prerequisite |
574 1.4 christos attributes.update | attributes.hasupdaterec);
575 1.4 christos }
576 1.4 christos
577 1.4 christos /* dns_name_init */
578 1.1 christos ISC_RUN_TEST_IMPL(init) {
579 1.1 christos dns_name_t name;
580 1.1 christos unsigned char offsets[1];
581 1.1 christos
582 1.1 christos UNUSED(state);
583 1.1 christos
584 1.1 christos dns_name_init(&name, offsets);
585 1.1 christos
586 1.1 christos assert_null(name.ndata);
587 1.1 christos assert_int_equal(name.length, 0);
588 1.1 christos assert_int_equal(name.labels, 0);
589 1.1 christos assert_ptr_equal(name.offsets, offsets);
590 1.1 christos assert_null(name.buffer);
591 1.4 christos assert_true(name_attr_zero(name.attributes));
592 1.1 christos }
593 1.1 christos
594 1.4 christos /* dns_name_invalidate */
595 1.1 christos ISC_RUN_TEST_IMPL(invalidate) {
596 1.1 christos dns_name_t name;
597 1.1 christos unsigned char offsets[1];
598 1.1 christos
599 1.1 christos UNUSED(state);
600 1.1 christos
601 1.1 christos dns_name_init(&name, offsets);
602 1.1 christos dns_name_invalidate(&name);
603 1.1 christos
604 1.1 christos assert_null(name.ndata);
605 1.1 christos assert_int_equal(name.length, 0);
606 1.1 christos assert_int_equal(name.labels, 0);
607 1.1 christos assert_null(name.offsets);
608 1.1 christos assert_null(name.buffer);
609 1.4 christos assert_true(name_attr_zero(name.attributes));
610 1.1 christos }
611 1.1 christos
612 1.4 christos /* dns_name_setbuffer/hasbuffer */
613 1.1 christos ISC_RUN_TEST_IMPL(buffer) {
614 1.1 christos dns_name_t name;
615 1.1 christos unsigned char buf[BUFSIZ];
616 1.1 christos isc_buffer_t b;
617 1.1 christos
618 1.1 christos UNUSED(state);
619 1.1 christos
620 1.1 christos isc_buffer_init(&b, buf, BUFSIZ);
621 1.1 christos dns_name_init(&name, NULL);
622 1.1 christos dns_name_setbuffer(&name, &b);
623 1.1 christos assert_ptr_equal(name.buffer, &b);
624 1.1 christos assert_true(dns_name_hasbuffer(&name));
625 1.1 christos }
626 1.1 christos
627 1.4 christos /* dns_name_isabsolute */
628 1.1 christos ISC_RUN_TEST_IMPL(isabsolute) {
629 1.1 christos struct {
630 1.1 christos const char *namestr;
631 1.1 christos bool expect;
632 1.1 christos } testcases[] = { { "x", false },
633 1.1 christos { "a.b.c.d.", true },
634 1.1 christos { "x.z", false } };
635 1.1 christos unsigned int i;
636 1.1 christos
637 1.1 christos UNUSED(state);
638 1.1 christos
639 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
640 1.1 christos isc_result_t result;
641 1.1 christos dns_name_t name;
642 1.1 christos unsigned char data[BUFSIZ];
643 1.1 christos isc_buffer_t b, nb;
644 1.1 christos size_t len;
645 1.1 christos
646 1.1 christos len = strlen(testcases[i].namestr);
647 1.1 christos isc_buffer_constinit(&b, testcases[i].namestr, len);
648 1.1 christos isc_buffer_add(&b, len);
649 1.1 christos
650 1.1 christos dns_name_init(&name, NULL);
651 1.1 christos isc_buffer_init(&nb, data, BUFSIZ);
652 1.1 christos dns_name_setbuffer(&name, &nb);
653 1.1 christos result = dns_name_fromtext(&name, &b, NULL, 0, NULL);
654 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
655 1.1 christos
656 1.1 christos assert_int_equal(dns_name_isabsolute(&name),
657 1.1 christos testcases[i].expect);
658 1.1 christos }
659 1.1 christos }
660 1.1 christos
661 1.4 christos /* dns_name_hash */
662 1.1 christos ISC_RUN_TEST_IMPL(hash) {
663 1.1 christos struct {
664 1.1 christos const char *name1;
665 1.1 christos const char *name2;
666 1.1 christos bool expect;
667 1.1 christos bool expecti;
668 1.1 christos } testcases[] = {
669 1.1 christos { "a.b.c.d", "A.B.C.D", true, false },
670 1.1 christos { "a.b.c.d.", "A.B.C.D.", true, false },
671 1.1 christos { "a.b.c.d", "a.b.c.d", true, true },
672 1.1 christos { "A.B.C.D.", "A.B.C.D.", true, false },
673 1.1 christos { "x.y.z.w", "a.b.c.d", false, false },
674 1.1 christos { "x.y.z.w.", "a.b.c.d.", false, false },
675 1.1 christos };
676 1.1 christos unsigned int i;
677 1.1 christos
678 1.1 christos UNUSED(state);
679 1.1 christos
680 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
681 1.1 christos isc_result_t result;
682 1.1 christos dns_fixedname_t f1, f2;
683 1.1 christos dns_name_t *n1, *n2;
684 1.1 christos unsigned int h1, h2;
685 1.1 christos
686 1.1 christos n1 = dns_fixedname_initname(&f1);
687 1.1 christos n2 = dns_fixedname_initname(&f2);
688 1.1 christos
689 1.4 christos result = dns_name_fromstring(n1, testcases[i].name1, NULL, 0,
690 1.4 christos NULL);
691 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
692 1.4 christos result = dns_name_fromstring(n2, testcases[i].name2, NULL, 0,
693 1.4 christos NULL);
694 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
695 1.1 christos
696 1.1 christos /* Check case-insensitive hashing first */
697 1.4 christos h1 = dns_name_hash(n1);
698 1.4 christos h2 = dns_name_hash(n2);
699 1.1 christos
700 1.1 christos if (verbose) {
701 1.1 christos print_message("# %s hashes to %u, "
702 1.1 christos "%s to %u, case insensitive\n",
703 1.1 christos testcases[i].name1, h1,
704 1.1 christos testcases[i].name2, h2);
705 1.1 christos }
706 1.1 christos
707 1.6 christos assert_int_equal(h1 == h2, testcases[i].expect);
708 1.1 christos
709 1.1 christos /* Now case-sensitive */
710 1.4 christos h1 = dns_name_hash(n1);
711 1.4 christos h2 = dns_name_hash(n2);
712 1.1 christos
713 1.1 christos if (verbose) {
714 1.1 christos print_message("# %s hashes to %u, "
715 1.1 christos "%s to %u, case sensitive\n",
716 1.1 christos testcases[i].name1, h1,
717 1.1 christos testcases[i].name2, h2);
718 1.1 christos }
719 1.1 christos
720 1.6 christos assert_int_equal(h1 == h2, testcases[i].expect);
721 1.1 christos }
722 1.1 christos }
723 1.1 christos
724 1.4 christos /* dns_name_issubdomain */
725 1.1 christos ISC_RUN_TEST_IMPL(issubdomain) {
726 1.1 christos struct {
727 1.1 christos const char *name1;
728 1.1 christos const char *name2;
729 1.1 christos bool expect;
730 1.1 christos } testcases[] = {
731 1.1 christos { "c.d", "a.b.c.d", false }, { "c.d.", "a.b.c.d.", false },
732 1.1 christos { "b.c.d", "c.d", true }, { "a.b.c.d.", "c.d.", true },
733 1.1 christos { "a.b.c", "a.b.c", true }, { "a.b.c.", "a.b.c.", true },
734 1.1 christos { "x.y.z", "a.b.c", false }
735 1.1 christos };
736 1.1 christos unsigned int i;
737 1.1 christos
738 1.1 christos UNUSED(state);
739 1.1 christos
740 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
741 1.1 christos isc_result_t result;
742 1.1 christos dns_fixedname_t f1, f2;
743 1.1 christos dns_name_t *n1, *n2;
744 1.1 christos
745 1.1 christos n1 = dns_fixedname_initname(&f1);
746 1.1 christos n2 = dns_fixedname_initname(&f2);
747 1.1 christos
748 1.4 christos result = dns_name_fromstring(n1, testcases[i].name1, NULL, 0,
749 1.4 christos NULL);
750 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
751 1.4 christos result = dns_name_fromstring(n2, testcases[i].name2, NULL, 0,
752 1.4 christos NULL);
753 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
754 1.1 christos
755 1.1 christos if (verbose) {
756 1.1 christos print_message("# check: %s %s a subdomain of %s\n",
757 1.1 christos testcases[i].name1,
758 1.1 christos testcases[i].expect ? "is" : "is not",
759 1.1 christos testcases[i].name2);
760 1.1 christos }
761 1.1 christos
762 1.1 christos assert_int_equal(dns_name_issubdomain(n1, n2),
763 1.1 christos testcases[i].expect);
764 1.1 christos }
765 1.1 christos }
766 1.1 christos
767 1.4 christos /* dns_name_countlabels */
768 1.1 christos ISC_RUN_TEST_IMPL(countlabels) {
769 1.1 christos struct {
770 1.1 christos const char *namestr;
771 1.1 christos unsigned int expect;
772 1.1 christos } testcases[] = {
773 1.4 christos { "c.d", 2 },
774 1.4 christos { "c.d.", 3 },
775 1.4 christos { "a.b.c.d.", 5 },
776 1.4 christos { "a.b.c.d", 4 },
777 1.4 christos { "a.b.c", 3 },
778 1.4 christos { ".", 1 },
779 1.4 christos { "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y."
780 1.4 christos "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y."
781 1.4 christos "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y."
782 1.4 christos "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y."
783 1.4 christos "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y."
784 1.4 christos "a.b.",
785 1.4 christos 128 },
786 1.1 christos };
787 1.1 christos unsigned int i;
788 1.1 christos
789 1.1 christos UNUSED(state);
790 1.1 christos
791 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
792 1.1 christos isc_result_t result;
793 1.1 christos dns_fixedname_t fname;
794 1.1 christos dns_name_t *name;
795 1.1 christos
796 1.1 christos name = dns_fixedname_initname(&fname);
797 1.1 christos
798 1.4 christos result = dns_name_fromstring(name, testcases[i].namestr, NULL,
799 1.4 christos 0, NULL);
800 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
801 1.1 christos
802 1.1 christos if (verbose) {
803 1.1 christos print_message("# %s: expect %u labels\n",
804 1.1 christos testcases[i].namestr,
805 1.1 christos testcases[i].expect);
806 1.1 christos }
807 1.1 christos
808 1.1 christos assert_int_equal(dns_name_countlabels(name),
809 1.1 christos testcases[i].expect);
810 1.1 christos }
811 1.1 christos }
812 1.1 christos
813 1.4 christos /* dns_name_getlabel */
814 1.1 christos ISC_RUN_TEST_IMPL(getlabel) {
815 1.1 christos struct {
816 1.1 christos const char *name1;
817 1.1 christos unsigned int pos1;
818 1.1 christos const char *name2;
819 1.1 christos unsigned int pos2;
820 1.1 christos } testcases[] = {
821 1.1 christos { "c.d", 1, "a.b.c.d", 3 },
822 1.1 christos { "a.b.c.d", 3, "c.d", 1 },
823 1.1 christos { "a.b.c.", 3, "A.B.C.", 3 },
824 1.1 christos };
825 1.1 christos unsigned int i;
826 1.1 christos
827 1.1 christos UNUSED(state);
828 1.1 christos
829 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
830 1.1 christos isc_result_t result;
831 1.1 christos dns_fixedname_t f1, f2;
832 1.1 christos dns_name_t *n1, *n2;
833 1.1 christos dns_label_t l1, l2;
834 1.1 christos unsigned int j;
835 1.1 christos
836 1.1 christos n1 = dns_fixedname_initname(&f1);
837 1.1 christos n2 = dns_fixedname_initname(&f2);
838 1.1 christos
839 1.4 christos result = dns_name_fromstring(n1, testcases[i].name1, NULL, 0,
840 1.4 christos NULL);
841 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
842 1.4 christos result = dns_name_fromstring(n2, testcases[i].name2, NULL, 0,
843 1.4 christos NULL);
844 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
845 1.1 christos
846 1.1 christos dns_name_getlabel(n1, testcases[i].pos1, &l1);
847 1.1 christos dns_name_getlabel(n2, testcases[i].pos2, &l2);
848 1.1 christos assert_int_equal(l1.length, l2.length);
849 1.1 christos
850 1.1 christos for (j = 0; j < l1.length; j++) {
851 1.1 christos assert_int_equal(l1.base[j], l2.base[j]);
852 1.1 christos }
853 1.1 christos }
854 1.1 christos }
855 1.1 christos
856 1.4 christos /* dns_name_getlabelsequence */
857 1.1 christos ISC_RUN_TEST_IMPL(getlabelsequence) {
858 1.1 christos struct {
859 1.1 christos const char *name1;
860 1.1 christos unsigned int pos1;
861 1.1 christos const char *name2;
862 1.1 christos unsigned int pos2;
863 1.1 christos unsigned int range;
864 1.1 christos } testcases[] = {
865 1.1 christos { "c.d", 1, "a.b.c.d", 3, 1 },
866 1.1 christos { "a.b.c.d.e", 2, "c.d", 0, 2 },
867 1.1 christos { "a.b.c", 0, "a.b.c", 0, 3 },
868 1.1 christos };
869 1.1 christos unsigned int i;
870 1.1 christos
871 1.1 christos UNUSED(state);
872 1.1 christos
873 1.1 christos for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
874 1.1 christos isc_result_t result;
875 1.1 christos dns_name_t t1, t2;
876 1.1 christos dns_fixedname_t f1, f2;
877 1.1 christos dns_name_t *n1, *n2;
878 1.1 christos
879 1.1 christos /* target names */
880 1.1 christos dns_name_init(&t1, NULL);
881 1.1 christos dns_name_init(&t2, NULL);
882 1.1 christos
883 1.1 christos /* source names */
884 1.1 christos n1 = dns_fixedname_initname(&f1);
885 1.1 christos n2 = dns_fixedname_initname(&f2);
886 1.1 christos
887 1.4 christos result = dns_name_fromstring(n1, testcases[i].name1, NULL, 0,
888 1.4 christos NULL);
889 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
890 1.4 christos result = dns_name_fromstring(n2, testcases[i].name2, NULL, 0,
891 1.4 christos NULL);
892 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
893 1.1 christos
894 1.1 christos dns_name_getlabelsequence(n1, testcases[i].pos1,
895 1.1 christos testcases[i].range, &t1);
896 1.1 christos dns_name_getlabelsequence(n2, testcases[i].pos2,
897 1.1 christos testcases[i].range, &t2);
898 1.1 christos
899 1.1 christos assert_true(dns_name_equal(&t1, &t2));
900 1.1 christos }
901 1.1 christos }
902 1.1 christos
903 1.4 christos ISC_RUN_TEST_IMPL(maxlabels) {
904 1.4 christos isc_result_t result;
905 1.4 christos dns_fixedname_t fixed;
906 1.4 christos dns_name_t *name = NULL;
907 1.4 christos
908 1.4 christos const char one_too_many[] =
909 1.4 christos "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y."
910 1.4 christos "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y."
911 1.4 christos "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y."
912 1.4 christos "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y."
913 1.4 christos "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y."
914 1.4 christos "a.b.c.";
915 1.4 christos
916 1.4 christos name = dns_fixedname_initname(&fixed);
917 1.4 christos result = dns_name_fromstring(name, one_too_many, dns_rootname, 0, NULL);
918 1.4 christos assert_int_equal(result, ISC_R_NOSPACE);
919 1.4 christos
920 1.4 christos name = dns_fixedname_initname(&fixed);
921 1.4 christos result = dns_name_fromstring(name, one_too_many + 2, dns_rootname, 0,
922 1.4 christos NULL);
923 1.4 christos assert_int_equal(result, ISC_R_SUCCESS);
924 1.4 christos assert_true(dns_name_isvalid(name));
925 1.4 christos assert_int_equal(dns_name_countlabels(name), DNS_NAME_MAXLABELS);
926 1.4 christos }
927 1.4 christos
928 1.1 christos #ifdef DNS_BENCHMARK_TESTS
929 1.1 christos
930 1.1 christos /*
931 1.1 christos * XXXMUKS: Don't delete this code. It is useful in benchmarking the
932 1.1 christos * name parser, but we don't require it as part of the unit test runs.
933 1.1 christos */
934 1.1 christos
935 1.1 christos /* Benchmark dns_name_fromwire() implementation */
936 1.1 christos
937 1.1 christos ISC_RUN_TEST_IMPL(fromwire_thread(void *arg) {
938 1.1 christos unsigned int maxval = 32000000;
939 1.1 christos uint8_t data[] = { 3, 'w', 'w', 'w', 7, 'e', 'x',
940 1.1 christos 'a', 'm', 'p', 'l', 'e', 7, 'i',
941 1.1 christos 'n', 'v', 'a', 'l', 'i', 'd', 0 };
942 1.1 christos unsigned char output_data[DNS_NAME_MAXWIRE];
943 1.1 christos isc_buffer_t source, target;
944 1.1 christos unsigned int i;
945 1.1 christos dns_decompress_t dctx;
946 1.1 christos
947 1.1 christos UNUSED(arg);
948 1.1 christos
949 1.4 christos dns_decompress_init(&dctx, DNS_DECOMPRESS_STRICT);
950 1.1 christos dns_decompress_setmethods(&dctx, DNS_COMPRESS_NONE);
951 1.1 christos
952 1.1 christos isc_buffer_init(&source, data, sizeof(data));
953 1.1 christos isc_buffer_add(&source, sizeof(data));
954 1.1 christos isc_buffer_init(&target, output_data, sizeof(output_data));
955 1.1 christos
956 1.1 christos /* Parse 32 million names in each thread */
957 1.1 christos for (i = 0; i < maxval; i++) {
958 1.1 christos dns_name_t name;
959 1.1 christos
960 1.1 christos isc_buffer_clear(&source);
961 1.1 christos isc_buffer_clear(&target);
962 1.1 christos isc_buffer_add(&source, sizeof(data));
963 1.1 christos isc_buffer_setactive(&source, sizeof(data));
964 1.1 christos
965 1.1 christos dns_name_init(&name, NULL);
966 1.4 christos (void)dns_name_fromwire(&name, &source, &dctx, &target);
967 1.1 christos }
968 1.1 christos
969 1.4 christos return NULL;
970 1.1 christos }
971 1.1 christos
972 1.1 christos ISC_RUN_TEST_IMPL(benchmark) {
973 1.1 christos isc_result_t result;
974 1.1 christos unsigned int i;
975 1.1 christos isc_time_t ts1, ts2;
976 1.1 christos double t;
977 1.1 christos unsigned int nthreads;
978 1.1 christos isc_thread_t threads[32];
979 1.1 christos
980 1.1 christos UNUSED(state);
981 1.1 christos
982 1.1 christos debug_mem_record = false;
983 1.1 christos
984 1.1 christos result = isc_time_now(&ts1);
985 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
986 1.1 christos
987 1.1 christos nthreads = ISC_MIN(isc_os_ncpus(), 32);
988 1.1 christos nthreads = ISC_MAX(nthreads, 1);
989 1.1 christos for (i = 0; i < nthreads; i++) {
990 1.1 christos isc_thread_create(fromwire_thread, NULL, &threads[i]);
991 1.1 christos }
992 1.1 christos
993 1.1 christos for (i = 0; i < nthreads; i++) {
994 1.1 christos isc_thread_join(threads[i], NULL);
995 1.1 christos }
996 1.1 christos
997 1.1 christos result = isc_time_now(&ts2);
998 1.1 christos assert_int_equal(result, ISC_R_SUCCESS);
999 1.1 christos
1000 1.1 christos t = isc_time_microdiff(&ts2, &ts1);
1001 1.1 christos
1002 1.1 christos printf("%u dns_name_fromwire() calls, %f seconds, %f calls/second\n",
1003 1.1 christos nthreads * 32000000, t / 1000000.0,
1004 1.1 christos (nthreads * 32000000) / (t / 1000000.0));
1005 1.1 christos }
1006 1.1 christos
1007 1.1 christos #endif /* DNS_BENCHMARK_TESTS */
1008 1.1 christos
1009 1.1 christos ISC_TEST_LIST_START
1010 1.1 christos ISC_TEST_ENTRY(fullcompare)
1011 1.1 christos ISC_TEST_ENTRY(compression)
1012 1.4 christos ISC_TEST_ENTRY(collision)
1013 1.3 christos ISC_TEST_ENTRY(fromregion)
1014 1.1 christos ISC_TEST_ENTRY(istat)
1015 1.1 christos ISC_TEST_ENTRY(init)
1016 1.1 christos ISC_TEST_ENTRY(invalidate)
1017 1.1 christos ISC_TEST_ENTRY(buffer)
1018 1.1 christos ISC_TEST_ENTRY(isabsolute)
1019 1.1 christos ISC_TEST_ENTRY(hash)
1020 1.1 christos ISC_TEST_ENTRY(issubdomain)
1021 1.1 christos ISC_TEST_ENTRY(countlabels)
1022 1.1 christos ISC_TEST_ENTRY(getlabel)
1023 1.1 christos ISC_TEST_ENTRY(getlabelsequence)
1024 1.4 christos ISC_TEST_ENTRY(maxlabels)
1025 1.1 christos #ifdef DNS_BENCHMARK_TESTS
1026 1.1 christos ISC_TEST_ENTRY(benchmark)
1027 1.1 christos #endif /* DNS_BENCHMARK_TESTS */
1028 1.1 christos ISC_TEST_LIST_END
1029 1.1 christos
1030 1.1 christos ISC_TEST_MAIN
1031