isc_mem_t *mctx; /*%< Memory context */
ns_server_t *sctx; /*%< Server context */
isc_taskmgr_t *taskmgr; /*%< Task manager */
- isc_task_t *excl; /*%< Exclusive task */
+ isc_task_t *task; /*%< Task */
isc_timermgr_t *timermgr; /*%< Timer manager */
isc_nm_t *nm; /*%< Net manager */
uint32_t ncpus; /*%< Number of workers */
static void
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
need_rescan(ns_interfacemgr_t *mgr, struct MSGHDR *rtm, size_t len) {
if (rtm->MSGTYPE != RTM_NEWADDR && rtm->MSGTYPE != RTM_DELADDR) {
void *arg) {
ns_interfacemgr_t *mgr = (ns_interfacemgr_t *)arg;
struct MSGHDR *rtm = NULL;
- bool done = true;
size_t rtmlen;
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_DEBUG(9), "route_recv: %s",
}
#endif /* ifdef RTM_VERSION */
- if (need_rescan(mgr, rtm, rtmlen) && mgr->route != NULL &&
- mgr->sctx->interface_auto)
- {
- isc_event_t *event = NULL;
- event = isc_event_allocate(mgr->mctx, mgr, NS_EVENT_IFSCAN,
- scan_event, mgr, sizeof(*event));
- isc_task_send(mgr->excl, &event);
- }
+ REQUIRE(mgr->route != NULL);
- LOCK(&mgr->lock);
- if (mgr->route != NULL) {
- isc_nm_read(handle, route_recv, mgr);
- done = false;
+ if (need_rescan(mgr, rtm, rtmlen) && mgr->sctx->interface_auto) {
+ ns_interfacemgr_scan(mgr, false, false);
}
- UNLOCK(&mgr->lock);
- if (done) {
- isc_nmhandle_detach(&mgr->route);
- ns_interfacemgr_detach(&mgr);
- }
+ isc_nm_read(handle, route_recv, mgr);
return;
}
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) {
goto cleanup_lock;
}
*/
result = ns_listenlist_create(mctx, &mgr->listenon4);
if (result != ISC_R_SUCCESS) {
- goto cleanup_sctx;
+ goto cleanup_task;
}
ns_listenlist_attach(mgr->listenon4, &mgr->listenon6);
cleanup_listenon:
ns_listenlist_detach(&mgr->listenon4);
ns_listenlist_detach(&mgr->listenon6);
+cleanup_task:
+ isc_task_detach(&mgr->task);
cleanup_lock:
isc_mutex_destroy(&mgr->lock);
-cleanup_sctx:
ns_server_detach(&mgr->sctx);
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
return (result);
if (mgr->sctx != NULL) {
ns_server_detach(&mgr->sctx);
}
- if (mgr->excl != NULL) {
- isc_task_detach(&mgr->excl);
- }
+ isc_task_detach(&mgr->task);
mgr->magic = 0;
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
}
dns_aclenv_t *
ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) {
+ dns_aclenv_t *aclenv = NULL;
+
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
- return (mgr->aclenv);
+ LOCK(&mgr->lock);
+ aclenv = mgr->aclenv;
+ UNLOCK(&mgr->lock);
+
+ return (aclenv);
}
void
INSIST(NS_INTERFACE_VALID(ifp));
next = ISC_LIST_NEXT(ifp, link);
if (ifp->generation != mgr->generation) {
- char sabuf[256];
ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link);
if (LISTENING(ifp)) {
+ char sabuf[256];
isc_sockaddr_format(&ifp->addr, sabuf,
sizeof(sabuf));
isc_log_write(
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
listenon_is_ip6_any(ns_listenelt_t *elt) {
REQUIRE(elt && elt->acl);
}
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;
unsigned int prefixlen;
isc_netaddr_t *netaddr;
/* First add localhost address */
prefixlen = (netaddr->family == AF_INET) ? 32 : 128;
- result = dns_iptable_addprefix(mgr->aclenv->localhost->iptable, netaddr,
- prefixlen, true);
+ result = dns_iptable_addprefix(localhost->iptable, netaddr, prefixlen,
+ true);
if (result != ISC_R_SUCCESS) {
return (result);
}
return (ISC_R_SUCCESS);
}
- result = dns_iptable_addprefix(mgr->aclenv->localnets->iptable, netaddr,
- prefixlen, true);
+ result = dns_iptable_addprefix(localnets->iptable, netaddr, prefixlen,
+ true);
if (result != ISC_R_SUCCESS) {
return (result);
}
old = ISC_LIST_NEXT(old, link))
{
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_mem_put(mgr->mctx, addr, sizeof(*addr));
- } else {
- ISC_LIST_APPEND(mgr->listenon, addr, link);
- }
+ ISC_LIST_APPEND(mgr->listenon, addr, link);
+unlock:
UNLOCK(&mgr->lock);
}
static void
clearlistenon(ns_interfacemgr_t *mgr) {
+ ISC_LIST(isc_sockaddr_t) listenon;
isc_sockaddr_t *old;
+ ISC_LIST_INIT(listenon);
+
LOCK(&mgr->lock);
- old = ISC_LIST_HEAD(mgr->listenon);
+ ISC_LIST_MOVE(listenon, mgr->listenon);
+ UNLOCK(&mgr->lock);
+
+ old = ISC_LIST_HEAD(listenon);
while (old != NULL) {
- ISC_LIST_UNLINK(mgr->listenon, old, link);
+ ISC_LIST_UNLINK(listenon, old, link);
isc_mem_put(mgr->mctx, old, sizeof(*old));
- old = ISC_LIST_HEAD(mgr->listenon);
+ old = ISC_LIST_HEAD(listenon);
}
- UNLOCK(&mgr->lock);
}
static isc_result_t
bool ipv6pktinfo = true;
isc_result_t result;
isc_netaddr_t zero_address, zero_address6;
- ns_listenelt_t *le;
+ ns_listenelt_t *le = NULL;
isc_sockaddr_t listen_addr;
ns_interface_t *ifp = NULL;
bool log_explicit = false;
char sabuf[ISC_SOCKADDR_FORMATSIZE];
bool tried_listening;
bool all_addresses_in_use;
+ dns_acl_t *localhost = NULL;
+ dns_acl_t *localnets = NULL;
if (isc_net_probeipv6() == ISC_R_SUCCESS) {
scan_ipv6 = true;
return (result);
}
- result = clearacl(mgr->mctx, &mgr->aclenv->localhost);
+ result = dns_acl_create(mgr->mctx, 0, &localhost);
if (result != ISC_R_SUCCESS) {
goto cleanup_iter;
}
- result = clearacl(mgr->mctx, &mgr->aclenv->localnets);
+ result = dns_acl_create(mgr->mctx, 0, &localnets);
if (result != ISC_R_SUCCESS) {
- goto cleanup_iter;
+ goto cleanup_localhost;
}
+
clearlistenon(mgr);
tried_listening = false;
result = isc_interfaceiter_next(iter))
{
isc_interface_t interface;
- ns_listenlist_t *ll;
+ ns_listenlist_t *ll = NULL;
unsigned int family;
result = isc_interfaceiter_current(iter, &interface);
goto listenon;
}
- result = setup_locals(mgr, &interface);
+ result = setup_locals(&interface, localhost, localnets);
if (result != ISC_R_SUCCESS) {
goto ignore_interface;
}
? ISC_R_ADDRINUSE
: ISC_R_SUCCESS);
}
+
+ dns_aclenv_set(mgr->aclenv, localhost, localnets);
+
+ /* cleanup_localnets: */
+ dns_acl_detach(&localnets);
+
+cleanup_localhost:
+ dns_acl_detach(&localhost);
+
cleanup_iter:
isc_interfaceiter_destroy(&iter);
return (result);
}
-static isc_result_t
-ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, bool verbose, bool config) {
+isc_result_t
+ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
isc_result_t result;
bool purge = true;
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
+ REQUIRE(isc_nm_tid() == 0);
mgr->generation++; /* Increment the generation count. */
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
ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {
REQUIRE(NS_INTERFACEMGR_VALID(mgr));