xref: /netbsd-src/external/mpl/bind/dist/tests/dns/dispatch_test.c (revision bcda20f65a8566e103791ec395f7f499ef322704)
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