From: Ondřej Surý Date: Mon, 23 Oct 2023 10:26:50 +0000 (+0200) Subject: Add dispatch_getcp and dispatch_newtcp tests X-Git-Tag: v9.19.18~25^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d246aa02a6e696aaa672b63a0c17e9c405418250;p=thirdparty%2Fbind9.git Add dispatch_getcp and dispatch_newtcp tests Refactor the dispatch unit test to use more local variables (previously dispatchmgr, dispatch and dispentry were all global), and add two new tests: * dispatch_getcp - test whether the TCP connection will get reused * dispatch_newtcp - test that the TCP connection will not get reused when DNS_DISPATCHOPT_UNSHARED is in effect --- diff --git a/tests/dns/dispatch_test.c b/tests/dns/dispatch_test.c index c8950069cd0..cb1f023d35d 100644 --- a/tests/dns/dispatch_test.c +++ b/tests/dns/dispatch_test.c @@ -65,8 +65,6 @@ static const char *tls_name_str = "ephemeral"; static dns_transport_t *tls_transport = NULL; static dns_transport_list_t *transport_list = NULL; -static dns_dispatchmgr_t *dispatchmgr = NULL; -static dns_dispatch_t *dispatch = NULL; static isc_nmsocket_t *sock = NULL; static isc_nm_t *connect_nm = NULL; @@ -80,6 +78,27 @@ struct { uint8_t message[12]; } testdata; +typedef struct { + dns_dispatchmgr_t *dispatchmgr; + dns_dispatch_t *dispatch; + dns_dispentry_t *dispentry; + uint16_t id; +} test_dispatch_t; + +static void +test_dispatch_done(test_dispatch_t *test) { + dns_dispatch_done(&test->dispentry); + dns_dispatch_detach(&test->dispatch); + dns_dispatchmgr_detach(&test->dispatchmgr); + isc_mem_put(mctx, test, sizeof(*test)); +} + +static void +test_dispatch_shutdown(test_dispatch_t *test) { + test_dispatch_done(test); + isc_loopmgr_shutdown(loopmgr); +} + static int setup_ephemeral_port(isc_sockaddr_t *addr, sa_family_t family) { socklen_t addrlen = sizeof(*addr); @@ -131,7 +150,10 @@ setup_test(void **state) { uv_os_sock_t socket = -1; - setup_loopmgr(state); + /* Create just 1 loop for this test */ + isc_loopmgr_create(mctx, 1, &loopmgr); + mainloop = isc_loop_main(loopmgr); + setup_netmgr(state); isc_netmgr_create(mctx, loopmgr, &connect_nm); @@ -221,7 +243,8 @@ teardown_test(void **state) { } static isc_result_t -make_dispatchset(unsigned int ndisps, dns_dispatchset_t **dsetp) { +make_dispatchset(dns_dispatchmgr_t *dispatchmgr, unsigned int ndisps, + dns_dispatchset_t **dsetp) { isc_result_t result; isc_sockaddr_t any; dns_dispatch_t *disp = NULL; @@ -242,6 +265,7 @@ make_dispatchset(unsigned int ndisps, dns_dispatchset_t **dsetp) { ISC_LOOP_TEST_IMPL(dispatchset_create) { dns_dispatchset_t *dset = NULL; isc_result_t result; + dns_dispatchmgr_t *dispatchmgr = NULL; UNUSED(arg); @@ -249,11 +273,11 @@ ISC_LOOP_TEST_IMPL(dispatchset_create) { &dispatchmgr); assert_int_equal(result, ISC_R_SUCCESS); - result = make_dispatchset(1, &dset); + result = make_dispatchset(dispatchmgr, 1, &dset); assert_int_equal(result, ISC_R_SUCCESS); dns_dispatchset_destroy(&dset); - result = make_dispatchset(10, &dset); + result = make_dispatchset(dispatchmgr, 10, &dset); assert_int_equal(result, ISC_R_SUCCESS); dns_dispatchset_destroy(&dset); @@ -265,6 +289,7 @@ ISC_LOOP_TEST_IMPL(dispatchset_create) { /* test dispatch set per-loop dispatch */ ISC_LOOP_TEST_IMPL(dispatchset_get) { isc_result_t result; + dns_dispatchmgr_t *dispatchmgr = NULL; dns_dispatchset_t *dset = NULL; dns_dispatch_t *d1, *d2, *d3, *d4, *d5; uint32_t tid_saved; @@ -275,7 +300,7 @@ ISC_LOOP_TEST_IMPL(dispatchset_get) { &dispatchmgr); assert_int_equal(result, ISC_R_SUCCESS); - result = make_dispatchset(1, &dset); + result = make_dispatchset(dispatchmgr, 1, &dset); assert_int_equal(result, ISC_R_SUCCESS); d1 = dns_dispatchset_get(dset); @@ -291,7 +316,7 @@ ISC_LOOP_TEST_IMPL(dispatchset_get) { dns_dispatchset_destroy(&dset); - result = make_dispatchset(4, &dset); + result = make_dispatchset(dispatchmgr, 4, &dset); assert_int_equal(result, ISC_R_SUCCESS); /* @@ -322,21 +347,20 @@ ISC_LOOP_TEST_IMPL(dispatchset_get) { isc_loopmgr_shutdown(loopmgr); } -static dns_dispentry_t *dispentry = NULL; static atomic_bool first = true; static void -server_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) { +server_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { UNUSED(handle); UNUSED(eresult); - UNUSED(cbarg); + UNUSED(arg); return; } static void nameserver(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, - void *cbarg ISC_ATTR_UNUSED) { + void *arg ISC_ATTR_UNUSED) { isc_region_t response1, response2; static unsigned char buf1[16]; static unsigned char buf2[16]; @@ -369,79 +393,160 @@ nameserver(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, } static isc_result_t -accept_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) { +accept_cb(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { UNUSED(handle); - UNUSED(cbarg); + UNUSED(arg); return (eresult); } static void noop_nameserver(isc_nmhandle_t *handle, isc_result_t eresult, - isc_region_t *region, void *cbarg) { + isc_region_t *region, void *arg) { UNUSED(handle); UNUSED(eresult); UNUSED(region); - UNUSED(cbarg); + UNUSED(arg); } static void -response_getnext(isc_result_t result, isc_region_t *region, void *arg) { - UNUSED(region); - UNUSED(arg); +response_getnext(isc_result_t result, isc_region_t *region ISC_ATTR_UNUSED, + void *arg) { + test_dispatch_t *test = arg; if (atomic_compare_exchange_strong(&first, &(bool){ true }, false)) { - result = dns_dispatch_getnext(dispentry); + result = dns_dispatch_getnext(test->dispentry); assert_int_equal(result, ISC_R_SUCCESS); } else { - dns_dispatch_done(&dispentry); - isc_loopmgr_shutdown(loopmgr); + test_dispatch_shutdown(test); } } static void -response(isc_result_t eresult, isc_region_t *region, void *arg) { - UNUSED(region); - UNUSED(arg); +response_noop(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, + void *arg) { + test_dispatch_t *test = arg; + + if (eresult == ISC_R_SUCCESS) { + test_dispatch_done(test); + } +} + +static void +response_shutdown(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, + void *arg) { + test_dispatch_t *test = arg; assert_int_equal(eresult, ISC_R_SUCCESS); - dns_dispatch_done(&dispentry); - isc_loopmgr_shutdown(loopmgr); + test_dispatch_shutdown(test); } static void -response_timeout(isc_result_t eresult, isc_region_t *region, void *arg) { - UNUSED(region); - UNUSED(arg); +response_timeout(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, + void *arg) { + test_dispatch_t *test = arg; assert_int_equal(eresult, ISC_R_TIMEDOUT); - dns_dispatch_done(&dispentry); - isc_loopmgr_shutdown(loopmgr); + test_dispatch_shutdown(test); } static void -connected(isc_result_t eresult, isc_region_t *region, void *cbarg) { - isc_region_t *r = (isc_region_t *)cbarg; - +client_senddone(isc_result_t eresult, isc_region_t *region, void *arg) { UNUSED(eresult); UNUSED(region); + UNUSED(arg); +} + +static void +connected(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, + void *arg) { + test_dispatch_t *test = arg; + + REQUIRE(eresult == ISC_R_SUCCESS); - dns_dispatch_send(dispentry, r); + dns_dispatch_send(test->dispentry, &testdata.region); } static void -client_senddone(isc_result_t eresult, isc_region_t *region, void *cbarg) { - UNUSED(eresult); - UNUSED(region); - UNUSED(cbarg); +connected_shutdown(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, + void *arg) { + test_dispatch_t *test = arg; + + REQUIRE(eresult == ISC_R_SUCCESS); + + test_dispatch_shutdown(test); } static void -timeout_connected(isc_result_t eresult, isc_region_t *region, void *cbarg) { - UNUSED(region); - UNUSED(cbarg); +connected_gettcp(isc_result_t eresult ISC_ATTR_UNUSED, + isc_region_t *region ISC_ATTR_UNUSED, void *arg) { + test_dispatch_t *test1 = arg; + + /* Client 2 */ + isc_result_t result; + test_dispatch_t *test2 = isc_mem_get(mctx, sizeof(*test2)); + *test2 = (test_dispatch_t){ + .dispatchmgr = dns_dispatchmgr_ref(test1->dispatchmgr), + }; + + result = dns_dispatch_gettcp(test2->dispatchmgr, &tcp_server_addr, + &tcp_connect_addr, &test2->dispatch); + assert_int_equal(result, ISC_R_SUCCESS); + + assert_ptr_equal(test1->dispatch, test2->dispatch); + + result = dns_dispatch_add(test2->dispatch, isc_loop_main(loopmgr), 0, + T_CLIENT_CONNECT, &tcp_server_addr, NULL, + NULL, connected_shutdown, client_senddone, + response_noop, test2, &test2->id, + &test2->dispentry); + assert_int_equal(result, ISC_R_SUCCESS); + + dns_dispatch_connect(test2->dispentry); + + test_dispatch_done(test1); +} + +static void +connected_newtcp(isc_result_t eresult ISC_ATTR_UNUSED, + isc_region_t *region ISC_ATTR_UNUSED, void *arg) { + test_dispatch_t *test3 = arg; + + /* Client - unshared */ + isc_result_t result; + test_dispatch_t *test4 = isc_mem_get(mctx, sizeof(*test4)); + *test4 = (test_dispatch_t){ + .dispatchmgr = dns_dispatchmgr_ref(test3->dispatchmgr), + }; + result = dns_dispatch_gettcp(test4->dispatchmgr, &tcp_server_addr, + &tcp_connect_addr, &test4->dispatch); + assert_int_equal(result, ISC_R_NOTFOUND); + + result = dns_dispatch_createtcp( + test4->dispatchmgr, &tcp_connect_addr, &tcp_server_addr, + DNS_DISPATCHOPT_UNSHARED, &test4->dispatch); + assert_int_equal(result, ISC_R_SUCCESS); + + assert_ptr_not_equal(test3->dispatch, test4->dispatch); + + result = dns_dispatch_add(test4->dispatch, isc_loop_main(loopmgr), 0, + T_CLIENT_CONNECT, &tcp_server_addr, NULL, + NULL, connected_shutdown, client_senddone, + response_noop, test4, &test4->id, + &test4->dispentry); + assert_int_equal(result, ISC_R_SUCCESS); + + dns_dispatch_connect(test4->dispentry); + + test_dispatch_done(test3); +} + +static void +timeout_connected(isc_result_t eresult, isc_region_t *region ISC_ATTR_UNUSED, + void *arg) { + test_dispatch_t *test = arg; if (eresult == ISC_R_ADDRNOTAVAIL || eresult == ISC_R_CONNREFUSED) { /* FIXME: Skip */ @@ -449,14 +554,13 @@ timeout_connected(isc_result_t eresult, isc_region_t *region, void *cbarg) { assert_int_equal(eresult, ISC_R_TIMEDOUT); } - dns_dispatch_done(&dispentry); - - isc_loopmgr_shutdown(loopmgr); + test_dispatch_shutdown(test); } ISC_LOOP_TEST_IMPL(dispatch_timeout_tcp_connect) { isc_result_t result; - uint16_t id; + test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); + *test = (test_dispatch_t){ 0 }; /* Client */ tcp_connect_addr = (isc_sockaddr_t){ .length = 0 }; @@ -466,26 +570,24 @@ ISC_LOOP_TEST_IMPL(dispatch_timeout_tcp_connect) { testdata.region.length = sizeof(testdata.message); result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, - &dispatchmgr); + &test->dispatchmgr); assert_int_equal(result, ISC_R_SUCCESS); - result = dns_dispatch_createtcp(dispatchmgr, &tcp_connect_addr, - &tcp_server_addr, 0, &dispatch); + result = dns_dispatch_createtcp(test->dispatchmgr, &tcp_connect_addr, + &tcp_server_addr, 0, &test->dispatch); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatchmgr_detach(&dispatchmgr); - result = dns_dispatch_add(dispatch, isc_loop_main(loopmgr), 0, + result = dns_dispatch_add(test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, &tcp_server_addr, NULL, NULL, timeout_connected, client_senddone, - response_timeout, &testdata.region, &id, - &dispentry); + response_timeout, test, &test->id, + &test->dispentry); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatch_detach(&dispatch); - testdata.message[0] = (id >> 8) & 0xff; - testdata.message[1] = id & 0xff; + testdata.message[0] = (test->id >> 8) & 0xff; + testdata.message[1] = test->id & 0xff; - dns_dispatch_connect(dispentry); + dns_dispatch_connect(test->dispentry); } static void @@ -499,7 +601,8 @@ stop_listening(void *arg) { ISC_LOOP_TEST_IMPL(dispatch_timeout_tcp_response) { isc_result_t result; - uint16_t id; + test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); + *test = (test_dispatch_t){ 0 }; /* Server */ result = isc_nm_listenstreamdns(netmgr, ISC_NM_LISTEN_ONE, @@ -512,27 +615,26 @@ ISC_LOOP_TEST_IMPL(dispatch_timeout_tcp_response) { /* Client */ result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, - &dispatchmgr); + &test->dispatchmgr); assert_int_equal(result, ISC_R_SUCCESS); - result = dns_dispatch_createtcp(dispatchmgr, &tcp_connect_addr, - &tcp_server_addr, 0, &dispatch); + result = dns_dispatch_createtcp(test->dispatchmgr, &tcp_connect_addr, + &tcp_server_addr, 0, &test->dispatch); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatchmgr_detach(&dispatchmgr); result = dns_dispatch_add( - dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, + test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, &tcp_server_addr, NULL, NULL, connected, client_senddone, - response_timeout, &testdata.region, &id, &dispentry); + response_timeout, test, &test->id, &test->dispentry); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatch_detach(&dispatch); - dns_dispatch_connect(dispentry); + dns_dispatch_connect(test->dispentry); } ISC_LOOP_TEST_IMPL(dispatch_tcp_response) { isc_result_t result; - uint16_t id; + test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); + *test = (test_dispatch_t){ 0 }; /* Server */ result = isc_nm_listenstreamdns(netmgr, ISC_NM_LISTEN_ONE, @@ -547,30 +649,29 @@ ISC_LOOP_TEST_IMPL(dispatch_tcp_response) { testdata.region.length = sizeof(testdata.message); result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, - &dispatchmgr); + &test->dispatchmgr); assert_int_equal(result, ISC_R_SUCCESS); - result = dns_dispatch_createtcp(dispatchmgr, &tcp_connect_addr, - &tcp_server_addr, 0, &dispatch); + result = dns_dispatch_createtcp(test->dispatchmgr, &tcp_connect_addr, + &tcp_server_addr, 0, &test->dispatch); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatchmgr_detach(&dispatchmgr); - result = dns_dispatch_add(dispatch, isc_loop_main(loopmgr), 0, - T_CLIENT_CONNECT, &tcp_server_addr, NULL, - NULL, connected, client_senddone, response, - &testdata.region, &id, &dispentry); + result = dns_dispatch_add( + test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, + &tcp_server_addr, NULL, NULL, connected, client_senddone, + response_shutdown, test, &test->id, &test->dispentry); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatch_detach(&dispatch); - testdata.message[0] = (id >> 8) & 0xff; - testdata.message[1] = id & 0xff; + testdata.message[0] = (test->id >> 8) & 0xff; + testdata.message[1] = test->id & 0xff; - dns_dispatch_connect(dispentry); + dns_dispatch_connect(test->dispentry); } ISC_LOOP_TEST_IMPL(dispatch_tls_response) { isc_result_t result; - uint16_t id; + test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); + *test = (test_dispatch_t){ 0 }; /* Server */ result = isc_nm_listenstreamdns( @@ -585,37 +686,32 @@ ISC_LOOP_TEST_IMPL(dispatch_tls_response) { testdata.region.length = sizeof(testdata.message); result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, - &dispatchmgr); + &test->dispatchmgr); assert_int_equal(result, ISC_R_SUCCESS); - result = dns_dispatch_createtcp(dispatchmgr, &tls_connect_addr, - &tls_server_addr, 0, &dispatch); + result = dns_dispatch_createtcp(test->dispatchmgr, &tls_connect_addr, + &tls_server_addr, 0, &test->dispatch); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatchmgr_detach(&dispatchmgr); - result = dns_dispatch_add(dispatch, isc_loop_main(loopmgr), 0, + result = dns_dispatch_add(test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, &tls_server_addr, tls_transport, tls_tlsctx_client_cache, - connected, client_senddone, response, - &testdata.region, &id, &dispentry); + connected, client_senddone, response_shutdown, + test, &test->id, &test->dispentry); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatch_detach(&dispatch); - testdata.message[0] = (id >> 8) & 0xff; - testdata.message[1] = id & 0xff; + testdata.message[0] = (test->id >> 8) & 0xff; + testdata.message[1] = test->id & 0xff; - dns_dispatch_connect(dispentry); + dns_dispatch_connect(test->dispentry); } ISC_LOOP_TEST_IMPL(dispatch_timeout_udp_response) { isc_result_t result; - uint16_t id; + test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); + *test = (test_dispatch_t){ 0 }; /* Server */ - result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, - &dispatchmgr); - assert_int_equal(result, ISC_R_SUCCESS); - result = isc_nm_listenudp(netmgr, ISC_NM_LISTEN_ONE, &udp_server_addr, noop_nameserver, NULL, &sock); assert_int_equal(result, ISC_R_SUCCESS); @@ -624,25 +720,28 @@ ISC_LOOP_TEST_IMPL(dispatch_timeout_udp_response) { isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock); /* Client */ - result = dns_dispatch_createudp(dispatchmgr, &udp_connect_addr, - &dispatch); + result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, + &test->dispatchmgr); + assert_int_equal(result, ISC_R_SUCCESS); + + result = dns_dispatch_createudp(test->dispatchmgr, &udp_connect_addr, + &test->dispatch); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatchmgr_detach(&dispatchmgr); result = dns_dispatch_add( - dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, + test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, &udp_server_addr, NULL, NULL, connected, client_senddone, - response_timeout, &testdata.region, &id, &dispentry); + response_timeout, test, &test->id, &test->dispentry); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatch_detach(&dispatch); - dns_dispatch_connect(dispentry); + dns_dispatch_connect(test->dispentry); } /* test dispatch getnext */ ISC_LOOP_TEST_IMPL(dispatch_getnext) { isc_result_t result; - uint16_t id; + test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); + *test = (test_dispatch_t){ 0 }; /* Server */ result = isc_nm_listenudp(netmgr, ISC_NM_LISTEN_ONE, &udp_server_addr, @@ -656,28 +755,93 @@ ISC_LOOP_TEST_IMPL(dispatch_getnext) { testdata.region.length = sizeof(testdata.message); result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, - &dispatchmgr); + &test->dispatchmgr); assert_int_equal(result, ISC_R_SUCCESS); - result = dns_dispatch_createudp(dispatchmgr, &udp_connect_addr, - &dispatch); + result = dns_dispatch_createudp(test->dispatchmgr, &udp_connect_addr, + &test->dispatch); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatchmgr_detach(&dispatchmgr); result = dns_dispatch_add( - dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, + test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, &udp_server_addr, NULL, NULL, connected, client_senddone, - response_getnext, &testdata.region, &id, &dispentry); + response_getnext, test, &test->id, &test->dispentry); assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatch_detach(&dispatch); - testdata.message[0] = (id >> 8) & 0xff; - testdata.message[1] = id & 0xff; + testdata.message[0] = (test->id >> 8) & 0xff; + testdata.message[1] = test->id & 0xff; + + dns_dispatch_connect(test->dispentry); +} + +ISC_LOOP_TEST_IMPL(dispatch_gettcp) { + isc_result_t result; + test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); + *test = (test_dispatch_t){ 0 }; + + /* Server */ + result = isc_nm_listenstreamdns(netmgr, ISC_NM_LISTEN_ONE, + &tcp_server_addr, nameserver, NULL, + accept_cb, NULL, 0, NULL, NULL, &sock); + assert_int_equal(result, ISC_R_SUCCESS); + + /* ensure we stop listening after the test is done */ + isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock); + + result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, + &test->dispatchmgr); + assert_int_equal(result, ISC_R_SUCCESS); + + /* Client */ + result = dns_dispatch_createtcp(test->dispatchmgr, &tcp_connect_addr, + &tcp_server_addr, 0, &test->dispatch); + assert_int_equal(result, ISC_R_SUCCESS); + + result = dns_dispatch_add( + test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, + &tcp_server_addr, NULL, NULL, connected_gettcp, client_senddone, + response_noop, test, &test->id, &test->dispentry); + assert_int_equal(result, ISC_R_SUCCESS); + + dns_dispatch_connect(test->dispentry); +} + +ISC_LOOP_TEST_IMPL(dispatch_newtcp) { + isc_result_t result; + test_dispatch_t *test = isc_mem_get(mctx, sizeof(*test)); + *test = (test_dispatch_t){ 0 }; + + /* Server */ + result = isc_nm_listenstreamdns(netmgr, ISC_NM_LISTEN_ONE, + &tcp_server_addr, nameserver, NULL, + accept_cb, NULL, 0, NULL, NULL, &sock); + assert_int_equal(result, ISC_R_SUCCESS); + + /* ensure we stop listening after the test is done */ + isc_loop_teardown(isc_loop_main(loopmgr), stop_listening, sock); + + /* Client - unshared */ + result = dns_dispatchmgr_create(mctx, loopmgr, connect_nm, + &test->dispatchmgr); + assert_int_equal(result, ISC_R_SUCCESS); + + result = dns_dispatch_createtcp( + test->dispatchmgr, &tcp_connect_addr, &tcp_server_addr, + DNS_DISPATCHOPT_UNSHARED, &test->dispatch); + assert_int_equal(result, ISC_R_SUCCESS); + + result = dns_dispatch_add( + test->dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT, + &tcp_server_addr, NULL, NULL, connected_newtcp, client_senddone, + response_noop, test, &test->id, &test->dispentry); + assert_int_equal(result, ISC_R_SUCCESS); - dns_dispatch_connect(dispentry); + dns_dispatch_connect(test->dispentry); } ISC_TEST_LIST_START +ISC_TEST_ENTRY_CUSTOM(dispatch_gettcp, setup_test, teardown_test) +ISC_TEST_ENTRY_CUSTOM(dispatch_newtcp, setup_test, teardown_test) ISC_TEST_ENTRY_CUSTOM(dispatch_timeout_udp_response, setup_test, teardown_test) ISC_TEST_ENTRY_CUSTOM(dispatchset_create, setup_test, teardown_test) ISC_TEST_ENTRY_CUSTOM(dispatchset_get, setup_test, teardown_test)