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