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