return (ISC_R_SUCCESS);
}
-static isc_result_t
-add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr,
- isc_dscp_t dscp, bool wcardport_ok) {
- ns_listenelt_t *lelt = NULL;
- dns_acl_t *src_acl = NULL;
- isc_result_t result;
- isc_sockaddr_t any_sa6;
- isc_netaddr_t netaddr;
-
- REQUIRE(isc_sockaddr_pf(addr) == AF_INET6);
-
- isc_sockaddr_any6(&any_sa6);
- if (!isc_sockaddr_equal(&any_sa6, addr) &&
- (wcardport_ok || isc_sockaddr_getport(addr) != 0))
- {
- isc_netaddr_fromin6(&netaddr, &addr->type.sin6.sin6_addr);
-
- result = dns_acl_create(mctx, 0, &src_acl);
- if (result != ISC_R_SUCCESS) {
- return (result);
- }
-
- result = dns_iptable_addprefix(src_acl->iptable, &netaddr, 128,
- true);
- if (result != ISC_R_SUCCESS) {
- goto clean;
- }
-
- result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr),
- dscp, src_acl, &lelt);
- if (result != ISC_R_SUCCESS) {
- goto clean;
- }
- ISC_LIST_APPEND(list->elts, lelt, link);
- }
-
- return (ISC_R_SUCCESS);
-
-clean:
- INSIST(lelt == NULL);
- dns_acl_detach(&src_acl);
-
- return (result);
-}
-
-/*
- * Make a list of xxx-source addresses and call ns_interfacemgr_adjust()
- * to update the listening interfaces accordingly.
- * We currently only consider IPv6, because this only affects IPv6 wildcard
- * sockets.
- */
-static void
-adjust_interfaces(named_server_t *server, isc_mem_t *mctx) {
- isc_result_t result;
- ns_listenlist_t *list = NULL;
- dns_view_t *view;
- dns_zone_t *zone, *next;
- isc_sockaddr_t addr, *addrp;
- isc_dscp_t dscp = -1;
-
- result = ns_listenlist_create(mctx, &list);
- if (result != ISC_R_SUCCESS) {
- return;
- }
-
- for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
- view = ISC_LIST_NEXT(view, link))
- {
- dns_dispatch_t *dispatch6;
-
- dispatch6 = dns_resolver_dispatchv6(view->resolver);
- if (dispatch6 == NULL) {
- continue;
- }
- result = dns_dispatch_getlocaladdress(dispatch6, &addr);
- if (result != ISC_R_SUCCESS) {
- goto fail;
- }
-
- /*
- * We always add non-wildcard address regardless of whether
- * the port is 'any' (the fourth arg is TRUE): if the port is
- * specific, we need to add it since it may conflict with a
- * listening interface; if it's zero, we'll dynamically open
- * query ports, and some of them may override an existing
- * wildcard IPv6 port.
- */
- /* XXXMPA fix dscp */
- result = add_listenelt(mctx, list, &addr, dscp, true);
- if (result != ISC_R_SUCCESS) {
- goto fail;
- }
- }
-
- zone = NULL;
- for (result = dns_zone_first(server->zonemgr, &zone);
- result == ISC_R_SUCCESS;
- next = NULL, result = dns_zone_next(zone, &next), zone = next)
- {
- dns_view_t *zoneview;
-
- /*
- * At this point the zone list may contain a stale zone
- * just removed from the configuration. To see the validity,
- * check if the corresponding view is in our current view list.
- * There may also be old zones that are still in the process
- * of shutting down and have detached from their old view
- * (zoneview == NULL).
- */
- zoneview = dns_zone_getview(zone);
- if (zoneview == NULL) {
- continue;
- }
- for (view = ISC_LIST_HEAD(server->viewlist);
- view != NULL && view != zoneview;
- view = ISC_LIST_NEXT(view, link))
- {}
- if (view == NULL) {
- continue;
- }
-
- addrp = dns_zone_getnotifysrc6(zone);
- dscp = dns_zone_getnotifysrc6dscp(zone);
- result = add_listenelt(mctx, list, addrp, dscp, false);
- if (result != ISC_R_SUCCESS) {
- goto fail;
- }
-
- addrp = dns_zone_getxfrsource6(zone);
- dscp = dns_zone_getxfrsource6dscp(zone);
- result = add_listenelt(mctx, list, addrp, dscp, false);
- if (result != ISC_R_SUCCESS) {
- goto fail;
- }
- }
-
- ns_interfacemgr_adjust(server->interfacemgr, list, true);
-
-clean:
- ns_listenlist_detach(&list);
- return;
-
-fail:
- /*
- * Even when we failed the procedure, most of other interfaces
- * should work correctly. We therefore just warn it.
- */
- isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
- NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
- "could not adjust the listen-on list; "
- "some interfaces may not work");
- goto clean;
-}
-
/*
* This event callback is invoked to do periodic network interface
* scanning.
isc_mem_put(server->sctx->mctx, altsecret, sizeof(*altsecret));
}
- /*
- * Adjust the listening interfaces in accordance with the source
- * addresses specified in views and zones.
- */
- if (isc_net_probeipv6() == ISC_R_SUCCESS) {
- adjust_interfaces(server, named_g_mctx);
- }
-
/*
* Record the time of most recent configuration
*/
static isc_result_t
ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
- const char *name, ns_interface_t **ifpret, bool accept_tcp,
- isc_dscp_t dscp, bool *addr_in_use) {
+ const char *name, ns_interface_t **ifpret, isc_dscp_t dscp,
+ bool *addr_in_use) {
isc_result_t result;
ns_interface_t *ifp = NULL;
REQUIRE(ifpret != NULL && *ifpret == NULL);
goto cleanup_interface;
}
- if (((mgr->sctx->options & NS_SERVER_NOTCP) == 0) && accept_tcp) {
+ if (((mgr->sctx->options & NS_SERVER_NOTCP) == 0)) {
result = ns_interface_listentcp(ifp);
if (result != ISC_R_SUCCESS) {
if ((result == ISC_R_ADDRINUSE) &&
}
static isc_result_t
-do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) {
+do_scan(ns_interfacemgr_t *mgr, bool verbose) {
isc_interfaceiter_t *iter = NULL;
bool scan_ipv4 = false;
bool scan_ipv6 = false;
- bool adjusting = false;
bool ipv6only = true;
bool ipv6pktinfo = true;
isc_result_t result;
bool tried_listening;
bool all_addresses_in_use;
- if (ext_listen != NULL) {
- adjusting = true;
- }
-
if (isc_net_probeipv6() == ISC_R_SUCCESS) {
scan_ipv6 = true;
} else if ((mgr->sctx->options & NS_SERVER_DISABLE6) == 0) {
"interfaces, port %u",
le->port);
result = ns_interface_setup(mgr, &listen_addr,
- "<any>", &ifp, true,
+ "<any>", &ifp,
le->dscp, NULL);
if (result == ISC_R_SUCCESS) {
ifp->flags |= NS_INTERFACEFLAG_ANYADDR;
return (result);
}
- if (!adjusting) {
- result = clearacl(mgr->mctx, &mgr->aclenv.localhost);
- if (result != ISC_R_SUCCESS) {
- goto cleanup_iter;
- }
- result = clearacl(mgr->mctx, &mgr->aclenv.localnets);
- if (result != ISC_R_SUCCESS) {
- goto cleanup_iter;
- }
- clearlistenon(mgr);
+ result = clearacl(mgr->mctx, &mgr->aclenv.localhost);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup_iter;
}
+ result = clearacl(mgr->mctx, &mgr->aclenv.localnets);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup_iter;
+ }
+ clearlistenon(mgr);
tried_listening = false;
all_addresses_in_use = true;
continue;
}
- if (!adjusting) {
- /*
- * If running with -T fixedlocal, then we only
- * want 127.0.0.1 and ::1 in the localhost ACL.
- */
- if (((mgr->sctx->options & NS_SERVER_FIXEDLOCAL) !=
- 0) &&
- !isc_netaddr_isloopback(&interface.address))
- {
- goto listenon;
- }
+ /*
+ * If running with -T fixedlocal, then we only
+ * want 127.0.0.1 and ::1 in the localhost ACL.
+ */
+ if (((mgr->sctx->options & NS_SERVER_FIXEDLOCAL) != 0) &&
+ !isc_netaddr_isloopback(&interface.address))
+ {
+ goto listenon;
+ }
- result = setup_locals(mgr, &interface);
- if (result != ISC_R_SUCCESS) {
- goto ignore_interface;
- }
+ result = setup_locals(mgr, &interface);
+ if (result != ISC_R_SUCCESS) {
+ goto ignore_interface;
}
listenon:
continue;
}
- if (!adjusting && dolistenon) {
+ if (dolistenon) {
setup_listenon(mgr, &interface, le->port);
dolistenon = false;
}
ipv6_wildcard = true;
}
- /*
- * When adjusting interfaces with extra a listening
- * list, see if the address matches the extra list.
- * If it does, and is also covered by a wildcard
- * interface, we need to listen on the address
- * explicitly.
- */
- if (adjusting) {
- ns_listenelt_t *ele;
-
- match = 0;
- for (ele = ISC_LIST_HEAD(ext_listen->elts);
- ele != NULL;
- ele = ISC_LIST_NEXT(ele, link))
- {
- (void)dns_acl_match(&listen_netaddr,
- NULL, ele->acl,
- NULL, &match, NULL);
- if (match > 0 &&
- (ele->port == le->port ||
- ele->port == 0)) {
- break;
- } else {
- match = 0;
- }
- }
- if (ipv6_wildcard && match == 0) {
- continue;
- }
- }
-
ifp = find_matching_interface(mgr, &listen_sockaddr);
if (ifp != NULL) {
ifp->generation = mgr->generation;
} else {
bool addr_in_use = false;
- if (!adjusting && ipv6_wildcard) {
+ if (ipv6_wildcard) {
continue;
}
if (log_explicit && family == AF_INET6 &&
- !adjusting && listenon_is_ip6_any(le)) {
+ listenon_is_ip6_any(le)) {
isc_log_write(
IFMGR_COMMON_LOGARGS,
verbose ? ISC_LOG_INFO
sizeof(sabuf));
isc_log_write(
IFMGR_COMMON_LOGARGS, ISC_LOG_INFO,
- "%s"
"listening on %s interface "
"%s, %s",
- (adjusting) ? "additionally " : "",
(family == AF_INET) ? "IPv4" : "IPv6",
interface.name, sabuf);
result = ns_interface_setup(
mgr, &listen_sockaddr, interface.name,
- &ifp, (adjusting) ? false : true,
- le->dscp, &addr_in_use);
+ &ifp, le->dscp, &addr_in_use);
tried_listening = true;
if (!addr_in_use) {
}
static isc_result_t
-ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
- bool verbose) {
+ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, bool verbose) {
isc_result_t result;
bool purge = true;
mgr->generation++; /* Increment the generation count. */
- result = do_scan(mgr, ext_listen, verbose);
+ result = do_scan(mgr, verbose);
if ((result != ISC_R_SUCCESS) && (result != ISC_R_ADDRINUSE)) {
purge = false;
}
/*
* Warn if we are not listening on any interface.
*/
- if (ext_listen == NULL && ISC_LIST_EMPTY(mgr->interfaces)) {
+ if (ISC_LIST_EMPTY(mgr->interfaces)) {
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING,
"not listening on any interfaces");
}
unlock = true;
}
- result = ns_interfacemgr_scan0(mgr, NULL, verbose);
+ result = ns_interfacemgr_scan0(mgr, verbose);
if (unlock) {
isc_task_endexclusive(mgr->excl);
return (result);
}
-isc_result_t
-ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list,
- bool verbose) {
- return (ns_interfacemgr_scan0(mgr, list, verbose));
-}
-
void
ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {
REQUIRE(NS_INTERFACEMGR_VALID(mgr));