2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-24 19:18:50 +00:00
bind/lib/dns/tests/resolver_test.c

227 lines
5.0 KiB
C
Raw Normal View History

/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
2018-11-14 20:24:54 +08:00
#if HAVE_CMOCKA
#include <sched.h> /* IWYU pragma: keep */
#include <setjmp.h>
2018-11-14 20:24:54 +08:00
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
2018-11-14 20:24:54 +08:00
#define UNIT_TESTING
#include <cmocka.h>
#include <isc/app.h>
#include <isc/buffer.h>
2018-11-14 20:24:54 +08:00
#include <isc/print.h>
#include <isc/socket.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h>
#include <dns/dispatch.h>
#include <dns/name.h>
#include <dns/resolver.h>
#include <dns/view.h>
#include "dnstest.h"
static dns_dispatchmgr_t *dispatchmgr = NULL;
2020-02-13 14:44:37 -08:00
static dns_dispatch_t *dispatch = NULL;
static dns_view_t *view = NULL;
2018-11-14 20:24:54 +08:00
static int
2020-02-13 14:44:37 -08:00
_setup(void **state) {
isc_result_t result;
isc_sockaddr_t local;
2018-11-14 20:24:54 +08:00
UNUSED(state);
result = dns_test_begin(NULL, true);
2018-11-14 20:24:54 +08:00
assert_int_equal(result, ISC_R_SUCCESS);
Convert dispatch to netmgr The flow of operations in dispatch is changing and will now be similar for both UDP and TCP queries: 1) Call dns_dispatch_addresponse() to assign a query ID and register that we'll be listening for a response with that ID soon. the parameters for this function include callback functions to inform the caller when the socket is connected and when the message has been sent, as well as a task action that will be sent when the response arrives. (later this could become a netmgr callback, but at this stage to minimize disruption to the calling code, we continue to use isc_task for the response event.) on successful completion of this function, a dispatch entry object will be instantiated. 2) Call dns_dispatch_connect() on the dispatch entry. this runs isc_nm_udpconnect() or isc_nm_tcpdnsconnect(), as needed, and begins listening for responses. the caller is informed via a callback function when the connection is established. 3) Call dns_dispatch_send() on the dispatch entry. this runs isc_nm_send() to send a request. 4) Call dns_dispatch_removeresponse() to terminate listening and close the connection. Implementation comments below: - As we will be using netmgr buffers now. code to send the length in TCP queries has also been removed as that is handled by the netmgr. - TCP dispatches can be used by multiple simultaneous queries, so dns_dispatch_connect() now checks whether the dispatch is already connected before calling isc_nm_tcpdnsconnect() again. - Running dns_dispatch_getnext() from a non-network thread caused a crash due to assertions in the netmgr read functions that appear to be unnecessary now. the assertions have been removed. - fctx->nqueries was formerly incremented when the connection was successful, but is now incremented when the query is started and decremented if the connection fails. - It's no longer necessary for each dispatch to have a pool of tasks, so there's now a single task per dispatch. - Dispatch code to avoid UDP ports already in use has been removed. - dns_resolver and dns_request have been modified to use netmgr callback functions instead of task events. some additional changes were needed to handle shutdown processing correctly. - Timeout processing is not yet fully converted to use netmgr timeouts. - Fixed a lock order cycle reported by TSAN (view -> zone-> adb -> view) by by calling dns_zt functions without holding the view lock.
2021-01-14 13:02:57 -08:00
result = dns_dispatchmgr_create(dt_mctx, netmgr, &dispatchmgr);
2018-11-14 20:24:54 +08:00
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_test_makeview("view", &view);
2018-11-14 20:24:54 +08:00
assert_int_equal(result, ISC_R_SUCCESS);
isc_sockaddr_any(&local);
Convert dispatch to netmgr The flow of operations in dispatch is changing and will now be similar for both UDP and TCP queries: 1) Call dns_dispatch_addresponse() to assign a query ID and register that we'll be listening for a response with that ID soon. the parameters for this function include callback functions to inform the caller when the socket is connected and when the message has been sent, as well as a task action that will be sent when the response arrives. (later this could become a netmgr callback, but at this stage to minimize disruption to the calling code, we continue to use isc_task for the response event.) on successful completion of this function, a dispatch entry object will be instantiated. 2) Call dns_dispatch_connect() on the dispatch entry. this runs isc_nm_udpconnect() or isc_nm_tcpdnsconnect(), as needed, and begins listening for responses. the caller is informed via a callback function when the connection is established. 3) Call dns_dispatch_send() on the dispatch entry. this runs isc_nm_send() to send a request. 4) Call dns_dispatch_removeresponse() to terminate listening and close the connection. Implementation comments below: - As we will be using netmgr buffers now. code to send the length in TCP queries has also been removed as that is handled by the netmgr. - TCP dispatches can be used by multiple simultaneous queries, so dns_dispatch_connect() now checks whether the dispatch is already connected before calling isc_nm_tcpdnsconnect() again. - Running dns_dispatch_getnext() from a non-network thread caused a crash due to assertions in the netmgr read functions that appear to be unnecessary now. the assertions have been removed. - fctx->nqueries was formerly incremented when the connection was successful, but is now incremented when the query is started and decremented if the connection fails. - It's no longer necessary for each dispatch to have a pool of tasks, so there's now a single task per dispatch. - Dispatch code to avoid UDP ports already in use has been removed. - dns_resolver and dns_request have been modified to use netmgr callback functions instead of task events. some additional changes were needed to handle shutdown processing correctly. - Timeout processing is not yet fully converted to use netmgr timeouts. - Fixed a lock order cycle reported by TSAN (view -> zone-> adb -> view) by by calling dns_zt functions without holding the view lock.
2021-01-14 13:02:57 -08:00
result = dns_dispatch_createudp(dispatchmgr, taskmgr, &local, 0,
&dispatch);
2018-11-14 20:24:54 +08:00
assert_int_equal(result, ISC_R_SUCCESS);
return (0);
}
2018-11-14 20:24:54 +08:00
static int
2020-02-13 14:44:37 -08:00
_teardown(void **state) {
2018-11-14 20:24:54 +08:00
UNUSED(state);
dns_dispatch_detach(&dispatch);
dns_view_detach(&view);
dns_dispatchmgr_destroy(&dispatchmgr);
dns_test_end();
2018-11-14 20:24:54 +08:00
return (0);
}
static void
2020-02-13 14:44:37 -08:00
mkres(dns_resolver_t **resolverp) {
isc_result_t result;
Convert dispatch to netmgr The flow of operations in dispatch is changing and will now be similar for both UDP and TCP queries: 1) Call dns_dispatch_addresponse() to assign a query ID and register that we'll be listening for a response with that ID soon. the parameters for this function include callback functions to inform the caller when the socket is connected and when the message has been sent, as well as a task action that will be sent when the response arrives. (later this could become a netmgr callback, but at this stage to minimize disruption to the calling code, we continue to use isc_task for the response event.) on successful completion of this function, a dispatch entry object will be instantiated. 2) Call dns_dispatch_connect() on the dispatch entry. this runs isc_nm_udpconnect() or isc_nm_tcpdnsconnect(), as needed, and begins listening for responses. the caller is informed via a callback function when the connection is established. 3) Call dns_dispatch_send() on the dispatch entry. this runs isc_nm_send() to send a request. 4) Call dns_dispatch_removeresponse() to terminate listening and close the connection. Implementation comments below: - As we will be using netmgr buffers now. code to send the length in TCP queries has also been removed as that is handled by the netmgr. - TCP dispatches can be used by multiple simultaneous queries, so dns_dispatch_connect() now checks whether the dispatch is already connected before calling isc_nm_tcpdnsconnect() again. - Running dns_dispatch_getnext() from a non-network thread caused a crash due to assertions in the netmgr read functions that appear to be unnecessary now. the assertions have been removed. - fctx->nqueries was formerly incremented when the connection was successful, but is now incremented when the query is started and decremented if the connection fails. - It's no longer necessary for each dispatch to have a pool of tasks, so there's now a single task per dispatch. - Dispatch code to avoid UDP ports already in use has been removed. - dns_resolver and dns_request have been modified to use netmgr callback functions instead of task events. some additional changes were needed to handle shutdown processing correctly. - Timeout processing is not yet fully converted to use netmgr timeouts. - Fixed a lock order cycle reported by TSAN (view -> zone-> adb -> view) by by calling dns_zt functions without holding the view lock.
2021-01-14 13:02:57 -08:00
result = dns_resolver_create(view, taskmgr, 1, 1, netmgr, timermgr, 0,
dispatchmgr, dispatch, NULL, resolverp);
2018-11-14 20:24:54 +08:00
assert_int_equal(result, ISC_R_SUCCESS);
}
static void
2020-02-13 14:44:37 -08:00
destroy_resolver(dns_resolver_t **resolverp) {
dns_resolver_shutdown(*resolverp);
dns_resolver_detach(resolverp);
}
2018-11-14 20:24:54 +08:00
/* dns_resolver_create */
static void
2020-02-13 14:44:37 -08:00
create_test(void **state) {
dns_resolver_t *resolver = NULL;
2018-11-14 20:24:54 +08:00
UNUSED(state);
mkres(&resolver);
destroy_resolver(&resolver);
}
2018-11-14 20:24:54 +08:00
/* dns_resolver_gettimeout */
static void
2020-02-13 14:44:37 -08:00
gettimeout_test(void **state) {
dns_resolver_t *resolver = NULL;
2020-02-13 14:44:37 -08:00
unsigned int timeout;
2018-11-14 20:24:54 +08:00
UNUSED(state);
mkres(&resolver);
timeout = dns_resolver_gettimeout(resolver);
2018-11-14 20:24:54 +08:00
assert_true(timeout > 0);
destroy_resolver(&resolver);
}
2018-11-14 20:24:54 +08:00
/* dns_resolver_settimeout */
static void
2020-02-13 14:44:37 -08:00
settimeout_test(void **state) {
dns_resolver_t *resolver = NULL;
2020-02-13 14:44:37 -08:00
unsigned int default_timeout, timeout;
2018-11-14 20:24:54 +08:00
UNUSED(state);
mkres(&resolver);
default_timeout = dns_resolver_gettimeout(resolver);
dns_resolver_settimeout(resolver, default_timeout + 1);
timeout = dns_resolver_gettimeout(resolver);
2018-11-14 20:24:54 +08:00
assert_true(timeout == default_timeout + 1);
destroy_resolver(&resolver);
}
2018-11-14 20:24:54 +08:00
/* dns_resolver_settimeout */
static void
2020-02-13 14:44:37 -08:00
settimeout_default_test(void **state) {
dns_resolver_t *resolver = NULL;
2020-02-13 14:44:37 -08:00
unsigned int default_timeout, timeout;
2018-11-14 20:24:54 +08:00
UNUSED(state);
mkres(&resolver);
default_timeout = dns_resolver_gettimeout(resolver);
dns_resolver_settimeout(resolver, default_timeout + 100);
timeout = dns_resolver_gettimeout(resolver);
2018-11-14 20:24:54 +08:00
assert_int_equal(timeout, default_timeout + 100);
dns_resolver_settimeout(resolver, 0);
timeout = dns_resolver_gettimeout(resolver);
2018-11-14 20:24:54 +08:00
assert_int_equal(timeout, default_timeout);
destroy_resolver(&resolver);
}
2018-11-14 20:24:54 +08:00
/* dns_resolver_settimeout below minimum */
static void
2020-02-13 14:44:37 -08:00
settimeout_belowmin_test(void **state) {
dns_resolver_t *resolver = NULL;
2020-02-13 14:44:37 -08:00
unsigned int default_timeout, timeout;
2018-11-14 20:24:54 +08:00
UNUSED(state);
mkres(&resolver);
default_timeout = dns_resolver_gettimeout(resolver);
dns_resolver_settimeout(resolver, 9000);
timeout = dns_resolver_gettimeout(resolver);
2018-11-14 20:24:54 +08:00
assert_int_equal(timeout, default_timeout);
destroy_resolver(&resolver);
}
2018-11-14 20:24:54 +08:00
/* dns_resolver_settimeout over maximum */
static void
2020-02-13 14:44:37 -08:00
settimeout_overmax_test(void **state) {
dns_resolver_t *resolver = NULL;
2020-02-13 14:44:37 -08:00
unsigned int timeout;
2018-11-14 20:24:54 +08:00
UNUSED(state);
mkres(&resolver);
dns_resolver_settimeout(resolver, 4000000);
timeout = dns_resolver_gettimeout(resolver);
2018-11-14 20:24:54 +08:00
assert_in_range(timeout, 0, 3999999);
destroy_resolver(&resolver);
}
2018-11-14 20:24:54 +08:00
int
2020-02-13 14:44:37 -08:00
main(void) {
2018-11-14 20:24:54 +08:00
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(create_test, _setup, _teardown),
cmocka_unit_test_setup_teardown(gettimeout_test, _setup,
_teardown),
cmocka_unit_test_setup_teardown(settimeout_test, _setup,
_teardown),
cmocka_unit_test_setup_teardown(settimeout_default_test, _setup,
_teardown),
2018-11-14 20:24:54 +08:00
cmocka_unit_test_setup_teardown(settimeout_belowmin_test,
_setup, _teardown),
cmocka_unit_test_setup_teardown(settimeout_overmax_test, _setup,
_teardown),
2018-11-14 20:24:54 +08:00
};
return (cmocka_run_group_tests(tests, NULL, NULL));
}
#else /* HAVE_CMOCKA */
#include <stdio.h>
int
2020-02-13 14:44:37 -08:00
main(void) {
2018-11-14 20:24:54 +08:00
printf("1..0 # Skipped: cmocka not available\n");
return (SKIPPED_TEST_EXIT_CODE);
}
2018-11-14 20:24:54 +08:00
#endif /* if HAVE_CMOCKA */