2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-25 03:27:18 +00:00
bind/lib/dns/tests/zonemgr_test.c

264 lines
6.7 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-10-25 20:30:51 -07:00
#if HAVE_CMOCKA
#include <sched.h> /* IWYU pragma: keep */
#include <setjmp.h>
2018-10-25 20:30:51 -07:00
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
2018-10-25 20:30:51 -07:00
#define UNIT_TESTING
#include <cmocka.h>
#include <isc/buffer.h>
#include <isc/task.h>
#include <isc/timer.h>
2018-10-25 20:30:51 -07:00
#include <isc/util.h>
#include <dns/name.h>
#include <dns/view.h>
#include <dns/zone.h>
#include "dnstest.h"
2018-10-25 20:30:51 -07:00
static int
2020-02-13 14:44:37 -08:00
_setup(void **state) {
isc_result_t result;
2018-10-25 20:30:51 -07:00
UNUSED(state);
result = dns_test_begin(NULL, true);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
2018-10-25 20:30:51 -07:00
return (0);
}
2018-10-25 20:30:51 -07:00
static int
2020-02-13 14:44:37 -08:00
_teardown(void **state) {
2018-10-25 20:30:51 -07:00
UNUSED(state);
dns_test_end();
2018-10-25 20:30:51 -07:00
return (0);
}
2018-10-25 20:30:51 -07:00
/* create zone manager */
static void
2020-02-13 14:44:37 -08:00
zonemgr_create(void **state) {
2018-10-25 20:30:51 -07:00
dns_zonemgr_t *myzonemgr = NULL;
2020-02-13 14:44:37 -08:00
isc_result_t result;
2018-10-25 20:30:51 -07:00
UNUSED(state);
dispatch: Clean up connect and recv callbacks - disp_connected() has been split into two functions, udp_connected() (which takes 'resp' as an argument) and tcp_connected() (which takes 'disp', and calls the connect callbacks for all pending resps). - In dns_dispatch_connect(), if a connection is already open, we need to detach the dispentry immediately because we won't be running tcp_connected(). - dns_disptach_cancel() also now calls the connect callbacks for pending TCP responses, and the response callbacks for open TCP connections waiting on read. - If udp_connected() runs after dns_dispatch_cancel() has been called, ensure that the caller's connect callback is run. - If a UDP connection fails with EADDRINUSE, we try again up to five times with a different local port number before giving up. - If a TCP connection is canceled while still pending connection, the connect timeout may still fire. we attach the dispatch before connecting to ensure that it won't be detached too soon in this case. - The dispentry is no longer removed from the pending list when deactivating, so that the connect callback can still be run if dns_dispatch_removeresponse() was run while the connecting was pending. - Rewrote dns_dispatch_gettcp() to avoid a data race. - startrecv() and dispatch_getnext() can be called with a NULL resp when using TCP. - Refactored udp_recv() and tcp_recv() and added result logging. - EOF is now treated the same as CANCELED in response callbacks. - ISC_R_SHUTTINGDOWN is sent to the reponse callbacks for all resps if tcp_recv() is triggered by a netmgr shutdown. (response callbacks are *not* sent by udp_recv() in this case.)
2021-08-04 13:14:11 -07:00
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, NULL,
2018-10-25 20:30:51 -07:00
&myzonemgr);
assert_int_equal(result, ISC_R_SUCCESS);
2018-10-25 20:30:51 -07:00
dns_zonemgr_shutdown(myzonemgr);
dns_zonemgr_detach(&myzonemgr);
assert_null(myzonemgr);
}
2018-10-25 20:30:51 -07:00
/* manage and release a zone */
static void
2020-02-13 14:44:37 -08:00
zonemgr_managezone(void **state) {
dns_zonemgr_t *myzonemgr = NULL;
2020-02-13 14:44:37 -08:00
dns_zone_t *zone = NULL;
isc_result_t result;
2018-10-25 20:30:51 -07:00
UNUSED(state);
dispatch: Clean up connect and recv callbacks - disp_connected() has been split into two functions, udp_connected() (which takes 'resp' as an argument) and tcp_connected() (which takes 'disp', and calls the connect callbacks for all pending resps). - In dns_dispatch_connect(), if a connection is already open, we need to detach the dispentry immediately because we won't be running tcp_connected(). - dns_disptach_cancel() also now calls the connect callbacks for pending TCP responses, and the response callbacks for open TCP connections waiting on read. - If udp_connected() runs after dns_dispatch_cancel() has been called, ensure that the caller's connect callback is run. - If a UDP connection fails with EADDRINUSE, we try again up to five times with a different local port number before giving up. - If a TCP connection is canceled while still pending connection, the connect timeout may still fire. we attach the dispatch before connecting to ensure that it won't be detached too soon in this case. - The dispentry is no longer removed from the pending list when deactivating, so that the connect callback can still be run if dns_dispatch_removeresponse() was run while the connecting was pending. - Rewrote dns_dispatch_gettcp() to avoid a data race. - startrecv() and dispatch_getnext() can be called with a NULL resp when using TCP. - Refactored udp_recv() and tcp_recv() and added result logging. - EOF is now treated the same as CANCELED in response callbacks. - ISC_R_SHUTTINGDOWN is sent to the reponse callbacks for all resps if tcp_recv() is triggered by a netmgr shutdown. (response callbacks are *not* sent by udp_recv() in this case.)
2021-08-04 13:14:11 -07:00
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, NULL,
&myzonemgr);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_test_makezone("foo", &zone, NULL, false);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
/* This should not succeed until the dns_zonemgr_setsize() is run */
result = dns_zonemgr_managezone(myzonemgr, zone);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_FAILURE);
2018-10-25 20:30:51 -07:00
assert_int_equal(dns_zonemgr_getcount(myzonemgr, DNS_ZONESTATE_ANY), 0);
result = dns_zonemgr_setsize(myzonemgr, 1);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
/* Now it should succeed */
result = dns_zonemgr_managezone(myzonemgr, zone);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
2018-10-25 20:30:51 -07:00
assert_int_equal(dns_zonemgr_getcount(myzonemgr, DNS_ZONESTATE_ANY), 1);
dns_zonemgr_releasezone(myzonemgr, zone);
dns_zone_detach(&zone);
2018-10-25 20:30:51 -07:00
assert_int_equal(dns_zonemgr_getcount(myzonemgr, DNS_ZONESTATE_ANY), 0);
dns_zonemgr_shutdown(myzonemgr);
dns_zonemgr_detach(&myzonemgr);
2018-10-25 20:30:51 -07:00
assert_null(myzonemgr);
}
2018-10-25 20:30:51 -07:00
/* create and release a zone */
static void
2020-02-13 14:44:37 -08:00
zonemgr_createzone(void **state) {
dns_zonemgr_t *myzonemgr = NULL;
2020-02-13 14:44:37 -08:00
dns_zone_t *zone = NULL;
isc_result_t result;
2018-10-25 20:30:51 -07:00
UNUSED(state);
dispatch: Clean up connect and recv callbacks - disp_connected() has been split into two functions, udp_connected() (which takes 'resp' as an argument) and tcp_connected() (which takes 'disp', and calls the connect callbacks for all pending resps). - In dns_dispatch_connect(), if a connection is already open, we need to detach the dispentry immediately because we won't be running tcp_connected(). - dns_disptach_cancel() also now calls the connect callbacks for pending TCP responses, and the response callbacks for open TCP connections waiting on read. - If udp_connected() runs after dns_dispatch_cancel() has been called, ensure that the caller's connect callback is run. - If a UDP connection fails with EADDRINUSE, we try again up to five times with a different local port number before giving up. - If a TCP connection is canceled while still pending connection, the connect timeout may still fire. we attach the dispatch before connecting to ensure that it won't be detached too soon in this case. - The dispentry is no longer removed from the pending list when deactivating, so that the connect callback can still be run if dns_dispatch_removeresponse() was run while the connecting was pending. - Rewrote dns_dispatch_gettcp() to avoid a data race. - startrecv() and dispatch_getnext() can be called with a NULL resp when using TCP. - Refactored udp_recv() and tcp_recv() and added result logging. - EOF is now treated the same as CANCELED in response callbacks. - ISC_R_SHUTTINGDOWN is sent to the reponse callbacks for all resps if tcp_recv() is triggered by a netmgr shutdown. (response callbacks are *not* sent by udp_recv() in this case.)
2021-08-04 13:14:11 -07:00
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, NULL,
&myzonemgr);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
/* This should not succeed until the dns_zonemgr_setsize() is run */
result = dns_zonemgr_createzone(myzonemgr, &zone);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_FAILURE);
result = dns_zonemgr_setsize(myzonemgr, 1);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
/* Now it should succeed */
result = dns_zonemgr_createzone(myzonemgr, &zone);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
assert_non_null(zone);
if (zone != NULL) {
dns_zone_detach(&zone);
}
dns_zonemgr_shutdown(myzonemgr);
dns_zonemgr_detach(&myzonemgr);
2018-10-25 20:30:51 -07:00
assert_null(myzonemgr);
}
2018-10-25 20:30:51 -07:00
/* manage and release a zone */
static void
2020-02-13 14:44:37 -08:00
zonemgr_unreachable(void **state) {
dns_zonemgr_t *myzonemgr = NULL;
2020-02-13 14:44:37 -08:00
dns_zone_t *zone = NULL;
isc_sockaddr_t addr1, addr2;
struct in_addr in;
2020-02-13 14:44:37 -08:00
isc_result_t result;
isc_time_t now;
2018-10-25 20:30:51 -07:00
UNUSED(state);
TIME_NOW(&now);
dispatch: Clean up connect and recv callbacks - disp_connected() has been split into two functions, udp_connected() (which takes 'resp' as an argument) and tcp_connected() (which takes 'disp', and calls the connect callbacks for all pending resps). - In dns_dispatch_connect(), if a connection is already open, we need to detach the dispentry immediately because we won't be running tcp_connected(). - dns_disptach_cancel() also now calls the connect callbacks for pending TCP responses, and the response callbacks for open TCP connections waiting on read. - If udp_connected() runs after dns_dispatch_cancel() has been called, ensure that the caller's connect callback is run. - If a UDP connection fails with EADDRINUSE, we try again up to five times with a different local port number before giving up. - If a TCP connection is canceled while still pending connection, the connect timeout may still fire. we attach the dispatch before connecting to ensure that it won't be detached too soon in this case. - The dispentry is no longer removed from the pending list when deactivating, so that the connect callback can still be run if dns_dispatch_removeresponse() was run while the connecting was pending. - Rewrote dns_dispatch_gettcp() to avoid a data race. - startrecv() and dispatch_getnext() can be called with a NULL resp when using TCP. - Refactored udp_recv() and tcp_recv() and added result logging. - EOF is now treated the same as CANCELED in response callbacks. - ISC_R_SHUTTINGDOWN is sent to the reponse callbacks for all resps if tcp_recv() is triggered by a netmgr shutdown. (response callbacks are *not* sent by udp_recv() in this case.)
2021-08-04 13:14:11 -07:00
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, NULL,
&myzonemgr);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_test_makezone("foo", &zone, NULL, false);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_zonemgr_setsize(myzonemgr, 1);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_zonemgr_managezone(myzonemgr, zone);
2018-10-25 20:30:51 -07:00
assert_int_equal(result, ISC_R_SUCCESS);
in.s_addr = inet_addr("10.53.0.1");
isc_sockaddr_fromin(&addr1, &in, 2112);
in.s_addr = inet_addr("10.53.0.2");
isc_sockaddr_fromin(&addr2, &in, 5150);
2018-10-25 20:30:51 -07:00
assert_false(dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now));
/*
* We require multiple unreachableadd calls to mark a server as
* unreachable.
*/
dns_zonemgr_unreachableadd(myzonemgr, &addr1, &addr2, &now);
2018-10-25 20:30:51 -07:00
assert_false(dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now));
dns_zonemgr_unreachableadd(myzonemgr, &addr1, &addr2, &now);
2018-10-25 20:30:51 -07:00
assert_true(dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now));
in.s_addr = inet_addr("10.53.0.3");
isc_sockaddr_fromin(&addr2, &in, 5150);
2018-10-25 20:30:51 -07:00
assert_false(dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now));
/*
* We require multiple unreachableadd calls to mark a server as
* unreachable.
*/
dns_zonemgr_unreachableadd(myzonemgr, &addr1, &addr2, &now);
dns_zonemgr_unreachableadd(myzonemgr, &addr1, &addr2, &now);
2018-10-25 20:30:51 -07:00
assert_true(dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now));
dns_zonemgr_unreachabledel(myzonemgr, &addr1, &addr2);
2018-10-25 20:30:51 -07:00
assert_false(dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now));
in.s_addr = inet_addr("10.53.0.2");
isc_sockaddr_fromin(&addr2, &in, 5150);
2018-10-25 20:30:51 -07:00
assert_true(dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now));
dns_zonemgr_unreachabledel(myzonemgr, &addr1, &addr2);
2018-10-25 20:30:51 -07:00
assert_false(dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now));
dns_zonemgr_releasezone(myzonemgr, zone);
dns_zone_detach(&zone);
dns_zonemgr_shutdown(myzonemgr);
dns_zonemgr_detach(&myzonemgr);
2018-10-25 20:30:51 -07:00
assert_null(myzonemgr);
}
/*
* XXX:
* dns_zonemgr API calls that are not yet part of this unit test:
*
* - dns_zonemgr_attach
* - dns_zonemgr_forcemaint
* - dns_zonemgr_resumexfrs
* - dns_zonemgr_shutdown
* - dns_zonemgr_setsize
* - dns_zonemgr_settransfersin
* - dns_zonemgr_getttransfersin
* - dns_zonemgr_settransfersperns
* - dns_zonemgr_getttransfersperns
* - dns_zonemgr_setiolimit
* - dns_zonemgr_getiolimit
* - dns_zonemgr_dbdestroyed
* - dns_zonemgr_setserialqueryrate
* - dns_zonemgr_getserialqueryrate
*/
2018-10-25 20:30:51 -07:00
int
2020-02-13 14:44:37 -08:00
main(void) {
2018-10-25 20:30:51 -07:00
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(zonemgr_create, _setup,
_teardown),
cmocka_unit_test_setup_teardown(zonemgr_managezone, _setup,
_teardown),
cmocka_unit_test_setup_teardown(zonemgr_createzone, _setup,
_teardown),
cmocka_unit_test_setup_teardown(zonemgr_unreachable, _setup,
_teardown),
2018-10-25 20:30:51 -07: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-10-25 20:30:51 -07:00
printf("1..0 # Skipped: cmocka not available\n");
return (SKIPPED_TEST_EXIT_CODE);
2018-10-25 20:30:51 -07:00
}
#endif /* if HAVE_CMOCKA */