mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
Remove exclusive mode from ns_interfacemgr
Now that the dns_aclenv_t has now properly rwlocked .localhost and .localnets member, we can remove the task exclusive mode use from the ns_interfacemgr. Some light related cleanup has been also done.
This commit is contained in:
@@ -74,7 +74,7 @@ struct ns_interfacemgr {
|
|||||||
isc_mem_t *mctx; /*%< Memory context */
|
isc_mem_t *mctx; /*%< Memory context */
|
||||||
ns_server_t *sctx; /*%< Server context */
|
ns_server_t *sctx; /*%< Server context */
|
||||||
isc_taskmgr_t *taskmgr; /*%< Task manager */
|
isc_taskmgr_t *taskmgr; /*%< Task manager */
|
||||||
isc_task_t *excl; /*%< Exclusive task */
|
isc_task_t *task; /*%< Task */
|
||||||
isc_timermgr_t *timermgr; /*%< Timer manager */
|
isc_timermgr_t *timermgr; /*%< Timer manager */
|
||||||
isc_nm_t *nm; /*%< Net manager */
|
isc_nm_t *nm; /*%< Net manager */
|
||||||
uint32_t ncpus; /*%< Number of workers */
|
uint32_t ncpus; /*%< Number of workers */
|
||||||
@@ -97,16 +97,6 @@ purge_old_interfaces(ns_interfacemgr_t *mgr);
|
|||||||
static void
|
static void
|
||||||
clearlistenon(ns_interfacemgr_t *mgr);
|
clearlistenon(ns_interfacemgr_t *mgr);
|
||||||
|
|
||||||
static void
|
|
||||||
scan_event(isc_task_t *task, isc_event_t *event) {
|
|
||||||
ns_interfacemgr_t *mgr = (ns_interfacemgr_t *)event->ev_arg;
|
|
||||||
|
|
||||||
UNUSED(task);
|
|
||||||
|
|
||||||
ns_interfacemgr_scan(mgr, false, false);
|
|
||||||
isc_event_free(&event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
need_rescan(ns_interfacemgr_t *mgr, struct MSGHDR *rtm, size_t len) {
|
need_rescan(ns_interfacemgr_t *mgr, struct MSGHDR *rtm, size_t len) {
|
||||||
if (rtm->MSGTYPE != RTM_NEWADDR && rtm->MSGTYPE != RTM_DELADDR) {
|
if (rtm->MSGTYPE != RTM_NEWADDR && rtm->MSGTYPE != RTM_DELADDR) {
|
||||||
@@ -216,7 +206,6 @@ route_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
|
|||||||
void *arg) {
|
void *arg) {
|
||||||
ns_interfacemgr_t *mgr = (ns_interfacemgr_t *)arg;
|
ns_interfacemgr_t *mgr = (ns_interfacemgr_t *)arg;
|
||||||
struct MSGHDR *rtm = NULL;
|
struct MSGHDR *rtm = NULL;
|
||||||
bool done = true;
|
|
||||||
size_t rtmlen;
|
size_t rtmlen;
|
||||||
|
|
||||||
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_DEBUG(9), "route_recv: %s",
|
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_DEBUG(9), "route_recv: %s",
|
||||||
@@ -262,26 +251,13 @@ route_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
|
|||||||
}
|
}
|
||||||
#endif /* ifdef RTM_VERSION */
|
#endif /* ifdef RTM_VERSION */
|
||||||
|
|
||||||
if (need_rescan(mgr, rtm, rtmlen) && mgr->route != NULL &&
|
REQUIRE(mgr->route != NULL);
|
||||||
mgr->sctx->interface_auto)
|
|
||||||
{
|
if (need_rescan(mgr, rtm, rtmlen) && mgr->sctx->interface_auto) {
|
||||||
isc_event_t *event = NULL;
|
ns_interfacemgr_scan(mgr, false, false);
|
||||||
event = isc_event_allocate(mgr->mctx, mgr, NS_EVENT_IFSCAN,
|
|
||||||
scan_event, mgr, sizeof(*event));
|
|
||||||
isc_task_send(mgr->excl, &event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(&mgr->lock);
|
isc_nm_read(handle, route_recv, mgr);
|
||||||
if (mgr->route != NULL) {
|
|
||||||
isc_nm_read(handle, route_recv, mgr);
|
|
||||||
done = false;
|
|
||||||
}
|
|
||||||
UNLOCK(&mgr->lock);
|
|
||||||
|
|
||||||
if (done) {
|
|
||||||
isc_nmhandle_detach(&mgr->route);
|
|
||||||
ns_interfacemgr_detach(&mgr);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,7 +309,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
|
|||||||
|
|
||||||
isc_mutex_init(&mgr->lock);
|
isc_mutex_init(&mgr->lock);
|
||||||
|
|
||||||
result = isc_taskmgr_excltask(taskmgr, &mgr->excl);
|
result = isc_task_create_bound(taskmgr, 0, &mgr->task, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_lock;
|
goto cleanup_lock;
|
||||||
}
|
}
|
||||||
@@ -348,7 +324,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
|
|||||||
*/
|
*/
|
||||||
result = ns_listenlist_create(mctx, &mgr->listenon4);
|
result = ns_listenlist_create(mctx, &mgr->listenon4);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_sctx;
|
goto cleanup_task;
|
||||||
}
|
}
|
||||||
ns_listenlist_attach(mgr->listenon4, &mgr->listenon6);
|
ns_listenlist_attach(mgr->listenon4, &mgr->listenon6);
|
||||||
|
|
||||||
@@ -389,9 +365,10 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
|
|||||||
cleanup_listenon:
|
cleanup_listenon:
|
||||||
ns_listenlist_detach(&mgr->listenon4);
|
ns_listenlist_detach(&mgr->listenon4);
|
||||||
ns_listenlist_detach(&mgr->listenon6);
|
ns_listenlist_detach(&mgr->listenon6);
|
||||||
|
cleanup_task:
|
||||||
|
isc_task_detach(&mgr->task);
|
||||||
cleanup_lock:
|
cleanup_lock:
|
||||||
isc_mutex_destroy(&mgr->lock);
|
isc_mutex_destroy(&mgr->lock);
|
||||||
cleanup_sctx:
|
|
||||||
ns_server_detach(&mgr->sctx);
|
ns_server_detach(&mgr->sctx);
|
||||||
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
|
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
|
||||||
return (result);
|
return (result);
|
||||||
@@ -417,9 +394,7 @@ ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) {
|
|||||||
if (mgr->sctx != NULL) {
|
if (mgr->sctx != NULL) {
|
||||||
ns_server_detach(&mgr->sctx);
|
ns_server_detach(&mgr->sctx);
|
||||||
}
|
}
|
||||||
if (mgr->excl != NULL) {
|
isc_task_detach(&mgr->task);
|
||||||
isc_task_detach(&mgr->excl);
|
|
||||||
}
|
|
||||||
mgr->magic = 0;
|
mgr->magic = 0;
|
||||||
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
|
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
|
||||||
}
|
}
|
||||||
@@ -434,9 +409,15 @@ ns_interfacemgr_setbacklog(ns_interfacemgr_t *mgr, int backlog) {
|
|||||||
|
|
||||||
dns_aclenv_t *
|
dns_aclenv_t *
|
||||||
ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) {
|
ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) {
|
||||||
|
dns_aclenv_t *aclenv = NULL;
|
||||||
|
|
||||||
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
||||||
|
|
||||||
return (mgr->aclenv);
|
LOCK(&mgr->lock);
|
||||||
|
aclenv = mgr->aclenv;
|
||||||
|
UNLOCK(&mgr->lock);
|
||||||
|
|
||||||
|
return (aclenv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -810,9 +791,9 @@ purge_old_interfaces(ns_interfacemgr_t *mgr) {
|
|||||||
INSIST(NS_INTERFACE_VALID(ifp));
|
INSIST(NS_INTERFACE_VALID(ifp));
|
||||||
next = ISC_LIST_NEXT(ifp, link);
|
next = ISC_LIST_NEXT(ifp, link);
|
||||||
if (ifp->generation != mgr->generation) {
|
if (ifp->generation != mgr->generation) {
|
||||||
char sabuf[256];
|
|
||||||
ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link);
|
ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link);
|
||||||
if (LISTENING(ifp)) {
|
if (LISTENING(ifp)) {
|
||||||
|
char sabuf[256];
|
||||||
isc_sockaddr_format(&ifp->addr, sabuf,
|
isc_sockaddr_format(&ifp->addr, sabuf,
|
||||||
sizeof(sabuf));
|
sizeof(sabuf));
|
||||||
isc_log_write(
|
isc_log_write(
|
||||||
@@ -826,20 +807,6 @@ purge_old_interfaces(ns_interfacemgr_t *mgr) {
|
|||||||
UNLOCK(&mgr->lock);
|
UNLOCK(&mgr->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
|
||||||
clearacl(isc_mem_t *mctx, dns_acl_t **aclp) {
|
|
||||||
dns_acl_t *newacl = NULL;
|
|
||||||
isc_result_t result;
|
|
||||||
result = dns_acl_create(mctx, 0, &newacl);
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
dns_acl_detach(aclp);
|
|
||||||
dns_acl_attach(newacl, aclp);
|
|
||||||
dns_acl_detach(&newacl);
|
|
||||||
return (ISC_R_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
listenon_is_ip6_any(ns_listenelt_t *elt) {
|
listenon_is_ip6_any(ns_listenelt_t *elt) {
|
||||||
REQUIRE(elt && elt->acl);
|
REQUIRE(elt && elt->acl);
|
||||||
@@ -847,7 +814,8 @@ listenon_is_ip6_any(ns_listenelt_t *elt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) {
|
setup_locals(isc_interface_t *interface, dns_acl_t *localhost,
|
||||||
|
dns_acl_t *localnets) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
unsigned int prefixlen;
|
unsigned int prefixlen;
|
||||||
isc_netaddr_t *netaddr;
|
isc_netaddr_t *netaddr;
|
||||||
@@ -856,8 +824,8 @@ setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) {
|
|||||||
|
|
||||||
/* First add localhost address */
|
/* First add localhost address */
|
||||||
prefixlen = (netaddr->family == AF_INET) ? 32 : 128;
|
prefixlen = (netaddr->family == AF_INET) ? 32 : 128;
|
||||||
result = dns_iptable_addprefix(mgr->aclenv->localhost->iptable, netaddr,
|
result = dns_iptable_addprefix(localhost->iptable, netaddr, prefixlen,
|
||||||
prefixlen, true);
|
true);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
@@ -887,8 +855,8 @@ setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) {
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = dns_iptable_addprefix(mgr->aclenv->localnets->iptable, netaddr,
|
result = dns_iptable_addprefix(localnets->iptable, netaddr, prefixlen,
|
||||||
prefixlen, true);
|
true);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
@@ -911,30 +879,34 @@ setup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface,
|
|||||||
old = ISC_LIST_NEXT(old, link))
|
old = ISC_LIST_NEXT(old, link))
|
||||||
{
|
{
|
||||||
if (isc_sockaddr_equal(addr, old)) {
|
if (isc_sockaddr_equal(addr, old)) {
|
||||||
break;
|
/* We found an existing address */
|
||||||
|
isc_mem_put(mgr->mctx, addr, sizeof(*addr));
|
||||||
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old != NULL) {
|
ISC_LIST_APPEND(mgr->listenon, addr, link);
|
||||||
isc_mem_put(mgr->mctx, addr, sizeof(*addr));
|
unlock:
|
||||||
} else {
|
|
||||||
ISC_LIST_APPEND(mgr->listenon, addr, link);
|
|
||||||
}
|
|
||||||
UNLOCK(&mgr->lock);
|
UNLOCK(&mgr->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clearlistenon(ns_interfacemgr_t *mgr) {
|
clearlistenon(ns_interfacemgr_t *mgr) {
|
||||||
|
ISC_LIST(isc_sockaddr_t) listenon;
|
||||||
isc_sockaddr_t *old;
|
isc_sockaddr_t *old;
|
||||||
|
|
||||||
|
ISC_LIST_INIT(listenon);
|
||||||
|
|
||||||
LOCK(&mgr->lock);
|
LOCK(&mgr->lock);
|
||||||
old = ISC_LIST_HEAD(mgr->listenon);
|
ISC_LIST_MOVE(listenon, mgr->listenon);
|
||||||
while (old != NULL) {
|
|
||||||
ISC_LIST_UNLINK(mgr->listenon, old, link);
|
|
||||||
isc_mem_put(mgr->mctx, old, sizeof(*old));
|
|
||||||
old = ISC_LIST_HEAD(mgr->listenon);
|
|
||||||
}
|
|
||||||
UNLOCK(&mgr->lock);
|
UNLOCK(&mgr->lock);
|
||||||
|
|
||||||
|
old = ISC_LIST_HEAD(listenon);
|
||||||
|
while (old != NULL) {
|
||||||
|
ISC_LIST_UNLINK(listenon, old, link);
|
||||||
|
isc_mem_put(mgr->mctx, old, sizeof(*old));
|
||||||
|
old = ISC_LIST_HEAD(listenon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
@@ -946,7 +918,7 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||||||
bool ipv6pktinfo = true;
|
bool ipv6pktinfo = true;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_netaddr_t zero_address, zero_address6;
|
isc_netaddr_t zero_address, zero_address6;
|
||||||
ns_listenelt_t *le;
|
ns_listenelt_t *le = NULL;
|
||||||
isc_sockaddr_t listen_addr;
|
isc_sockaddr_t listen_addr;
|
||||||
ns_interface_t *ifp = NULL;
|
ns_interface_t *ifp = NULL;
|
||||||
bool log_explicit = false;
|
bool log_explicit = false;
|
||||||
@@ -954,6 +926,8 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||||||
char sabuf[ISC_SOCKADDR_FORMATSIZE];
|
char sabuf[ISC_SOCKADDR_FORMATSIZE];
|
||||||
bool tried_listening;
|
bool tried_listening;
|
||||||
bool all_addresses_in_use;
|
bool all_addresses_in_use;
|
||||||
|
dns_acl_t *localhost = NULL;
|
||||||
|
dns_acl_t *localnets = NULL;
|
||||||
|
|
||||||
if (isc_net_probeipv6() == ISC_R_SUCCESS) {
|
if (isc_net_probeipv6() == ISC_R_SUCCESS) {
|
||||||
scan_ipv6 = true;
|
scan_ipv6 = true;
|
||||||
@@ -1067,14 +1041,15 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = clearacl(mgr->mctx, &mgr->aclenv->localhost);
|
result = dns_acl_create(mgr->mctx, 0, &localhost);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_iter;
|
goto cleanup_iter;
|
||||||
}
|
}
|
||||||
result = clearacl(mgr->mctx, &mgr->aclenv->localnets);
|
result = dns_acl_create(mgr->mctx, 0, &localnets);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_iter;
|
goto cleanup_localhost;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearlistenon(mgr);
|
clearlistenon(mgr);
|
||||||
|
|
||||||
tried_listening = false;
|
tried_listening = false;
|
||||||
@@ -1083,7 +1058,7 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||||||
result = isc_interfaceiter_next(iter))
|
result = isc_interfaceiter_next(iter))
|
||||||
{
|
{
|
||||||
isc_interface_t interface;
|
isc_interface_t interface;
|
||||||
ns_listenlist_t *ll;
|
ns_listenlist_t *ll = NULL;
|
||||||
unsigned int family;
|
unsigned int family;
|
||||||
|
|
||||||
result = isc_interfaceiter_current(iter, &interface);
|
result = isc_interfaceiter_current(iter, &interface);
|
||||||
@@ -1128,7 +1103,7 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||||||
goto listenon;
|
goto listenon;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = setup_locals(mgr, &interface);
|
result = setup_locals(&interface, localhost, localnets);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto ignore_interface;
|
goto ignore_interface;
|
||||||
}
|
}
|
||||||
@@ -1276,17 +1251,27 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||||||
? ISC_R_ADDRINUSE
|
? ISC_R_ADDRINUSE
|
||||||
: ISC_R_SUCCESS);
|
: ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dns_aclenv_set(mgr->aclenv, localhost, localnets);
|
||||||
|
|
||||||
|
/* cleanup_localnets: */
|
||||||
|
dns_acl_detach(&localnets);
|
||||||
|
|
||||||
|
cleanup_localhost:
|
||||||
|
dns_acl_detach(&localhost);
|
||||||
|
|
||||||
cleanup_iter:
|
cleanup_iter:
|
||||||
isc_interfaceiter_destroy(&iter);
|
isc_interfaceiter_destroy(&iter);
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
isc_result_t
|
||||||
ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
bool purge = true;
|
bool purge = true;
|
||||||
|
|
||||||
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
||||||
|
REQUIRE(isc_nm_tid() == 0);
|
||||||
|
|
||||||
mgr->generation++; /* Increment the generation count. */
|
mgr->generation++; /* Increment the generation count. */
|
||||||
|
|
||||||
@@ -1323,30 +1308,6 @@ ns_interfacemgr_islistening(ns_interfacemgr_t *mgr) {
|
|||||||
return (ISC_LIST_EMPTY(mgr->interfaces) ? false : true);
|
return (ISC_LIST_EMPTY(mgr->interfaces) ? false : true);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
|
||||||
ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|
||||||
isc_result_t result;
|
|
||||||
bool unlock = false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for success because we may already be task-exclusive
|
|
||||||
* at this point. Only if we succeed at obtaining an exclusive
|
|
||||||
* lock now will we need to relinquish it later.
|
|
||||||
*/
|
|
||||||
result = isc_task_beginexclusive(mgr->excl);
|
|
||||||
if (result == ISC_R_SUCCESS) {
|
|
||||||
unlock = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ns_interfacemgr_scan0(mgr, verbose, config);
|
|
||||||
|
|
||||||
if (unlock) {
|
|
||||||
isc_task_endexclusive(mgr->excl);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {
|
ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {
|
||||||
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
||||||
|
Reference in New Issue
Block a user