1 /* $NetBSD: dispatch_test.c,v 1.3 2025/01/26 16:25:47 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 #include <inttypes.h> 17 #include <sched.h> /* IWYU pragma: keep */ 18 #include <setjmp.h> 19 #include <stdarg.h> 20 #include <stdbool.h> 21 #include <stddef.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <unistd.h> 25 26 #define UNIT_TESTING 27 #include <cmocka.h> 28 29 #include <isc/buffer.h> 30 #include <isc/managers.h> 31 #include <isc/refcount.h> 32 #include <isc/tls.h> 33 #include <isc/util.h> 34 #include <isc/uv.h> 35 36 #include <dns/dispatch.h> 37 #include <dns/name.h> 38 #include <dns/view.h> 39 40 #include <tests/dns.h> 41 42 /* Timeouts in miliseconds */ 43 #define T_SERVER_INIT (120 * 1000) 44 #define T_SERVER_IDLE (120 * 1000) 45 #define T_SERVER_KEEPALIVE (120 * 1000) 46 #define T_SERVER_ADVERTISED (120 * 1000) 47 48 #define T_CLIENT_INIT (120 * 1000) 49 #define T_CLIENT_IDLE (120 * 1000) 50 #define T_CLIENT_KEEPALIVE (120 * 1000) 51 #define T_CLIENT_ADVERTISED (120 * 1000) 52 53 #define T_CLIENT_CONNECT (30 * 1000) 54 55 /* For checks which are expected to timeout */ 56 #define T_CLIENT_CONNECT_SHORT (10 * 1000) 57 58 /* dns_dispatchset_t *dset = NULL; */ 59 static isc_sockaddr_t udp_server_addr; 60 static isc_sockaddr_t udp_connect_addr; 61 static isc_sockaddr_t tcp_server_addr; 62 static isc_sockaddr_t tcp_connect_addr; 63 static isc_sockaddr_t tls_server_addr; 64 static isc_sockaddr_t tls_connect_addr; 65 66 static isc_tlsctx_cache_t *tls_tlsctx_client_cache = NULL; 67 static isc_tlsctx_t *tls_listen_tlsctx = NULL; 68 static dns_name_t tls_name; 69 static const char *tls_name_str = "ephemeral"; 70 static dns_transport_t *tls_transport = NULL; 71 static dns_transport_list_t *transport_list = NULL; 72 73 static isc_nmsocket_t *sock = NULL; 74 75 static isc_nm_t *connect_nm = NULL; 76 77 const struct in6_addr in6addr_blackhole = { { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78 0, 0, 0, 0, 1 } } }; 79 80 struct { 81 uint8_t rbuf[12]; 82 isc_region_t region; 83 uint8_t message[12]; 84 } testdata; 85 86 typedef struct { 87 dns_dispatchmgr_t *dispatchmgr; 88 dns_dispatch_t *dispatch; 89 dns_dispentry_t *dispentry; 90 uint16_t id; 91 } test_dispatch_t; 92 93 static void 94 test_dispatch_done(test_dispatch_t *test) { 95 dns_dispatch_done(&test->dispentry); 96 dns_dispatch_detach(&test->dispatch); 97 dns_dispatchmgr_detach(&test->dispatchmgr); 98 isc_mem_put(mctx, test, sizeof(*test)); 99 } 100 101 static void 102 test_dispatch_shutdown(test_dispatch_t *test) { 103 test_dispatch_done(test); 104 isc_loopmgr_shutdown(loopmgr); 105 } 106 107 static int 108 setup_ephemeral_port(isc_sockaddr_t *addr, sa_family_t family) { 109 socklen_t addrlen = sizeof(*addr); 110 uv_os_sock_t fd; 111 int r; 112 113 isc_sockaddr_fromin6(addr, &in6addr_loopback, 0); 114 115 fd = socket(AF_INET6, family, 0); 116 if (fd < 0) { 117 perror("setup_ephemeral_port: socket()"); 118 return -1; 119 } 120 121 r = bind(fd, (const struct sockaddr *)&addr->type.sa, 122 sizeof(addr->type.sin6)); 123 if (r != 0) { 124 perror("setup_ephemeral_port: bind()"); 125 close(fd); 126 return r; 127 } 128 129 r = getsockname(fd, (struct sockaddr *)&addr->type.sa, &addrlen); 130 if (r != 0) { 131 perror("setup_ephemeral_port: getsockname()"); 132 close(fd); 133 return r; 134 } 135 136 #if IPV6_RECVERR 137 #define setsockopt_on(socket, level, name) \ 138 setsockopt(socket, level, name, &(int){ 1 }, sizeof(int)) 139 140 r = setsockopt_on(fd, IPPROTO_IPV6, IPV6_RECVERR); 141 if (r != 0) { 142 perror("setup_ephemeral_port"); 143 close(fd); 144 return r; 145 } 146 #endif 147 148 return fd; 149 } 150 151 static int 152 setup_test(void **state) { 153 isc_buffer_t namesrc, namebuf; 154 char namedata[DNS_NAME_FORMATSIZE + 1]; 155 156 uv_os_sock_t socket = -1; 157 158 /* Create just 1 loop for this test */ 159 isc_loopmgr_create(mctx, 1, &loopmgr); 160 mainloop = isc_loop_main(loopmgr); 161 162 setup_netmgr(state); 163 164 isc_netmgr_create(mctx, loopmgr, &connect_nm); 165 166 udp_connect_addr = (isc_sockaddr_t){ .length = 0 }; 167 isc_sockaddr_fromin6(&udp_connect_addr, &in6addr_loopback, 0); 168 169 tcp_connect_addr = (isc_sockaddr_t){ .length = 0 }; 170 isc_sockaddr_fromin6(&tcp_connect_addr, &in6addr_loopback, 0); 171 172 tls_connect_addr = (isc_sockaddr_t){ .length = 0 }; 173 isc_sockaddr_fromin6(&tls_connect_addr, &in6addr_loopback, 0); 174 175 udp_server_addr = (isc_sockaddr_t){ .length = 0 }; 176 socket = setup_ephemeral_port(&udp_server_addr, SOCK_DGRAM); 177 if (socket < 0) { 178 return -1; 179 } 180 close(socket); 181 182 tcp_server_addr = (isc_sockaddr_t){ .length = 0 }; 183 socket = setup_ephemeral_port(&tcp_server_addr, SOCK_STREAM); 184 if (socket < 0) { 185 return -1; 186 } 187 close(socket); 188 189 tls_server_addr = (isc_sockaddr_t){ .length = 0 }; 190 socket = setup_ephemeral_port(&tls_server_addr, SOCK_STREAM); 191 if (socket < 0) { 192 return -1; 193 } 194 close(socket); 195 196 isc_nm_settimeouts(netmgr, T_SERVER_INIT, T_SERVER_IDLE, 197 T_SERVER_KEEPALIVE, T_SERVER_ADVERTISED); 198 199 /* 200 * Use shorter client-side timeouts, to ensure that clients 201 * time out before the server. 202 */ 203 isc_nm_settimeouts(connect_nm, T_CLIENT_INIT, T_CLIENT_IDLE, 204 T_CLIENT_KEEPALIVE, T_CLIENT_ADVERTISED); 205 206 memset(testdata.rbuf, 0, sizeof(testdata.rbuf)); 207 testdata.region.base = testdata.rbuf; 208 testdata.region.length = sizeof(testdata.rbuf); 209 memset(testdata.message, 0, sizeof(testdata.message)); 210 211 isc_tlsctx_cache_create(mctx, &tls_tlsctx_client_cache); 212 213 if (isc_tlsctx_createserver(NULL, NULL, &tls_listen_tlsctx) != 214 ISC_R_SUCCESS) 215 { 216 return -1; 217 } 218 219 dns_name_init(&tls_name, NULL); 220 isc_buffer_constinit(&namesrc, tls_name_str, strlen(tls_name_str)); 221 isc_buffer_add(&namesrc, strlen(tls_name_str)); 222 isc_buffer_init(&namebuf, namedata, sizeof(namedata)); 223 if (dns_name_fromtext(&tls_name, &namesrc, dns_rootname, 224 DNS_NAME_DOWNCASE, &namebuf) != ISC_R_SUCCESS) 225 { 226 return -1; 227 } 228 transport_list = dns_transport_list_new(mctx); 229 tls_transport = dns_transport_new(&tls_name, DNS_TRANSPORT_TLS, 230 transport_list); 231 dns_transport_set_tlsname(tls_transport, tls_name_str); 232 233 return 0; 234 } 235 236 static int 237 teardown_test(void **state) { 238 dns_transport_list_detach(&transport_list); 239 isc_tlsctx_cache_detach(&tls_tlsctx_client_cache); 240 isc_tlsctx_free(&tls_listen_tlsctx); 241 242 isc_netmgr_destroy(&connect_nm); 243 244 teardown_netmgr(state); 245 teardown_loopmgr(state); 246 247 return 0; 248 } 249 250 static isc_result_t 251 make_dispatchset(dns_dispatchmgr_t *dispatchmgr, unsigned int ndisps, 252 dns_dispatchset_t **dsetp) { 253 isc_result_t result; 254 isc_sockaddr_t any; 255 dns_dispatch_t *disp = NULL; 256 257 isc_sockaddr_any(&any); 258 result = dns_dispatch_createudp(dispatchmgr, &any, &disp); 259 if (result != ISC_R_SUCCESS) { 260 return result; 261 } 262 263 result = dns_dispatchset_create(mctx, disp, dsetp, ndisps); 264 dns_dispatch_detach(&disp); 265 266 return result; 267 } 268 269 /* create dispatch set */ 270 ISC_LOOP_TEST_IMPL(dispatchset_create) { 271 dns_dispatchset_t *dset = NULL; 272 isc_result_t result; 273 dns_dispatchmgr_t *dispatchmgr = NULL; 274 275 UNUSED(arg); 276 277 result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, 278 &dispatchmgr); 279 assert_int_equal(result, ISC_R_SUCCESS); 280 281 result = make_dispatchset(dispatchmgr, 1, &dset); 282 assert_int_equal(result, ISC_R_SUCCESS); 283 dns_dispatchset_destroy(&dset); 284 285 result = make_dispatchset(dispatchmgr, 10, &dset); 286 assert_int_equal(result, ISC_R_SUCCESS); 287 dns_dispatchset_destroy(&dset); 288 289 dns_dispatchmgr_detach(&dispatchmgr); 290 291 isc_loopmgr_shutdown(loopmgr); 292 } 293 294 /* test dispatch set per-loop dispatch */ 295 ISC_LOOP_TEST_IMPL(dispatchset_get) { 296 isc_result_t result; 297 dns_dispatchmgr_t *dispatchmgr = NULL; 298 dns_dispatchset_t *dset = NULL; 299 dns_dispatch_t *d1, *d2, *d3, *d4, *d5; 300 uint32_t tid_saved; 301 302 UNUSED(arg); 303 304 result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, 305 &dispatchmgr); 306 assert_int_equal(result, ISC_R_SUCCESS); 307 308 result = make_dispatchset(dispatchmgr, 1, &dset); 309 assert_int_equal(result, ISC_R_SUCCESS); 310 311 d1 = dns_dispatchset_get(dset); 312 d2 = dns_dispatchset_get(dset); 313 d3 = dns_dispatchset_get(dset); 314 d4 = dns_dispatchset_get(dset); 315 d5 = dns_dispatchset_get(dset); 316 317 assert_ptr_equal(d1, d2); 318 assert_ptr_equal(d2, d3); 319 assert_ptr_equal(d3, d4); 320 assert_ptr_equal(d4, d5); 321 322 dns_dispatchset_destroy(&dset); 323 324 result = make_dispatchset(dispatchmgr, 4, &dset); 325 assert_int_equal(result, ISC_R_SUCCESS); 326 327 /* 328 * Temporarily modify and then restore the current thread's 329 * ID value, in order to confirm that different threads get 330 * different dispatch sets but the same thread gets the same 331 * one. 332 */ 333 tid_saved = isc__tid_local; 334 d1 = dns_dispatchset_get(dset); 335 isc__tid_local++; 336 d2 = dns_dispatchset_get(dset); 337 isc__tid_local++; 338 d3 = dns_dispatchset_get(dset); 339 isc__tid_local++; 340 d4 = dns_dispatchset_get(dset); 341 isc__tid_local = tid_saved; 342 d5 = dns_dispatchset_get(dset); 343 344 assert_ptr_equal(d1, d5); 345 assert_ptr_not_equal(d1, d2); 346 assert_ptr_not_equal(d2, d3); 347 assert_ptr_not_equal(d3, d4); 348 assert_ptr_not_equal(d4, d5); 349 350 dns_dispatchset_destroy(&dset); 351 dns_dispatchmgr_detach(&dispatchmgr); 352 isc_loopmgr_shutdown(loopmgr); 353 } 354 355 static atomic_bool first = true; 356 357 static void 358 server_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { 359 UNUSED(handle); 360 UNUSED(eresult); 361 UNUSED(arg); 362 363 return; 364 } 365 366 static void 367 nameserver(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, 368 void *arg ISC_ATTR_UNUSED) { 369 isc_region_t response1, response2; 370 static unsigned char buf1[16]; 371 static unsigned char buf2[16]; 372 373 if (eresult != ISC_R_SUCCESS) { 374 return; 375 } 376 377 memmove(buf1, region->base, 12); 378 memset(buf1 + 12, 0, 4); 379 buf1[2] |= 0x80; /* qr=1 */ 380 381 memmove(buf2, region->base, 12); 382 memset(buf2 + 12, 1, 4); 383 buf2[2] |= 0x80; /* qr=1 */ 384 385 /* 386 * send message to be discarded. 387 */ 388 response1.base = buf1; 389 response1.length = sizeof(buf1); 390 isc_nm_send(handle, &response1, server_senddone, NULL); 391 392 /* 393 * send nextitem message. 394 */ 395 response2.base = buf2; 396 response2.length = sizeof(buf2); 397 isc_nm_send(handle, &response2, server_senddone, NULL); 398 } 399 400 static isc_result_t 401 accept_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { 402 UNUSED(handle); 403 UNUSED(arg); 404 405 return eresult; 406 } 407 408 static void 409 noop_nameserver(isc_nmhandle_t *handle, isc_result_t eresult, 410 isc_region_t *region, void *arg) { 411 UNUSED(handle); 412 UNUSED(eresult); 413 UNUSED(region); 414 UNUSED(arg); 415 } 416 417 static void 418 response_getnext(isc_result_t result, isc_region_t *region ISC_ATTR_UNUSED, 419 void *arg) { 420 test_dispatch_t *test = arg; 421 422 if (atomic_compare_exchange_strong(&first, &(bool){ true }, false)) { 423 result = dns_dispatch_getnext(test->dispentry); 424 assert_int_equal(result, ISC_R_SUCCESS); 425 } else { 426 test_dispatch_shutdown(test); 427 } 428 } 429 430 static void 431 response_noop(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, 432 void *arg) { 433 test_dispatch_t *test = arg; 434 435 if (eresult == ISC_R_SUCCESS) { 436 test_dispatch_done(test); 437 } 438 } 439 440 static void 441 response_shutdown(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, 442 void *arg) { 443 test_dispatch_t *test = arg; 444 445 assert_int_equal(eresult, ISC_R_SUCCESS); 446 447 test_dispatch_shutdown(test); 448 } 449 450 static void 451 response_timeout(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, 452 void *arg) { 453 test_dispatch_t *test = arg; 454 455 assert_int_equal(eresult, ISC_R_TIMEDOUT); 456 457 test_dispatch_shutdown(test); 458 } 459 460 static void 461 client_senddone(isc_result_t eresult, isc_region_t *region, void *arg) { 462 UNUSED(eresult); 463 UNUSED(region); 464 UNUSED(arg); 465 } 466 467 static void 468 connected(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, 469 void *arg) { 470 test_dispatch_t *test = arg; 471 472 switch (eresult) { 473 case ISC_R_CONNECTIONRESET: 474 /* Don't send any data if the connection failed */ 475 test_dispatch_shutdown(test); 476 return; 477 default: 478 assert_int_equal(eresult, ISC_R_SUCCESS); 479 } 480 481 dns_dispatch_send(test->dispentry, &testdata.region); 482 } 483 484 static void 485 connected_shutdown(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, 486 void *arg) { 487 test_dispatch_t *test = arg; 488 489 switch (eresult) { 490 case ISC_R_CONNECTIONRESET: 491 /* Skip */ 492 break; 493 default: 494 assert_int_equal(eresult, ISC_R_SUCCESS); 495 } 496 497 test_dispatch_shutdown(test); 498 } 499 500 static void 501 connected_gettcp(isc_result_t eresult ISC_ATTR_UNUSED, 502 isc_region_t *region ISC_ATTR_UNUSED, void *arg) { 503 test_dispatch_t *test1 = arg; 504 505 /* Client 2 */ 506 isc_result_t result; 507 test_dispatch_t *test2 = isc_mem_get(mctx, sizeof(*test2)); 508 *test2 = (test_dispatch_t){ 509 .dispatchmgr = dns_dispatchmgr_ref(test1->dispatchmgr), 510 }; 511 512 result = dns_dispatch_gettcp(test2->dispatchmgr, &tcp_server_addr, 513 &tcp_connect_addr, NULL, &test2->dispatch); 514 assert_int_equal(result, ISC_R_SUCCESS); 515 516 assert_ptr_equal(test1->dispatch, test2->dispatch); 517 518 result = dns_dispatch_add(test2->dispatch, isc_loop_main(loopmgr), 0, 519 T_CLIENT_CONNECT, &tcp_server_addr, NULL, 520 NULL, connected_shutdown, client_senddone, 521 response_noop, test2, &test2->id, 522 &test2->dispentry); 523 assert_int_equal(result, ISC_R_SUCCESS); 524 525 dns_dispatch_connect(test2->dispentry); 526 527 test_dispatch_done(test1); 528 } 529 530 static void 531 connected_newtcp(isc_result_t eresult ISC_ATTR_UNUSED, 532 isc_region_t *region ISC_ATTR_UNUSED, void *arg) { 533 test_dispatch_t *test3 = arg; 534 535 /* Client - unshared */ 536 isc_result_t result; 537 test_dispatch_t *test4 = isc_mem_get(mctx, sizeof(*test4)); 538 *test4 = (test_dispatch_t){ 539 .dispatchmgr = dns_dispatchmgr_ref(test3->dispatchmgr), 540 }; 541 result = dns_dispatch_gettcp(test4->dispatchmgr, &tcp_server_addr, 542 &tcp_connect_addr, NULL, &test4->dispatch); 543 assert_int_equal(result, ISC_R_NOTFOUND); 544 545 result = dns_dispatch_createtcp( 546 test4->dispatchmgr, &tcp_connect_addr, &tcp_server_addr, NULL, 547 DNS_DISPATCHOPT_UNSHARED, &test4->dispatch); 548 assert_int_equal(result, ISC_R_SUCCESS); 549 550 assert_ptr_not_equal(test3->dispatch, test4->dispatch); 551 552 result = dns_dispatch_add(test4->dispatch, isc_loop_main(loopmgr), 0, 553 T_CLIENT_CONNECT, &tcp_server_addr, NULL, 554 NULL, connected_shutdown, client_senddone, 555 response_noop, test4, &test4->id, 556 &test4->dispentry); 557 assert_int_equal(result, ISC_R_SUCCESS); 558 559 dns_dispatch_connect(test4->dispentry); 560 561 test_dispatch_done(test3); 562 } 563 564 static void 565 timeout_connected(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, 566 void *arg) { 567 test_dispatch_t *test = arg; 568 569 switch (eresult) { 570 case ISC_R_ADDRNOTAVAIL: 571 case ISC_R_CONNREFUSED: 572 /* Skip */ 573 break; 574 default: 575 assert_int_equal(eresult, ISC_R_TIMEDOUT); 576 } 577 578 test_dispatch_shutdown(test); 579 } 580 581 ISC_LOOP_TEST_IMPL(dispatch_timeout_tcp_connect) { 582 isc_result_t result; 583 test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); 584 *test = (test_dispatch_t){ 0 }; 585 586 /* Client */ 587 tcp_connect_addr = (isc_sockaddr_t){ .length = 0 }; 588 isc_sockaddr_fromin6(&tcp_connect_addr, &in6addr_blackhole, 0); 589 590 testdata.region.base = testdata.message; 591 testdata.region.length = sizeof(testdata.message); 592 593 result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, 594 &test->dispatchmgr); 595 assert_int_equal(result, ISC_R_SUCCESS); 596 597 result = dns_dispatch_createtcp(test->dispatchmgr, &tcp_connect_addr, 598 &tcp_server_addr, NULL, 0, 599 &test->dispatch); 600 assert_int_equal(result, ISC_R_SUCCESS); 601 602 result = dns_dispatch_add(test->dispatch, isc_loop_main(loopmgr), 0, 603 T_CLIENT_CONNECT_SHORT, &tcp_server_addr, 604 NULL, NULL, timeout_connected, 605 client_senddone, response_timeout, test, 606 &test->id, &test->dispentry); 607 assert_int_equal(result, ISC_R_SUCCESS); 608 609 testdata.message[0] = (test->id >> 8) & 0xff; 610 testdata.message[1] = test->id & 0xff; 611 612 dns_dispatch_connect(test->dispentry); 613 } 614 615 static void 616 stop_listening(void *arg) { 617 UNUSED(arg); 618 619 isc_nm_stoplistening(sock); 620 isc_nmsocket_close(&sock); 621 assert_null(sock); 622 } 623 624 ISC_LOOP_TEST_IMPL(dispatch_timeout_tcp_response) { 625 isc_result_t result; 626 test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); 627 *test = (test_dispatch_t){ 0 }; 628 629 /* Server */ 630 result = isc_nm_listenstreamdns( 631 netmgr, ISC_NM_LISTEN_ONE, &tcp_server_addr, noop_nameserver, 632 NULL, accept_cb, NULL, 0, NULL, NULL, ISC_NM_PROXY_NONE, &sock); 633 assert_int_equal(result, ISC_R_SUCCESS); 634 635 /* ensure we stop listening after the test is done */ 636 isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock); 637 638 /* Client */ 639 result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, 640 &test->dispatchmgr); 641 assert_int_equal(result, ISC_R_SUCCESS); 642 643 result = dns_dispatch_createtcp(test->dispatchmgr, &tcp_connect_addr, 644 &tcp_server_addr, NULL, 0, 645 &test->dispatch); 646 assert_int_equal(result, ISC_R_SUCCESS); 647 648 result = dns_dispatch_add(test->dispatch, isc_loop_main(loopmgr), 0, 649 T_CLIENT_CONNECT_SHORT, &tcp_server_addr, 650 NULL, NULL, connected, client_senddone, 651 response_timeout, test, &test->id, 652 &test->dispentry); 653 assert_int_equal(result, ISC_R_SUCCESS); 654 655 dns_dispatch_connect(test->dispentry); 656 } 657 658 ISC_LOOP_TEST_IMPL(dispatch_tcp_response) { 659 isc_result_t result; 660 test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); 661 *test = (test_dispatch_t){ 0 }; 662 663 /* Server */ 664 result = isc_nm_listenstreamdns( 665 netmgr, ISC_NM_LISTEN_ONE, &tcp_server_addr, nameserver, NULL, 666 accept_cb, NULL, 0, NULL, NULL, ISC_NM_PROXY_NONE, &sock); 667 assert_int_equal(result, ISC_R_SUCCESS); 668 669 isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock); 670 671 /* Client */ 672 testdata.region.base = testdata.message; 673 testdata.region.length = sizeof(testdata.message); 674 675 result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, 676 &test->dispatchmgr); 677 assert_int_equal(result, ISC_R_SUCCESS); 678 679 result = dns_dispatch_createtcp(test->dispatchmgr, &tcp_connect_addr, 680 &tcp_server_addr, NULL, 0, 681 &test->dispatch); 682 assert_int_equal(result, ISC_R_SUCCESS); 683 684 result = dns_dispatch_add( 685 test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, 686 &tcp_server_addr, NULL, NULL, connected, client_senddone, 687 response_shutdown, test, &test->id, &test->dispentry); 688 assert_int_equal(result, ISC_R_SUCCESS); 689 690 testdata.message[0] = (test->id >> 8) & 0xff; 691 testdata.message[1] = test->id & 0xff; 692 693 dns_dispatch_connect(test->dispentry); 694 } 695 696 ISC_LOOP_TEST_IMPL(dispatch_tls_response) { 697 isc_result_t result; 698 test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); 699 *test = (test_dispatch_t){ 0 }; 700 701 /* Server */ 702 result = isc_nm_listenstreamdns( 703 netmgr, ISC_NM_LISTEN_ONE, &tls_server_addr, nameserver, NULL, 704 accept_cb, NULL, 0, NULL, tls_listen_tlsctx, ISC_NM_PROXY_NONE, 705 &sock); 706 assert_int_equal(result, ISC_R_SUCCESS); 707 708 isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock); 709 710 /* Client */ 711 testdata.region.base = testdata.message; 712 testdata.region.length = sizeof(testdata.message); 713 714 result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, 715 &test->dispatchmgr); 716 assert_int_equal(result, ISC_R_SUCCESS); 717 718 result = dns_dispatch_createtcp(test->dispatchmgr, &tls_connect_addr, 719 &tls_server_addr, tls_transport, 0, 720 &test->dispatch); 721 assert_int_equal(result, ISC_R_SUCCESS); 722 723 result = dns_dispatch_add(test->dispatch, isc_loop_main(loopmgr), 0, 724 T_CLIENT_CONNECT, &tls_server_addr, 725 tls_transport, tls_tlsctx_client_cache, 726 connected, client_senddone, response_shutdown, 727 test, &test->id, &test->dispentry); 728 assert_int_equal(result, ISC_R_SUCCESS); 729 730 testdata.message[0] = (test->id >> 8) & 0xff; 731 testdata.message[1] = test->id & 0xff; 732 733 dns_dispatch_connect(test->dispentry); 734 } 735 736 ISC_LOOP_TEST_IMPL(dispatch_timeout_udp_response) { 737 isc_result_t result; 738 test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); 739 *test = (test_dispatch_t){ 0 }; 740 741 /* Server */ 742 result = isc_nm_listenudp(netmgr, ISC_NM_LISTEN_ONE, &udp_server_addr, 743 noop_nameserver, NULL, &sock); 744 assert_int_equal(result, ISC_R_SUCCESS); 745 746 /* ensure we stop listening after the test is done */ 747 isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock); 748 749 /* Client */ 750 result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, 751 &test->dispatchmgr); 752 assert_int_equal(result, ISC_R_SUCCESS); 753 754 result = dns_dispatch_createudp(test->dispatchmgr, &udp_connect_addr, 755 &test->dispatch); 756 assert_int_equal(result, ISC_R_SUCCESS); 757 758 result = dns_dispatch_add(test->dispatch, isc_loop_main(loopmgr), 0, 759 T_CLIENT_CONNECT_SHORT, &udp_server_addr, 760 NULL, NULL, connected, client_senddone, 761 response_timeout, test, &test->id, 762 &test->dispentry); 763 assert_int_equal(result, ISC_R_SUCCESS); 764 765 dns_dispatch_connect(test->dispentry); 766 } 767 768 /* test dispatch getnext */ 769 ISC_LOOP_TEST_IMPL(dispatch_getnext) { 770 isc_result_t result; 771 test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); 772 *test = (test_dispatch_t){ 0 }; 773 774 /* Server */ 775 result = isc_nm_listenudp(netmgr, ISC_NM_LISTEN_ONE, &udp_server_addr, 776 nameserver, NULL, &sock); 777 assert_int_equal(result, ISC_R_SUCCESS); 778 779 isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock); 780 781 /* Client */ 782 testdata.region.base = testdata.message; 783 testdata.region.length = sizeof(testdata.message); 784 785 result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, 786 &test->dispatchmgr); 787 assert_int_equal(result, ISC_R_SUCCESS); 788 789 result = dns_dispatch_createudp(test->dispatchmgr, &udp_connect_addr, 790 &test->dispatch); 791 assert_int_equal(result, ISC_R_SUCCESS); 792 793 result = dns_dispatch_add( 794 test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, 795 &udp_server_addr, NULL, NULL, connected, client_senddone, 796 response_getnext, test, &test->id, &test->dispentry); 797 assert_int_equal(result, ISC_R_SUCCESS); 798 799 testdata.message[0] = (test->id >> 8) & 0xff; 800 testdata.message[1] = test->id & 0xff; 801 802 dns_dispatch_connect(test->dispentry); 803 } 804 805 ISC_LOOP_TEST_IMPL(dispatch_gettcp) { 806 isc_result_t result; 807 test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); 808 *test = (test_dispatch_t){ 0 }; 809 810 /* Server */ 811 result = isc_nm_listenstreamdns( 812 netmgr, ISC_NM_LISTEN_ONE, &tcp_server_addr, nameserver, NULL, 813 accept_cb, NULL, 0, NULL, NULL, ISC_NM_PROXY_NONE, &sock); 814 assert_int_equal(result, ISC_R_SUCCESS); 815 816 /* ensure we stop listening after the test is done */ 817 isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock); 818 819 result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, 820 &test->dispatchmgr); 821 assert_int_equal(result, ISC_R_SUCCESS); 822 823 /* Client */ 824 result = dns_dispatch_createtcp(test->dispatchmgr, &tcp_connect_addr, 825 &tcp_server_addr, NULL, 0, 826 &test->dispatch); 827 assert_int_equal(result, ISC_R_SUCCESS); 828 829 result = dns_dispatch_add( 830 test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, 831 &tcp_server_addr, NULL, NULL, connected_gettcp, client_senddone, 832 response_noop, test, &test->id, &test->dispentry); 833 assert_int_equal(result, ISC_R_SUCCESS); 834 835 dns_dispatch_connect(test->dispentry); 836 } 837 838 ISC_LOOP_TEST_IMPL(dispatch_newtcp) { 839 isc_result_t result; 840 test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); 841 *test = (test_dispatch_t){ 0 }; 842 843 /* Server */ 844 result = isc_nm_listenstreamdns( 845 netmgr, ISC_NM_LISTEN_ONE, &tcp_server_addr, nameserver, NULL, 846 accept_cb, NULL, 0, NULL, NULL, ISC_NM_PROXY_NONE, &sock); 847 assert_int_equal(result, ISC_R_SUCCESS); 848 849 /* ensure we stop listening after the test is done */ 850 isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock); 851 852 /* Client - unshared */ 853 result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, 854 &test->dispatchmgr); 855 assert_int_equal(result, ISC_R_SUCCESS); 856 857 result = dns_dispatch_createtcp( 858 test->dispatchmgr, &tcp_connect_addr, &tcp_server_addr, NULL, 859 DNS_DISPATCHOPT_UNSHARED, &test->dispatch); 860 assert_int_equal(result, ISC_R_SUCCESS); 861 862 result = dns_dispatch_add( 863 test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, 864 &tcp_server_addr, NULL, NULL, connected_newtcp, client_senddone, 865 response_noop, test, &test->id, &test->dispentry); 866 assert_int_equal(result, ISC_R_SUCCESS); 867 868 dns_dispatch_connect(test->dispentry); 869 } 870 871 ISC_TEST_LIST_START 872 ISC_TEST_ENTRY_CUSTOM(dispatch_gettcp, setup_test, teardown_test) 873 ISC_TEST_ENTRY_CUSTOM(dispatch_newtcp, setup_test, teardown_test) 874 ISC_TEST_ENTRY_CUSTOM(dispatch_timeout_udp_response, setup_test, teardown_test) 875 ISC_TEST_ENTRY_CUSTOM(dispatchset_create, setup_test, teardown_test) 876 ISC_TEST_ENTRY_CUSTOM(dispatchset_get, setup_test, teardown_test) 877 ISC_TEST_ENTRY_CUSTOM(dispatch_timeout_tcp_response, setup_test, teardown_test) 878 ISC_TEST_ENTRY_CUSTOM(dispatch_timeout_tcp_connect, setup_test, teardown_test) 879 ISC_TEST_ENTRY_CUSTOM(dispatch_tcp_response, setup_test, teardown_test) 880 ISC_TEST_ENTRY_CUSTOM(dispatch_tls_response, setup_test, teardown_test) 881 ISC_TEST_ENTRY_CUSTOM(dispatch_getnext, setup_test, teardown_test) 882 ISC_TEST_LIST_END 883 884 ISC_TEST_MAIN 885