Home | History | Annotate | Line # | Download | only in dns
dispatch_test.c revision 1.2.6.1
      1 /*	$NetBSD: dispatch_test.c,v 1.2.6.1 2025/08/02 05:54:11 perseant 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