1999-05-20 12:37:35 +00:00
|
|
|
/*
|
2017-09-08 13:39:09 -07:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
1999-05-20 12:37:35 +00:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
2021-06-03 08:37:05 +02:00
|
|
|
*
|
1999-05-20 12:37:35 +00:00
|
|
|
* 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/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
1999-05-20 12:37:35 +00:00
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
2000-01-11 21:18:22 +00:00
|
|
|
* information regarding copyright ownership.
|
1999-05-20 12:37:35 +00:00
|
|
|
*/
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*! \file */
|
2000-06-22 22:00:42 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
2000-04-28 03:53:48 +00:00
|
|
|
#include <isc/interfaceiter.h>
|
2024-08-14 13:25:50 +02:00
|
|
|
#include <isc/log.h>
|
2022-07-26 13:03:45 +02:00
|
|
|
#include <isc/loop.h>
|
2019-11-05 15:34:35 -08:00
|
|
|
#include <isc/netmgr.h>
|
2011-07-28 04:04:37 +00:00
|
|
|
#include <isc/os.h>
|
2017-09-28 10:09:22 -07:00
|
|
|
#include <isc/random.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <isc/string.h>
|
2022-07-26 13:03:45 +02:00
|
|
|
#include <isc/tid.h>
|
2000-01-11 21:18:22 +00:00
|
|
|
#include <isc/util.h>
|
1999-05-20 12:37:35 +00:00
|
|
|
|
2000-01-25 21:21:05 +00:00
|
|
|
#include <dns/acl.h>
|
1999-07-24 01:17:28 +00:00
|
|
|
#include <dns/dispatch.h>
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
#include <ns/client.h>
|
|
|
|
#include <ns/interfacemgr.h>
|
|
|
|
#include <ns/server.h>
|
2019-11-22 18:34:50 -03:00
|
|
|
#include <ns/stats.h>
|
2014-02-07 17:16:37 +11:00
|
|
|
|
|
|
|
#ifdef HAVE_NET_ROUTE_H
|
|
|
|
#include <net/route.h>
|
|
|
|
#if defined(RTM_VERSION) && defined(RTM_NEWADDR) && defined(RTM_DELADDR)
|
2021-10-02 17:17:54 -07:00
|
|
|
#define MSGHDR rt_msghdr
|
|
|
|
#define MSGTYPE rtm_type
|
2014-02-10 09:46:54 +11:00
|
|
|
#endif /* if defined(RTM_VERSION) && defined(RTM_NEWADDR) && \
|
|
|
|
* defined(RTM_DELADDR) */
|
|
|
|
#endif /* ifdef HAVE_NET_ROUTE_H */
|
|
|
|
|
|
|
|
#if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
|
2021-12-14 13:38:28 +02:00
|
|
|
#define LINUX_NETLINK_AVAILABLE
|
2014-02-10 09:46:54 +11:00
|
|
|
#include <linux/netlink.h>
|
|
|
|
#include <linux/rtnetlink.h>
|
|
|
|
#if defined(RTM_NEWADDR) && defined(RTM_DELADDR)
|
2021-10-02 17:17:54 -07:00
|
|
|
#define MSGHDR nlmsghdr
|
|
|
|
#define MSGTYPE nlmsg_type
|
2014-02-07 17:16:37 +11:00
|
|
|
#endif /* if defined(RTM_NEWADDR) && defined(RTM_DELADDR) */
|
|
|
|
#endif /* if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) \
|
2020-02-13 21:48:23 +01:00
|
|
|
*/
|
1999-05-20 12:37:35 +00:00
|
|
|
|
2021-12-14 16:51:02 -08:00
|
|
|
#define LISTENING(ifp) (((ifp)->flags & NS_INTERFACEFLAG_LISTENING) != 0)
|
|
|
|
|
2001-06-04 19:33:39 +00:00
|
|
|
#define IFMGR_MAGIC ISC_MAGIC('I', 'F', 'M', 'G')
|
|
|
|
#define NS_INTERFACEMGR_VALID(t) ISC_MAGIC_VALID(t, IFMGR_MAGIC)
|
1999-05-20 12:37:35 +00:00
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*% nameserver interface manager structure */
|
1999-05-20 12:37:35 +00:00
|
|
|
struct ns_interfacemgr {
|
2021-05-22 18:12:11 +02:00
|
|
|
unsigned int magic; /*%< Magic number */
|
2019-05-16 18:43:06 +02:00
|
|
|
isc_refcount_t references;
|
2000-01-11 21:18:22 +00:00
|
|
|
isc_mutex_t lock;
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_mem_t *mctx; /*%< Memory context */
|
|
|
|
ns_server_t *sctx; /*%< Server context */
|
2022-07-26 13:03:45 +02:00
|
|
|
isc_loopmgr_t *loopmgr; /*%< Loop manager */
|
2022-07-26 13:03:40 +02:00
|
|
|
isc_nm_t *nm; /*%< Net manager */
|
|
|
|
uint32_t ncpus; /*%< Number of workers */
|
2000-05-10 21:34:50 +00:00
|
|
|
dns_dispatchmgr_t *dispatchmgr;
|
2021-05-22 18:12:11 +02:00
|
|
|
unsigned int generation; /*%< Current generation no */
|
2000-06-05 19:10:13 +00:00
|
|
|
ns_listenlist_t *listenon4;
|
|
|
|
ns_listenlist_t *listenon6;
|
2021-05-22 18:12:11 +02:00
|
|
|
dns_aclenv_t *aclenv; /*%< Localhost/localnets ACLs */
|
|
|
|
ISC_LIST(ns_interface_t) interfaces; /*%< List of interfaces */
|
2005-02-10 05:53:43 +00:00
|
|
|
ISC_LIST(isc_sockaddr_t) listenon;
|
2021-05-22 18:12:11 +02:00
|
|
|
int backlog; /*%< Listen queue size */
|
|
|
|
atomic_bool shuttingdown; /*%< Interfacemgr shutting down */
|
|
|
|
ns_clientmgr_t **clientmgrs; /*%< Client managers */
|
2021-10-02 17:17:54 -07:00
|
|
|
isc_nmhandle_t *route;
|
1999-05-20 12:37:35 +00:00
|
|
|
};
|
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
static void
|
|
|
|
purge_old_interfaces(ns_interfacemgr_t *mgr);
|
1999-05-20 12:37:35 +00:00
|
|
|
|
2005-02-10 05:53:43 +00:00
|
|
|
static void
|
|
|
|
clearlistenon(ns_interfacemgr_t *mgr);
|
|
|
|
|
2021-12-14 13:38:28 +02:00
|
|
|
static bool
|
|
|
|
need_rescan(ns_interfacemgr_t *mgr, struct MSGHDR *rtm, size_t len) {
|
|
|
|
if (rtm->MSGTYPE != RTM_NEWADDR && rtm->MSGTYPE != RTM_DELADDR) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef LINUX_NETLINK_AVAILABLE
|
|
|
|
UNUSED(mgr);
|
|
|
|
UNUSED(len);
|
|
|
|
/* On most systems, any NEWADDR or DELADDR means we rescan */
|
|
|
|
return true;
|
|
|
|
#else /* LINUX_NETLINK_AVAILABLE */
|
|
|
|
/* ...but on linux we need to check the messages more carefully */
|
|
|
|
for (struct MSGHDR *nlh = rtm;
|
|
|
|
NLMSG_OK(nlh, len) && nlh->nlmsg_type != NLMSG_DONE;
|
|
|
|
nlh = NLMSG_NEXT(nlh, len))
|
|
|
|
{
|
|
|
|
struct ifaddrmsg *ifa = (struct ifaddrmsg *)NLMSG_DATA(nlh);
|
|
|
|
struct rtattr *rth = IFA_RTA(ifa);
|
|
|
|
size_t rtl = IFA_PAYLOAD(nlh);
|
|
|
|
|
|
|
|
while (rtl > 0 && RTA_OK(rth, rtl)) {
|
|
|
|
/*
|
|
|
|
* Look for IFA_ADDRESS to detect IPv6 interface
|
|
|
|
* state changes.
|
|
|
|
*/
|
|
|
|
if (rth->rta_type == IFA_ADDRESS &&
|
2022-11-02 19:33:14 +01:00
|
|
|
ifa->ifa_family == AF_INET6)
|
|
|
|
{
|
2021-12-14 16:51:02 -08:00
|
|
|
bool existed = false;
|
2021-12-14 13:38:28 +02:00
|
|
|
bool was_listening = false;
|
|
|
|
isc_netaddr_t addr = { 0 };
|
|
|
|
|
|
|
|
isc_netaddr_fromin6(&addr, RTA_DATA(rth));
|
2021-12-14 16:51:02 -08:00
|
|
|
INSIST(isc_netaddr_getzone(&addr) == 0);
|
2021-12-14 13:38:28 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check whether we were listening on the
|
|
|
|
* address. We need to do this as the
|
|
|
|
* Linux kernel seems to issue messages
|
|
|
|
* containing IFA_ADDRESS far more often
|
|
|
|
* than the actual state changes (on
|
|
|
|
* router advertisements?)
|
|
|
|
*/
|
|
|
|
LOCK(&mgr->lock);
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH (mgr->interfaces, ifp, link) {
|
2021-12-14 13:38:28 +02:00
|
|
|
isc_netaddr_t tmp = { 0 };
|
|
|
|
isc_netaddr_fromsockaddr(&tmp,
|
|
|
|
&ifp->addr);
|
2021-12-14 16:51:02 -08:00
|
|
|
if (tmp.family != AF_INET6) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We have to nullify the zone (IPv6
|
|
|
|
* scope ID) because we haven't got one
|
|
|
|
* from the kernel. Otherwise match
|
|
|
|
* could fail even for an existing
|
|
|
|
* address.
|
|
|
|
*/
|
|
|
|
isc_netaddr_setzone(&tmp, 0);
|
2021-12-14 13:38:28 +02:00
|
|
|
if (isc_netaddr_equal(&tmp, &addr)) {
|
2021-12-14 16:51:02 -08:00
|
|
|
was_listening = LISTENING(ifp);
|
|
|
|
existed = true;
|
2021-12-14 13:38:28 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Do rescan if the state of the interface
|
|
|
|
* has changed.
|
|
|
|
*/
|
2021-12-14 16:51:02 -08:00
|
|
|
if ((!existed && rtm->MSGTYPE == RTM_NEWADDR) ||
|
|
|
|
(existed && was_listening &&
|
2021-12-14 13:38:28 +02:00
|
|
|
rtm->MSGTYPE == RTM_DELADDR))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else if (rth->rta_type == IFA_ADDRESS &&
|
2022-11-02 19:33:14 +01:00
|
|
|
ifa->ifa_family == AF_INET)
|
|
|
|
{
|
2021-12-14 13:38:28 +02:00
|
|
|
/*
|
|
|
|
* It seems that the IPv4 P2P link state
|
|
|
|
* has changed.
|
|
|
|
*/
|
|
|
|
return true;
|
|
|
|
} else if (rth->rta_type == IFA_LOCAL) {
|
|
|
|
/*
|
|
|
|
* Local address state has changed - do
|
|
|
|
* rescan.
|
|
|
|
*/
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
rth = RTA_NEXT(rth, rtl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* LINUX_NETLINK_AVAILABLE */
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-10-02 17:17:54 -07:00
|
|
|
static void
|
|
|
|
route_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
|
|
|
|
void *arg) {
|
|
|
|
ns_interfacemgr_t *mgr = (ns_interfacemgr_t *)arg;
|
|
|
|
struct MSGHDR *rtm = NULL;
|
2021-12-14 13:38:28 +02:00
|
|
|
size_t rtmlen;
|
2014-02-07 17:16:37 +11:00
|
|
|
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_DEBUG(9), "route_recv: %s",
|
2021-10-02 17:17:54 -07:00
|
|
|
isc_result_totext(eresult));
|
|
|
|
|
|
|
|
if (handle == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-07-02 09:22:54 +02:00
|
|
|
switch (eresult) {
|
|
|
|
case ISC_R_SUCCESS:
|
|
|
|
break;
|
|
|
|
default:
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_ERROR,
|
2024-07-02 09:22:54 +02:00
|
|
|
"automatic interface scanning terminated: %s",
|
|
|
|
isc_result_totext(eresult));
|
|
|
|
FALLTHROUGH;
|
|
|
|
case ISC_R_CANCELED:
|
|
|
|
case ISC_R_SHUTTINGDOWN:
|
|
|
|
case ISC_R_EOF:
|
|
|
|
ns_interfacemgr_routedisconnect(mgr);
|
2014-02-07 17:16:37 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-10-02 17:17:54 -07:00
|
|
|
rtm = (struct MSGHDR *)region->base;
|
2021-12-14 13:38:28 +02:00
|
|
|
rtmlen = region->length;
|
|
|
|
|
2014-02-10 09:46:54 +11:00
|
|
|
#ifdef RTM_VERSION
|
2014-02-07 17:16:37 +11:00
|
|
|
if (rtm->rtm_version != RTM_VERSION) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_ERROR,
|
2014-02-07 17:16:37 +11:00
|
|
|
"automatic interface rescanning disabled: "
|
|
|
|
"rtm->rtm_version mismatch (%u != %u) "
|
|
|
|
"recompile required",
|
|
|
|
rtm->rtm_version, RTM_VERSION);
|
2021-10-02 17:17:54 -07:00
|
|
|
isc_nmhandle_detach(&mgr->route);
|
2021-10-17 16:45:22 -07:00
|
|
|
ns_interfacemgr_detach(&mgr);
|
2014-02-07 17:16:37 +11:00
|
|
|
return;
|
|
|
|
}
|
2014-02-10 09:46:54 +11:00
|
|
|
#endif /* ifdef RTM_VERSION */
|
2014-02-07 17:16:37 +11:00
|
|
|
|
2022-03-14 12:38:46 +01:00
|
|
|
REQUIRE(mgr->route != NULL);
|
2014-02-07 17:16:37 +11:00
|
|
|
|
2022-03-14 12:38:46 +01:00
|
|
|
if (need_rescan(mgr, rtm, rtmlen) && mgr->sctx->interface_auto) {
|
|
|
|
ns_interfacemgr_scan(mgr, false, false);
|
2014-04-03 19:48:29 -07:00
|
|
|
}
|
|
|
|
|
2022-03-14 12:38:46 +01:00
|
|
|
isc_nm_read(handle, route_recv, mgr);
|
2014-04-03 19:48:29 -07:00
|
|
|
return;
|
2014-02-07 17:16:37 +11:00
|
|
|
}
|
2021-10-02 17:17:54 -07:00
|
|
|
|
|
|
|
static void
|
|
|
|
route_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
|
|
|
|
ns_interfacemgr_t *mgr = (ns_interfacemgr_t *)arg;
|
|
|
|
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_DEBUG(9), "route_connected: %s",
|
|
|
|
isc_result_totext(eresult));
|
2021-10-02 17:17:54 -07:00
|
|
|
|
|
|
|
if (eresult != ISC_R_SUCCESS) {
|
2022-06-14 10:49:04 +00:00
|
|
|
ns_interfacemgr_detach(&mgr);
|
2021-10-02 17:17:54 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
INSIST(mgr->route == NULL);
|
|
|
|
|
|
|
|
isc_nmhandle_attach(handle, &mgr->route);
|
|
|
|
isc_nm_read(handle, route_recv, mgr);
|
|
|
|
}
|
2014-02-07 17:16:37 +11:00
|
|
|
|
1999-07-24 01:17:28 +00:00
|
|
|
isc_result_t
|
2017-09-08 13:39:09 -07:00
|
|
|
ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
|
2022-10-29 14:22:56 -07:00
|
|
|
isc_loopmgr_t *loopmgr, isc_nm_t *nm,
|
|
|
|
dns_dispatchmgr_t *dispatchmgr,
|
2024-07-02 09:22:54 +02:00
|
|
|
dns_geoip_databases_t *geoip, ns_interfacemgr_t **mgrp) {
|
2000-01-11 21:18:22 +00:00
|
|
|
isc_result_t result;
|
2021-10-02 17:17:54 -07:00
|
|
|
ns_interfacemgr_t *mgr = NULL;
|
2000-01-11 21:18:22 +00:00
|
|
|
|
1999-05-20 12:37:35 +00:00
|
|
|
REQUIRE(mctx != NULL);
|
|
|
|
REQUIRE(mgrp != NULL);
|
|
|
|
REQUIRE(*mgrp == NULL);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-05-20 12:37:35 +00:00
|
|
|
mgr = isc_mem_get(mctx, sizeof(*mgr));
|
2022-03-18 09:50:58 +01:00
|
|
|
*mgr = (ns_interfacemgr_t){
|
2022-07-26 13:03:40 +02:00
|
|
|
.loopmgr = loopmgr,
|
2022-03-18 09:50:58 +01:00
|
|
|
.nm = nm,
|
|
|
|
.dispatchmgr = dispatchmgr,
|
|
|
|
.generation = 1,
|
2022-07-26 13:03:45 +02:00
|
|
|
.ncpus = isc_loopmgr_nloops(loopmgr),
|
2022-03-18 09:50:58 +01:00
|
|
|
};
|
1999-05-20 12:37:35 +00:00
|
|
|
|
2013-03-08 14:38:03 +11:00
|
|
|
isc_mem_attach(mctx, &mgr->mctx);
|
2017-09-08 13:39:09 -07:00
|
|
|
ns_server_attach(sctx, &mgr->sctx);
|
|
|
|
|
2018-11-16 15:33:22 +01:00
|
|
|
isc_mutex_init(&mgr->lock);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2019-12-07 23:44:16 +01:00
|
|
|
atomic_init(&mgr->shuttingdown, false);
|
2008-07-22 23:47:04 +00:00
|
|
|
|
1999-05-20 12:37:35 +00:00
|
|
|
ISC_LIST_INIT(mgr->interfaces);
|
2005-02-10 05:53:43 +00:00
|
|
|
ISC_LIST_INIT(mgr->listenon);
|
1999-05-20 12:37:35 +00:00
|
|
|
|
2000-06-05 19:10:13 +00:00
|
|
|
/*
|
|
|
|
* The listen-on lists are initially empty.
|
|
|
|
*/
|
|
|
|
result = ns_listenlist_create(mctx, &mgr->listenon4);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2022-10-29 14:22:56 -07:00
|
|
|
goto cleanup_lock;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-06-05 19:10:13 +00:00
|
|
|
ns_listenlist_attach(mgr->listenon4, &mgr->listenon6);
|
2000-02-09 22:59:40 +00:00
|
|
|
|
2023-10-13 08:17:31 +02:00
|
|
|
dns_aclenv_create(mctx, &mgr->aclenv);
|
2019-06-27 21:08:20 -07:00
|
|
|
#if defined(HAVE_GEOIP2)
|
2021-05-22 18:12:11 +02:00
|
|
|
mgr->aclenv->geoip = geoip;
|
2017-09-08 13:39:09 -07:00
|
|
|
#else /* if defined(HAVE_GEOIP2) */
|
|
|
|
UNUSED(geoip);
|
2013-02-27 17:19:39 -08:00
|
|
|
#endif /* if defined(HAVE_GEOIP2) */
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2019-05-16 18:43:06 +02:00
|
|
|
isc_refcount_init(&mgr->references, 1);
|
1999-05-20 12:37:35 +00:00
|
|
|
mgr->magic = IFMGR_MAGIC;
|
|
|
|
*mgrp = mgr;
|
2014-02-07 17:16:37 +11:00
|
|
|
|
2023-08-23 08:56:31 +02:00
|
|
|
mgr->clientmgrs = isc_mem_cget(mgr->mctx, mgr->ncpus,
|
|
|
|
sizeof(mgr->clientmgrs[0]));
|
2022-03-18 09:50:58 +01:00
|
|
|
for (size_t i = 0; i < mgr->ncpus; i++) {
|
2022-10-29 14:22:56 -07:00
|
|
|
result = ns_clientmgr_create(mgr->sctx, mgr->loopmgr,
|
|
|
|
mgr->aclenv, (int)i,
|
2021-05-22 18:12:11 +02:00
|
|
|
&mgr->clientmgrs[i]);
|
|
|
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
return ISC_R_SUCCESS;
|
2000-01-13 23:32:41 +00:00
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
cleanup_lock:
|
|
|
|
isc_mutex_destroy(&mgr->lock);
|
|
|
|
ns_server_detach(&mgr->sctx);
|
2013-03-08 14:38:03 +11:00
|
|
|
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
|
2000-01-13 23:32:41 +00:00
|
|
|
return result;
|
1999-05-20 12:37:35 +00:00
|
|
|
}
|
|
|
|
|
2024-07-02 09:22:54 +02:00
|
|
|
void
|
|
|
|
ns_interfacemgr_routeconnect(ns_interfacemgr_t *mgr) {
|
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
|
|
|
REQUIRE(isc_tid() == 0);
|
|
|
|
|
|
|
|
if (mgr->route != NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ns_interfacemgr_ref(mgr);
|
|
|
|
|
|
|
|
isc_result_t result = isc_nm_routeconnect(mgr->nm, route_connected,
|
|
|
|
mgr);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_INFO, "unable to open route socket: %s",
|
2024-07-02 09:22:54 +02:00
|
|
|
isc_result_totext(result));
|
|
|
|
ns_interfacemgr_unref(mgr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ns_interfacemgr_routedisconnect(ns_interfacemgr_t *mgr) {
|
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
|
|
|
REQUIRE(isc_tid() == 0);
|
|
|
|
|
|
|
|
if (mgr->route == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_nmhandle_close(mgr->route);
|
|
|
|
isc_nmhandle_detach(&mgr->route);
|
|
|
|
ns_interfacemgr_detach(&mgr);
|
|
|
|
}
|
|
|
|
|
2000-01-11 21:18:22 +00:00
|
|
|
static void
|
2024-07-02 09:22:54 +02:00
|
|
|
ns_interfacemgr__destroy(ns_interfacemgr_t *mgr) {
|
2000-01-11 21:18:22 +00:00
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
2014-02-07 17:16:37 +11:00
|
|
|
|
2019-07-23 08:27:30 -04:00
|
|
|
isc_refcount_destroy(&mgr->references);
|
|
|
|
|
2021-05-22 18:12:11 +02:00
|
|
|
dns_aclenv_detach(&mgr->aclenv);
|
2000-06-05 19:10:13 +00:00
|
|
|
ns_listenlist_detach(&mgr->listenon4);
|
|
|
|
ns_listenlist_detach(&mgr->listenon6);
|
2005-02-10 05:53:43 +00:00
|
|
|
clearlistenon(mgr);
|
2018-11-19 10:31:09 +00:00
|
|
|
isc_mutex_destroy(&mgr->lock);
|
2022-03-18 09:50:58 +01:00
|
|
|
for (size_t i = 0; i < mgr->ncpus; i++) {
|
2022-11-03 17:42:12 +01:00
|
|
|
ns_clientmgr_detach(&mgr->clientmgrs[i]);
|
2021-05-22 18:12:11 +02:00
|
|
|
}
|
2023-08-23 08:56:31 +02:00
|
|
|
isc_mem_cput(mgr->mctx, mgr->clientmgrs, mgr->ncpus,
|
|
|
|
sizeof(mgr->clientmgrs[0]));
|
2021-05-22 18:12:11 +02:00
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
if (mgr->sctx != NULL) {
|
|
|
|
ns_server_detach(&mgr->sctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-01-11 21:18:22 +00:00
|
|
|
mgr->magic = 0;
|
2013-03-08 14:38:03 +11:00
|
|
|
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
|
2000-01-11 21:18:22 +00:00
|
|
|
}
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
void
|
|
|
|
ns_interfacemgr_setbacklog(ns_interfacemgr_t *mgr, int backlog) {
|
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
|
|
|
LOCK(&mgr->lock);
|
|
|
|
mgr->backlog = backlog;
|
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
}
|
|
|
|
|
2000-02-09 22:59:40 +00:00
|
|
|
dns_aclenv_t *
|
2000-05-08 14:38:29 +00:00
|
|
|
ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) {
|
2022-03-14 12:38:46 +01:00
|
|
|
dns_aclenv_t *aclenv = NULL;
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
|
|
|
|
2022-03-14 12:38:46 +01:00
|
|
|
LOCK(&mgr->lock);
|
|
|
|
aclenv = mgr->aclenv;
|
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
|
|
|
|
return aclenv;
|
2000-02-09 22:59:40 +00:00
|
|
|
}
|
|
|
|
|
2024-07-02 09:22:54 +02:00
|
|
|
ISC_REFCOUNT_IMPL(ns_interfacemgr, ns_interfacemgr__destroy);
|
2000-01-11 21:18:22 +00:00
|
|
|
|
|
|
|
void
|
2000-05-08 14:38:29 +00:00
|
|
|
ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) {
|
2000-01-11 21:18:22 +00:00
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
2000-01-11 21:18:22 +00:00
|
|
|
* Shut down and detach all interfaces.
|
2021-10-17 16:45:22 -07:00
|
|
|
* By incrementing the generation count, we make
|
|
|
|
* purge_old_interfaces() consider all interfaces "old".
|
2000-01-11 21:18:22 +00:00
|
|
|
*/
|
|
|
|
mgr->generation++;
|
2019-12-07 23:44:16 +01:00
|
|
|
atomic_store(&mgr->shuttingdown, true);
|
2021-10-02 17:17:54 -07:00
|
|
|
|
2021-10-17 16:45:22 -07:00
|
|
|
purge_old_interfaces(mgr);
|
|
|
|
|
2014-04-03 19:48:29 -07:00
|
|
|
if (mgr->route != NULL) {
|
2022-04-25 13:38:33 +02:00
|
|
|
isc_nm_cancelread(mgr->route);
|
2014-04-03 19:48:29 -07:00
|
|
|
}
|
2022-11-03 17:42:12 +01:00
|
|
|
|
|
|
|
for (size_t i = 0; i < mgr->ncpus; i++) {
|
|
|
|
ns_clientmgr_shutdown(mgr->clientmgrs[i]);
|
|
|
|
}
|
2000-01-11 21:18:22 +00:00
|
|
|
}
|
|
|
|
|
2023-01-31 13:30:12 -08:00
|
|
|
void
|
|
|
|
ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
|
|
|
|
const char *name, ns_interface_t **ifpret) {
|
2020-12-09 19:44:41 -08:00
|
|
|
ns_interface_t *ifp = NULL;
|
2023-01-31 13:30:12 -08:00
|
|
|
const char *default_name = "default";
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-01-11 21:18:22 +00:00
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
2011-07-28 11:16:04 +00:00
|
|
|
|
1999-05-20 12:37:35 +00:00
|
|
|
ifp = isc_mem_get(mgr->mctx, sizeof(*ifp));
|
2024-01-09 19:16:26 +02:00
|
|
|
*ifp = (ns_interface_t){ .generation = mgr->generation,
|
|
|
|
.addr = *addr,
|
|
|
|
.proxy_type = ISC_NM_PROXY_NONE };
|
2011-07-28 11:16:04 +00:00
|
|
|
|
2023-01-31 13:30:12 -08:00
|
|
|
if (name == NULL) {
|
|
|
|
name = default_name;
|
|
|
|
}
|
2017-09-14 18:11:56 +10:00
|
|
|
strlcpy(ifp->name, name, sizeof(ifp->name));
|
1999-05-20 12:37:35 +00:00
|
|
|
|
2018-11-16 15:33:22 +01:00
|
|
|
isc_mutex_init(&ifp->lock);
|
2000-01-11 21:18:22 +00:00
|
|
|
|
2019-04-17 15:22:27 +02:00
|
|
|
isc_refcount_init(&ifp->ntcpaccepting, 0);
|
|
|
|
isc_refcount_init(&ifp->ntcpactive, 0);
|
2019-02-06 11:27:11 -08:00
|
|
|
|
2000-09-22 00:13:08 +00:00
|
|
|
ISC_LINK_INIT(ifp, link);
|
|
|
|
|
2000-01-11 21:18:22 +00:00
|
|
|
ns_interfacemgr_attach(mgr, &ifp->mgr);
|
2022-09-06 17:12:14 -07:00
|
|
|
ifp->magic = IFACE_MAGIC;
|
|
|
|
|
2019-07-04 15:45:06 +02:00
|
|
|
LOCK(&mgr->lock);
|
2000-01-11 21:18:22 +00:00
|
|
|
ISC_LIST_APPEND(mgr->interfaces, ifp, link);
|
2019-07-04 15:45:06 +02:00
|
|
|
UNLOCK(&mgr->lock);
|
2000-01-11 21:18:22 +00:00
|
|
|
|
|
|
|
*ifpret = ifp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2023-10-30 17:03:30 +02:00
|
|
|
ns_interface_listenudp(ns_interface_t *ifp, isc_nm_proxy_type_t proxy) {
|
2000-01-11 21:18:22 +00:00
|
|
|
isc_result_t result;
|
2011-07-28 04:04:37 +00:00
|
|
|
|
2019-11-05 15:34:35 -08:00
|
|
|
/* Reserve space for an ns_client_t with the netmgr handle */
|
2023-10-30 17:03:30 +02:00
|
|
|
if (proxy == ISC_NM_PROXY_NONE) {
|
|
|
|
result = isc_nm_listenudp(ifp->mgr->nm, ISC_NM_LISTEN_ALL,
|
|
|
|
&ifp->addr, ns_client_request, ifp,
|
|
|
|
&ifp->udplistensocket);
|
|
|
|
} else {
|
|
|
|
INSIST(proxy == ISC_NM_PROXY_PLAIN);
|
|
|
|
result = isc_nm_listenproxyudp(ifp->mgr->nm, ISC_NM_LISTEN_ALL,
|
|
|
|
&ifp->addr, ns_client_request,
|
|
|
|
ifp, &ifp->udplistensocket);
|
|
|
|
}
|
2000-01-11 21:18:22 +00:00
|
|
|
return result;
|
|
|
|
}
|
1999-07-24 01:17:28 +00:00
|
|
|
|
2000-01-11 21:18:22 +00:00
|
|
|
static isc_result_t
|
2023-10-30 17:03:30 +02:00
|
|
|
ns_interface_listentcp(ns_interface_t *ifp, isc_nm_proxy_type_t proxy) {
|
2000-01-11 21:18:22 +00:00
|
|
|
isc_result_t result;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2022-08-05 19:43:34 +03:00
|
|
|
result = isc_nm_listenstreamdns(
|
2022-01-11 23:35:22 -08:00
|
|
|
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request,
|
2022-03-25 16:44:21 +01:00
|
|
|
ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog,
|
2023-10-30 17:03:30 +02:00
|
|
|
&ifp->mgr->sctx->tcpquota, NULL, proxy, &ifp->tcplistensocket);
|
2000-01-11 21:18:22 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_ERROR, "creating TCP socket: %s",
|
2000-01-11 21:18:22 +00:00
|
|
|
isc_result_totext(result));
|
|
|
|
}
|
2019-11-05 15:34:35 -08:00
|
|
|
|
2019-11-22 18:34:50 -03:00
|
|
|
/*
|
2019-11-25 18:36:14 -03:00
|
|
|
* We call this now to update the tcp-highwater statistic:
|
|
|
|
* this is necessary because we are adding to the TCP quota just
|
|
|
|
* by listening.
|
2019-11-22 18:34:50 -03:00
|
|
|
*/
|
2020-06-17 12:09:10 -07:00
|
|
|
result = ns__client_tcpconn(NULL, ISC_R_SUCCESS, ifp);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_ERROR, "connecting TCP socket: %s",
|
2020-06-17 12:09:10 -07:00
|
|
|
isc_result_totext(result));
|
|
|
|
}
|
2019-11-22 18:34:50 -03:00
|
|
|
|
2014-12-18 11:58:50 +05:30
|
|
|
return result;
|
1999-05-20 12:37:35 +00:00
|
|
|
}
|
|
|
|
|
2020-10-01 13:18:47 +02:00
|
|
|
/*
|
|
|
|
* XXXWPK we should probably pass a complete object with key, cert, and other
|
|
|
|
* TLS related options.
|
|
|
|
*/
|
|
|
|
static isc_result_t
|
2023-10-30 17:03:30 +02:00
|
|
|
ns_interface_listentls(ns_interface_t *ifp, isc_nm_proxy_type_t proxy,
|
|
|
|
isc_tlsctx_t *sslctx) {
|
2020-10-01 13:18:47 +02:00
|
|
|
isc_result_t result;
|
|
|
|
|
2022-11-29 18:15:54 +02:00
|
|
|
result = isc_nm_listenstreamdns(
|
2022-01-11 23:35:22 -08:00
|
|
|
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request,
|
2022-03-25 16:44:21 +01:00
|
|
|
ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog,
|
2023-10-30 17:03:30 +02:00
|
|
|
&ifp->mgr->sctx->tcpquota, sslctx, proxy,
|
2024-01-09 19:16:26 +02:00
|
|
|
&ifp->tlslistensocket);
|
2020-10-01 13:18:47 +02:00
|
|
|
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_ERROR, "creating TLS socket: %s",
|
2020-10-01 13:18:47 +02:00
|
|
|
isc_result_totext(result));
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We call this now to update the tcp-highwater statistic:
|
|
|
|
* this is necessary because we are adding to the TCP quota just
|
|
|
|
* by listening.
|
|
|
|
*/
|
|
|
|
result = ns__client_tcpconn(NULL, ISC_R_SUCCESS, ifp);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_ERROR, "updating TCP stats: %s",
|
2020-10-01 13:18:47 +02:00
|
|
|
isc_result_totext(result));
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-06-22 19:31:18 +03:00
|
|
|
#ifdef HAVE_LIBNGHTTP2
|
|
|
|
static isc_result_t
|
|
|
|
load_http_endpoints(isc_nm_http_endpoints_t *epset, ns_interface_t *ifp,
|
|
|
|
char **eps, size_t neps) {
|
|
|
|
isc_result_t result = ISC_R_FAILURE;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < neps; i++) {
|
|
|
|
result = isc_nm_http_endpoints_add(epset, eps[i],
|
2022-01-11 23:35:22 -08:00
|
|
|
ns_client_request, ifp);
|
2022-06-22 19:31:18 +03:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
#endif /* HAVE_LIBNGHTTP2 */
|
|
|
|
|
2020-12-07 14:19:10 +02:00
|
|
|
static isc_result_t
|
2023-10-30 17:03:30 +02:00
|
|
|
ns_interface_listenhttp(ns_interface_t *ifp, isc_nm_proxy_type_t proxy,
|
|
|
|
isc_tlsctx_t *sslctx, char **eps, size_t neps,
|
|
|
|
uint32_t max_clients, uint32_t max_concurrent_streams) {
|
2021-04-21 13:52:15 +02:00
|
|
|
#if HAVE_LIBNGHTTP2
|
2021-07-13 12:32:47 +03:00
|
|
|
isc_result_t result = ISC_R_FAILURE;
|
2020-12-07 14:19:10 +02:00
|
|
|
isc_nmsocket_t *sock = NULL;
|
2021-07-13 12:32:47 +03:00
|
|
|
isc_nm_http_endpoints_t *epset = NULL;
|
2022-06-22 14:52:58 +03:00
|
|
|
isc_quota_t *quota = NULL;
|
2020-12-07 14:19:10 +02:00
|
|
|
|
2021-07-13 12:32:47 +03:00
|
|
|
epset = isc_nm_http_endpoints_new(ifp->mgr->mctx);
|
2020-12-07 14:19:10 +02:00
|
|
|
|
2022-06-22 19:31:18 +03:00
|
|
|
result = load_http_endpoints(epset, ifp, eps, neps);
|
2020-12-07 14:19:10 +02:00
|
|
|
|
2021-07-13 12:32:47 +03:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2022-06-22 14:52:58 +03:00
|
|
|
quota = isc_mem_get(ifp->mgr->mctx, sizeof(*quota));
|
|
|
|
isc_quota_init(quota, max_clients);
|
2023-05-10 22:01:36 +03:00
|
|
|
result = isc_nm_listenhttp(
|
|
|
|
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr,
|
|
|
|
ifp->mgr->backlog, quota, sslctx, epset,
|
2023-10-30 17:03:30 +02:00
|
|
|
max_concurrent_streams, proxy, &sock);
|
2021-07-13 12:32:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_nm_http_endpoints_detach(&epset);
|
|
|
|
|
2022-06-22 14:52:58 +03:00
|
|
|
if (quota != NULL) {
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
isc_quota_destroy(quota);
|
|
|
|
isc_mem_put(ifp->mgr->mctx, quota, sizeof(*quota));
|
|
|
|
} else {
|
|
|
|
ifp->http_quota = quota;
|
|
|
|
ns_server_append_http_quota(ifp->mgr->sctx, quota);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-07 14:19:10 +02:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_ERROR, "creating %s socket: %s",
|
2020-12-07 14:19:10 +02:00
|
|
|
sslctx ? "HTTPS" : "HTTP",
|
|
|
|
isc_result_totext(result));
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sslctx) {
|
|
|
|
ifp->http_secure_listensocket = sock;
|
|
|
|
} else {
|
|
|
|
ifp->http_listensocket = sock;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We call this now to update the tcp-highwater statistic:
|
|
|
|
* this is necessary because we are adding to the TCP quota just
|
|
|
|
* by listening.
|
|
|
|
*/
|
|
|
|
result = ns__client_tcpconn(NULL, ISC_R_SUCCESS, ifp);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_ERROR, "updating TCP stats: %s",
|
2020-12-07 14:19:10 +02:00
|
|
|
isc_result_totext(result));
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
2021-04-21 13:52:15 +02:00
|
|
|
#else
|
|
|
|
UNUSED(ifp);
|
2023-10-30 17:03:30 +02:00
|
|
|
UNUSED(proxy);
|
2021-04-21 13:52:15 +02:00
|
|
|
UNUSED(sslctx);
|
|
|
|
UNUSED(eps);
|
|
|
|
UNUSED(neps);
|
2022-06-22 14:52:58 +03:00
|
|
|
UNUSED(max_clients);
|
2021-05-18 12:03:58 +03:00
|
|
|
UNUSED(max_concurrent_streams);
|
2021-04-21 13:52:15 +02:00
|
|
|
return ISC_R_NOTIMPLEMENTED;
|
|
|
|
#endif
|
2020-12-07 14:19:10 +02:00
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
static isc_result_t
|
2021-12-14 16:51:02 -08:00
|
|
|
interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, const char *name,
|
|
|
|
ns_interface_t **ifpret, ns_listenelt_t *elt,
|
|
|
|
bool *addr_in_use) {
|
2000-01-11 21:18:22 +00:00
|
|
|
isc_result_t result;
|
|
|
|
ns_interface_t *ifp = NULL;
|
2021-12-14 16:51:02 -08:00
|
|
|
|
|
|
|
REQUIRE(ifpret != NULL);
|
2020-03-30 13:49:55 -07:00
|
|
|
REQUIRE(addr_in_use == NULL || !*addr_in_use);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2021-12-14 16:51:02 -08:00
|
|
|
ifp = *ifpret;
|
|
|
|
|
|
|
|
if (ifp == NULL) {
|
2023-01-31 13:30:12 -08:00
|
|
|
ns_interface_create(mgr, addr, name, &ifp);
|
2021-12-14 16:51:02 -08:00
|
|
|
} else {
|
|
|
|
REQUIRE(!LISTENING(ifp));
|
2024-01-09 19:16:26 +02:00
|
|
|
LOCK(&mgr->lock);
|
|
|
|
ifp->generation = mgr->generation;
|
|
|
|
UNLOCK(&mgr->lock);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-05-20 12:37:35 +00:00
|
|
|
|
2021-12-14 16:51:02 -08:00
|
|
|
ifp->flags |= NS_INTERFACEFLAG_LISTENING;
|
2024-01-09 19:16:26 +02:00
|
|
|
ifp->proxy_type = elt->proxy;
|
2020-10-01 13:18:47 +02:00
|
|
|
|
2020-12-07 14:19:10 +02:00
|
|
|
if (elt->is_http) {
|
Add (http-)listener-clients option (DoH quota mechanism)
This commit adds support for http-listener-clients global options as
well as ability to override the default in an HTTP server description,
like:
http local-http-server {
...
listener-clients 100;
...
};
This way we have ability to specify per-listener active connections
quota globally and then override it when required. This is exactly
what AT&T requested us: they wanted a functionality to specify quota
globally and then override it for specific IPs. This change
functionality makes such a configuration possible.
It makes sense: for example, one could have different quotas for
internal and external clients. Or, for example, one could use BIND's
internal ability to serve encrypted DoH with some sane quota value for
internal clients, while having un-encrypted DoH listener without quota
to put BIND behind a load balancer doing TLS offloading for external
clients.
Moreover, the code no more shares the quota with TCP, which makes
little sense anyway (see tcp-clients option), because of the nature of
interaction of DoH clients: they tend to keep idle opened connections
for longer periods of time, preventing the TCP and TLS client from
being served. Thus, the need to have a separate, generally larger,
quota for them.
Also, the change makes any option within "http <name> { ... };"
statement optional, making it easier to override only required default
options.
By default, the DoH connections are limited to 300 per listener. I
hope that it is a good initial guesstimate.
2021-05-14 14:18:57 +03:00
|
|
|
result = ns_interface_listenhttp(
|
2023-10-30 17:03:30 +02:00
|
|
|
ifp, elt->proxy, elt->sslctx, elt->http_endpoints,
|
2022-06-22 14:52:58 +03:00
|
|
|
elt->http_endpoints_number, elt->http_max_clients,
|
2021-05-18 12:03:58 +03:00
|
|
|
elt->max_concurrent_streams);
|
2020-12-07 14:19:10 +02:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
goto cleanup_interface;
|
|
|
|
}
|
|
|
|
*ifpret = ifp;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2020-10-01 13:18:47 +02:00
|
|
|
if (elt->sslctx != NULL) {
|
2023-10-30 17:03:30 +02:00
|
|
|
result = ns_interface_listentls(ifp, elt->proxy, elt->sslctx);
|
2020-10-01 13:18:47 +02:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
goto cleanup_interface;
|
|
|
|
}
|
|
|
|
*ifpret = ifp;
|
|
|
|
return result;
|
|
|
|
}
|
2013-03-22 12:27:54 -07:00
|
|
|
|
2023-10-30 17:03:30 +02:00
|
|
|
result = ns_interface_listenudp(ifp, elt->proxy);
|
2014-12-20 00:31:54 -08:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
if ((result == ISC_R_ADDRINUSE) && (addr_in_use != NULL)) {
|
2018-04-17 08:29:14 -07:00
|
|
|
*addr_in_use = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-01-11 21:18:22 +00:00
|
|
|
goto cleanup_interface;
|
2014-12-20 00:31:54 -08:00
|
|
|
}
|
1999-07-24 01:17:28 +00:00
|
|
|
|
2021-09-07 14:40:19 +02:00
|
|
|
if ((mgr->sctx->options & NS_SERVER_NOTCP) == 0) {
|
2023-10-30 17:03:30 +02:00
|
|
|
result = ns_interface_listentcp(ifp, elt->proxy);
|
2002-08-30 02:05:30 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2014-12-18 11:58:50 +05:30
|
|
|
if ((result == ISC_R_ADDRINUSE) &&
|
2022-11-02 19:33:14 +01:00
|
|
|
(addr_in_use != NULL))
|
|
|
|
{
|
2018-04-17 08:29:14 -07:00
|
|
|
*addr_in_use = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-12-18 11:58:50 +05:30
|
|
|
|
2002-08-30 02:05:30 +00:00
|
|
|
/*
|
|
|
|
* XXXRTH We don't currently have a way to easily stop
|
2004-08-10 04:55:39 +00:00
|
|
|
* dispatch service, so we currently return
|
2002-08-30 02:05:30 +00:00
|
|
|
* ISC_R_SUCCESS (the UDP stuff will work even if TCP
|
|
|
|
* creation failed). This will be fixed later.
|
|
|
|
*/
|
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
}
|
2000-01-11 21:18:22 +00:00
|
|
|
}
|
|
|
|
*ifpret = ifp;
|
2011-03-11 06:11:27 +00:00
|
|
|
return result;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-01-11 21:18:22 +00:00
|
|
|
cleanup_interface:
|
2020-10-09 22:06:41 +02:00
|
|
|
ns_interface_shutdown(ifp);
|
2000-01-11 21:18:22 +00:00
|
|
|
return result;
|
|
|
|
}
|
1999-05-20 12:37:35 +00:00
|
|
|
|
2000-09-22 00:13:08 +00:00
|
|
|
void
|
|
|
|
ns_interface_shutdown(ns_interface_t *ifp) {
|
2021-12-14 16:51:02 -08:00
|
|
|
ifp->flags &= ~NS_INTERFACEFLAG_LISTENING;
|
|
|
|
|
2019-11-05 15:34:35 -08:00
|
|
|
if (ifp->udplistensocket != NULL) {
|
2020-03-20 11:55:10 +01:00
|
|
|
isc_nm_stoplistening(ifp->udplistensocket);
|
2020-06-04 14:54:36 -07:00
|
|
|
isc_nmsocket_close(&ifp->udplistensocket);
|
2019-11-05 15:34:35 -08:00
|
|
|
}
|
|
|
|
if (ifp->tcplistensocket != NULL) {
|
2020-03-20 11:55:10 +01:00
|
|
|
isc_nm_stoplistening(ifp->tcplistensocket);
|
2020-06-04 14:54:36 -07:00
|
|
|
isc_nmsocket_close(&ifp->tcplistensocket);
|
2019-11-05 15:34:35 -08:00
|
|
|
}
|
2024-01-09 19:16:26 +02:00
|
|
|
if (ifp->tlslistensocket != NULL) {
|
|
|
|
isc_nm_stoplistening(ifp->tlslistensocket);
|
|
|
|
isc_nmsocket_close(&ifp->tlslistensocket);
|
|
|
|
}
|
2020-12-07 14:19:10 +02:00
|
|
|
if (ifp->http_listensocket != NULL) {
|
|
|
|
isc_nm_stoplistening(ifp->http_listensocket);
|
|
|
|
isc_nmsocket_close(&ifp->http_listensocket);
|
|
|
|
}
|
|
|
|
if (ifp->http_secure_listensocket != NULL) {
|
|
|
|
isc_nm_stoplistening(ifp->http_secure_listensocket);
|
|
|
|
isc_nmsocket_close(&ifp->http_secure_listensocket);
|
|
|
|
}
|
2022-06-22 14:52:58 +03:00
|
|
|
ifp->http_quota = NULL;
|
2000-09-22 00:13:08 +00:00
|
|
|
}
|
|
|
|
|
2000-01-11 21:18:22 +00:00
|
|
|
static void
|
2021-12-15 08:27:28 -08:00
|
|
|
interface_destroy(ns_interface_t **interfacep) {
|
|
|
|
ns_interface_t *ifp = NULL;
|
|
|
|
ns_interfacemgr_t *mgr = NULL;
|
|
|
|
|
|
|
|
REQUIRE(interfacep != NULL);
|
|
|
|
|
|
|
|
ifp = *interfacep;
|
|
|
|
*interfacep = NULL;
|
2021-12-14 16:51:02 -08:00
|
|
|
|
2011-07-28 11:16:04 +00:00
|
|
|
REQUIRE(NS_INTERFACE_VALID(ifp));
|
|
|
|
|
2021-12-14 16:51:02 -08:00
|
|
|
mgr = ifp->mgr;
|
2019-09-27 12:11:16 +02:00
|
|
|
|
2000-09-22 00:13:08 +00:00
|
|
|
ns_interface_shutdown(ifp);
|
|
|
|
|
2021-12-14 16:51:02 -08:00
|
|
|
ifp->magic = 0;
|
|
|
|
isc_mutex_destroy(&ifp->lock);
|
2000-01-11 21:18:22 +00:00
|
|
|
ns_interfacemgr_detach(&ifp->mgr);
|
2019-04-17 15:22:27 +02:00
|
|
|
isc_refcount_destroy(&ifp->ntcpactive);
|
|
|
|
isc_refcount_destroy(&ifp->ntcpaccepting);
|
|
|
|
|
2021-12-14 16:51:02 -08:00
|
|
|
isc_mem_put(mgr->mctx, ifp, sizeof(*ifp));
|
2000-01-11 21:18:22 +00:00
|
|
|
}
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
1999-05-20 12:37:35 +00:00
|
|
|
* Search the interface list for an interface whose address and port
|
|
|
|
* both match those of 'addr'. Return a pointer to it, or NULL if not found.
|
|
|
|
*/
|
|
|
|
static ns_interface_t *
|
|
|
|
find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) {
|
2019-07-04 15:45:06 +02:00
|
|
|
LOCK(&mgr->lock);
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH (mgr->interfaces, ifp, link) {
|
2019-07-04 15:45:06 +02:00
|
|
|
if (isc_sockaddr_equal(&ifp->addr, addr)) {
|
2025-03-20 22:25:56 -07:00
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
return ifp;
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
1999-05-20 12:37:35 +00:00
|
|
|
}
|
2019-07-04 15:45:06 +02:00
|
|
|
UNLOCK(&mgr->lock);
|
2025-03-20 22:25:56 -07:00
|
|
|
|
|
|
|
return NULL;
|
1999-05-20 12:37:35 +00:00
|
|
|
}
|
|
|
|
|
2024-01-09 19:16:26 +02:00
|
|
|
static void
|
|
|
|
log_interface_shutdown(const ns_interface_t *ifp) {
|
|
|
|
char sabuf[ISC_SOCKADDR_FORMATSIZE];
|
|
|
|
isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf));
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_INFO, "no longer listening on %s", sabuf);
|
2024-01-09 19:16:26 +02:00
|
|
|
}
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
1999-05-20 12:37:35 +00:00
|
|
|
* Remove any interfaces whose generation number is not the current one.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
purge_old_interfaces(ns_interfacemgr_t *mgr) {
|
2022-04-27 22:12:01 -07:00
|
|
|
ISC_LIST(ns_interface_t) interfaces;
|
|
|
|
|
|
|
|
ISC_LIST_INIT(interfaces);
|
|
|
|
|
2019-07-04 15:45:06 +02:00
|
|
|
LOCK(&mgr->lock);
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH_SAFE (mgr->interfaces, ifp, link) {
|
2000-01-11 21:18:22 +00:00
|
|
|
INSIST(NS_INTERFACE_VALID(ifp));
|
|
|
|
if (ifp->generation != mgr->generation) {
|
|
|
|
ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link);
|
2022-04-27 22:12:01 -07:00
|
|
|
ISC_LIST_APPEND(interfaces, ifp, link);
|
1999-05-20 12:37:35 +00:00
|
|
|
}
|
|
|
|
}
|
2019-07-04 15:45:06 +02:00
|
|
|
UNLOCK(&mgr->lock);
|
2022-04-27 22:12:01 -07:00
|
|
|
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH_SAFE (interfaces, ifp, link) {
|
2022-04-27 22:12:01 -07:00
|
|
|
if (LISTENING(ifp)) {
|
2024-01-09 19:16:26 +02:00
|
|
|
log_interface_shutdown(ifp);
|
2022-04-27 22:12:01 -07:00
|
|
|
ns_interface_shutdown(ifp);
|
|
|
|
}
|
|
|
|
ISC_LIST_UNLINK(interfaces, ifp, link);
|
|
|
|
interface_destroy(&ifp);
|
|
|
|
}
|
1999-05-20 12:37:35 +00:00
|
|
|
}
|
|
|
|
|
2001-10-22 03:31:24 +00:00
|
|
|
static isc_result_t
|
2022-03-14 12:38:46 +01:00
|
|
|
setup_locals(isc_interface_t *interface, dns_acl_t *localhost,
|
|
|
|
dns_acl_t *localnets) {
|
2002-08-30 02:05:30 +00:00
|
|
|
isc_result_t result;
|
|
|
|
unsigned int prefixlen;
|
2008-07-22 23:47:04 +00:00
|
|
|
isc_netaddr_t *netaddr;
|
|
|
|
|
|
|
|
netaddr = &interface->address;
|
2002-08-30 02:05:30 +00:00
|
|
|
|
2008-07-22 23:47:04 +00:00
|
|
|
/* First add localhost address */
|
2007-09-12 01:09:08 +00:00
|
|
|
prefixlen = (netaddr->family == AF_INET) ? 32 : 128;
|
2022-03-14 12:38:46 +01:00
|
|
|
result = dns_iptable_addprefix(localhost->iptable, netaddr, prefixlen,
|
|
|
|
true);
|
2002-08-30 02:05:30 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
return result;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-08-30 02:05:30 +00:00
|
|
|
|
2008-07-22 23:47:04 +00:00
|
|
|
/* Then add localnets prefix */
|
2002-08-30 02:05:30 +00:00
|
|
|
result = isc_netaddr_masktoprefixlen(&interface->netmask, &prefixlen);
|
|
|
|
|
2009-01-17 11:04:25 +00:00
|
|
|
/* Non contiguous netmasks not allowed by IPv6 arch. */
|
2007-09-12 01:09:08 +00:00
|
|
|
if (result != ISC_R_SUCCESS && netaddr->family == AF_INET6) {
|
2002-08-30 02:05:30 +00:00
|
|
|
return result;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-08-30 02:05:30 +00:00
|
|
|
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_WARNING,
|
2002-08-30 02:05:30 +00:00
|
|
|
"omitting IPv4 interface %s from "
|
2013-09-26 07:40:34 +10:00
|
|
|
"localnets ACL: %s",
|
2002-08-30 02:05:30 +00:00
|
|
|
interface->name, isc_result_totext(result));
|
2008-07-22 23:47:04 +00:00
|
|
|
return ISC_R_SUCCESS;
|
2002-08-30 02:05:30 +00:00
|
|
|
}
|
|
|
|
|
2013-09-26 07:40:34 +10:00
|
|
|
if (prefixlen == 0U) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_WARNING,
|
2013-09-26 07:40:34 +10:00
|
|
|
"omitting %s interface %s from localnets ACL: "
|
|
|
|
"zero prefix length detected",
|
|
|
|
(netaddr->family == AF_INET) ? "IPv4" : "IPv6",
|
|
|
|
interface->name);
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2022-03-14 12:38:46 +01:00
|
|
|
result = dns_iptable_addprefix(localnets->iptable, netaddr, prefixlen,
|
|
|
|
true);
|
2007-09-12 01:09:08 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
return result;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2007-09-12 01:09:08 +00:00
|
|
|
|
2002-08-30 02:05:30 +00:00
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2005-02-10 05:53:43 +00:00
|
|
|
static void
|
|
|
|
setup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface,
|
|
|
|
in_port_t port) {
|
|
|
|
isc_sockaddr_t *addr;
|
|
|
|
|
|
|
|
addr = isc_mem_get(mgr->mctx, sizeof(*addr));
|
|
|
|
isc_sockaddr_fromnetaddr(addr, &interface->address, port);
|
|
|
|
|
2019-07-04 15:45:06 +02:00
|
|
|
LOCK(&mgr->lock);
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH (mgr->listenon, old, link) {
|
2019-07-04 15:45:06 +02:00
|
|
|
if (isc_sockaddr_equal(addr, old)) {
|
2022-03-14 12:38:46 +01:00
|
|
|
/* We found an existing address */
|
|
|
|
isc_mem_put(mgr->mctx, addr, sizeof(*addr));
|
|
|
|
goto unlock;
|
2019-07-04 15:45:06 +02:00
|
|
|
}
|
|
|
|
}
|
2005-02-10 05:53:43 +00:00
|
|
|
|
2022-03-14 12:38:46 +01:00
|
|
|
ISC_LIST_APPEND(mgr->listenon, addr, link);
|
|
|
|
unlock:
|
2019-07-04 15:45:06 +02:00
|
|
|
UNLOCK(&mgr->lock);
|
2005-02-10 05:53:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clearlistenon(ns_interfacemgr_t *mgr) {
|
2025-03-22 15:26:16 -07:00
|
|
|
ISC_LIST(isc_sockaddr_t) listenon = ISC_LIST_INITIALIZER;
|
2022-03-14 12:38:46 +01:00
|
|
|
|
2019-07-04 15:45:06 +02:00
|
|
|
LOCK(&mgr->lock);
|
2022-03-14 12:38:46 +01:00
|
|
|
ISC_LIST_MOVE(listenon, mgr->listenon);
|
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
|
2025-03-22 15:26:16 -07:00
|
|
|
ISC_LIST_FOREACH_SAFE (listenon, old, link) {
|
2022-03-14 12:38:46 +01:00
|
|
|
ISC_LIST_UNLINK(listenon, old, link);
|
2005-02-10 05:53:43 +00:00
|
|
|
isc_mem_put(mgr->mctx, old, sizeof(*old));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-31 13:48:14 +03:00
|
|
|
static void
|
2022-06-22 15:28:57 +03:00
|
|
|
replace_listener_tlsctx(ns_interface_t *ifp, isc_tlsctx_t *newctx) {
|
2022-03-31 13:48:14 +03:00
|
|
|
char sabuf[ISC_SOCKADDR_FORMATSIZE];
|
|
|
|
|
|
|
|
isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf));
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_INFO, "updating TLS context on %s", sabuf);
|
2024-01-09 19:16:26 +02:00
|
|
|
if (ifp->tlslistensocket != NULL) {
|
|
|
|
isc_nmsocket_set_tlsctx(ifp->tlslistensocket, newctx);
|
2022-03-31 13:48:14 +03:00
|
|
|
} else if (ifp->http_secure_listensocket != NULL) {
|
|
|
|
isc_nmsocket_set_tlsctx(ifp->http_secure_listensocket, newctx);
|
|
|
|
}
|
2022-06-22 15:28:57 +03:00
|
|
|
}
|
|
|
|
|
2022-06-22 16:45:28 +03:00
|
|
|
#ifdef HAVE_LIBNGHTTP2
|
2022-06-22 15:28:57 +03:00
|
|
|
static void
|
|
|
|
update_http_settings(ns_interface_t *ifp, ns_listenelt_t *le) {
|
2022-06-22 19:31:18 +03:00
|
|
|
isc_result_t result;
|
2022-06-22 16:45:28 +03:00
|
|
|
isc_nmsocket_t *listener;
|
2022-06-22 19:31:18 +03:00
|
|
|
isc_nm_http_endpoints_t *epset;
|
2022-06-22 16:45:28 +03:00
|
|
|
|
2022-06-22 15:28:57 +03:00
|
|
|
REQUIRE(le->is_http);
|
|
|
|
|
|
|
|
INSIST(ifp->http_quota != NULL);
|
|
|
|
isc_quota_max(ifp->http_quota, le->http_max_clients);
|
2022-06-22 16:45:28 +03:00
|
|
|
|
|
|
|
if (ifp->http_secure_listensocket != NULL) {
|
|
|
|
listener = ifp->http_secure_listensocket;
|
|
|
|
} else {
|
|
|
|
INSIST(ifp->http_listensocket != NULL);
|
|
|
|
listener = ifp->http_listensocket;
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_nmsocket_set_max_streams(listener, le->max_concurrent_streams);
|
2022-06-22 19:31:18 +03:00
|
|
|
|
|
|
|
epset = isc_nm_http_endpoints_new(ifp->mgr->mctx);
|
|
|
|
|
|
|
|
result = load_http_endpoints(epset, ifp, le->http_endpoints,
|
|
|
|
le->http_endpoints_number);
|
|
|
|
|
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
isc_nm_http_set_endpoints(listener, epset);
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_nm_http_endpoints_detach(&epset);
|
2022-06-22 15:28:57 +03:00
|
|
|
}
|
2022-06-22 16:45:28 +03:00
|
|
|
#endif /* HAVE_LIBNGHTTP2 */
|
2022-06-22 15:28:57 +03:00
|
|
|
|
|
|
|
static void
|
|
|
|
update_listener_configuration(ns_interfacemgr_t *mgr, ns_interface_t *ifp,
|
|
|
|
ns_listenelt_t *le) {
|
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
|
|
|
REQUIRE(NS_INTERFACE_VALID(ifp));
|
|
|
|
REQUIRE(le != NULL);
|
|
|
|
|
|
|
|
LOCK(&mgr->lock);
|
|
|
|
/*
|
|
|
|
* We need to update the TLS contexts
|
|
|
|
* inside the TLS/HTTPS listeners during
|
|
|
|
* a reconfiguration because the
|
|
|
|
* certificates could have been changed.
|
|
|
|
*/
|
|
|
|
if (le->sslctx != NULL) {
|
|
|
|
replace_listener_tlsctx(ifp, le->sslctx);
|
|
|
|
}
|
|
|
|
|
2022-06-22 16:45:28 +03:00
|
|
|
#ifdef HAVE_LIBNGHTTP2
|
2022-06-22 15:28:57 +03:00
|
|
|
/*
|
|
|
|
* Let's update HTTP listener settings
|
|
|
|
* on reconfiguration.
|
|
|
|
*/
|
|
|
|
if (le->is_http) {
|
|
|
|
update_http_settings(ifp, le);
|
|
|
|
}
|
2022-06-22 16:45:28 +03:00
|
|
|
#endif /* HAVE_LIBNGHTTP2 */
|
|
|
|
|
2022-03-31 13:48:14 +03:00
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
}
|
|
|
|
|
2024-01-09 19:16:26 +02:00
|
|
|
static bool
|
|
|
|
same_listener_type(ns_interface_t *ifp, ns_listenelt_t *new_le) {
|
|
|
|
bool same_transport_type = false;
|
|
|
|
|
2024-01-12 17:50:12 +02:00
|
|
|
/* See 'interface_setup()' above */
|
|
|
|
if (new_le->is_http) {
|
|
|
|
/* HTTP/DoH */
|
|
|
|
same_transport_type = (new_le->sslctx != NULL &&
|
|
|
|
ifp->http_secure_listensocket != NULL) ||
|
|
|
|
(new_le->sslctx == NULL &&
|
|
|
|
ifp->http_listensocket != NULL);
|
2024-01-09 19:16:26 +02:00
|
|
|
} else if (new_le->sslctx != NULL && ifp->tlslistensocket != NULL) {
|
|
|
|
/* TLS/DoT */
|
|
|
|
same_transport_type = true;
|
|
|
|
} else if (new_le->sslctx == NULL && (ifp->udplistensocket != NULL ||
|
|
|
|
ifp->tcplistensocket != NULL))
|
|
|
|
{
|
|
|
|
/* "plain" DNS/Do53 */
|
|
|
|
same_transport_type = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if transport type of the listener has not changed. That
|
|
|
|
* implies that PROXY type has not been changed as well.
|
|
|
|
*/
|
|
|
|
return same_transport_type && new_le->proxy == ifp->proxy_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
interface_update_or_shutdown(ns_interfacemgr_t *mgr, ns_interface_t *ifp,
|
|
|
|
ns_listenelt_t *le, const bool config) {
|
|
|
|
if (LISTENING(ifp) && config && !same_listener_type(ifp, le)) {
|
|
|
|
/*
|
|
|
|
* DNS listener type has been changed on re-configuration. We
|
|
|
|
* will need to recreate the listener anew.
|
|
|
|
*/
|
|
|
|
log_interface_shutdown(ifp);
|
|
|
|
ns_interface_shutdown(ifp);
|
|
|
|
} else {
|
|
|
|
LOCK(&mgr->lock);
|
|
|
|
ifp->generation = mgr->generation;
|
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
if (LISTENING(ifp)) {
|
|
|
|
if (config) {
|
|
|
|
update_listener_configuration(mgr, ifp, le);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2002-08-30 02:05:30 +00:00
|
|
|
static isc_result_t
|
2021-12-14 09:28:01 +00:00
|
|
|
do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
1999-05-20 12:37:35 +00:00
|
|
|
isc_interfaceiter_t *iter = NULL;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool scan_ipv4 = false;
|
|
|
|
bool scan_ipv6 = false;
|
1999-07-24 01:17:28 +00:00
|
|
|
isc_result_t result;
|
2002-08-16 23:46:11 +00:00
|
|
|
isc_netaddr_t zero_address, zero_address6;
|
2021-12-14 16:51:02 -08:00
|
|
|
ns_interface_t *ifp = NULL;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool dolistenon;
|
2013-03-22 12:27:54 -07:00
|
|
|
char sabuf[ISC_SOCKADDR_FORMATSIZE];
|
2018-04-17 08:29:14 -07:00
|
|
|
bool tried_listening;
|
|
|
|
bool all_addresses_in_use;
|
2022-03-14 12:38:46 +01:00
|
|
|
dns_acl_t *localhost = NULL;
|
|
|
|
dns_acl_t *localnets = NULL;
|
2002-08-16 23:46:11 +00:00
|
|
|
|
|
|
|
if (isc_net_probeipv6() == ISC_R_SUCCESS) {
|
2018-04-17 08:29:14 -07:00
|
|
|
scan_ipv6 = true;
|
2017-09-08 13:39:09 -07:00
|
|
|
} else if ((mgr->sctx->options & NS_SERVER_DISABLE6) == 0) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
2002-08-16 23:46:11 +00:00
|
|
|
verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
|
|
|
|
"no IPv6 interfaces found");
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-08-16 23:46:11 +00:00
|
|
|
|
|
|
|
if (isc_net_probeipv4() == ISC_R_SUCCESS) {
|
2018-04-17 08:29:14 -07:00
|
|
|
scan_ipv4 = true;
|
2017-09-08 13:39:09 -07:00
|
|
|
} else if ((mgr->sctx->options & NS_SERVER_DISABLE4) == 0) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
2002-08-16 23:46:11 +00:00
|
|
|
verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
|
|
|
|
"no IPv4 interfaces found");
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-08-16 23:46:11 +00:00
|
|
|
|
2001-09-10 23:03:09 +00:00
|
|
|
isc_netaddr_any(&zero_address);
|
2002-08-16 23:46:11 +00:00
|
|
|
isc_netaddr_any6(&zero_address6);
|
1999-05-20 12:37:35 +00:00
|
|
|
|
1999-07-24 01:17:28 +00:00
|
|
|
result = isc_interfaceiter_create(mgr->mctx, &iter);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-10-22 03:31:24 +00:00
|
|
|
return result;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-01-20 00:00:00 +00:00
|
|
|
|
2023-10-13 08:17:31 +02:00
|
|
|
dns_acl_create(mgr->mctx, 0, &localhost);
|
|
|
|
dns_acl_create(mgr->mctx, 0, &localnets);
|
2022-03-14 12:38:46 +01:00
|
|
|
|
2021-09-07 14:40:19 +02:00
|
|
|
clearlistenon(mgr);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
tried_listening = false;
|
|
|
|
all_addresses_in_use = true;
|
2000-01-20 00:00:00 +00:00
|
|
|
for (result = isc_interfaceiter_first(iter); result == ISC_R_SUCCESS;
|
|
|
|
result = isc_interfaceiter_next(iter))
|
|
|
|
{
|
1999-05-20 12:37:35 +00:00
|
|
|
isc_interface_t interface;
|
2022-03-14 12:38:46 +01:00
|
|
|
ns_listenlist_t *ll = NULL;
|
2008-07-22 23:47:04 +00:00
|
|
|
unsigned int family;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-07-24 01:17:28 +00:00
|
|
|
result = isc_interfaceiter_current(iter, &interface);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
break;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-01-13 23:32:41 +00:00
|
|
|
|
2002-08-16 23:46:11 +00:00
|
|
|
family = interface.address.family;
|
|
|
|
if (family != AF_INET && family != AF_INET6) {
|
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-03-30 13:49:55 -07:00
|
|
|
if (!scan_ipv4 && family == AF_INET) {
|
2002-08-16 23:46:11 +00:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-03-30 13:49:55 -07:00
|
|
|
if (!scan_ipv6 && family == AF_INET6) {
|
2000-01-20 00:00:00 +00:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-01-20 00:00:00 +00:00
|
|
|
|
2001-09-10 23:03:09 +00:00
|
|
|
/*
|
|
|
|
* Test for the address being nonzero rather than testing
|
|
|
|
* INTERFACE_F_UP, because on some systems the latter
|
|
|
|
* follows the media state and we could end up ignoring
|
|
|
|
* the interface for an entire rescan interval due to
|
|
|
|
* a temporary media glitch at rescan time.
|
|
|
|
*/
|
2002-08-16 23:46:11 +00:00
|
|
|
if (family == AF_INET &&
|
2022-11-02 19:33:14 +01:00
|
|
|
isc_netaddr_equal(&interface.address, &zero_address))
|
|
|
|
{
|
2002-08-16 23:46:11 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (family == AF_INET6 &&
|
2022-11-02 19:33:14 +01:00
|
|
|
isc_netaddr_equal(&interface.address, &zero_address6))
|
|
|
|
{
|
2000-02-07 18:47:43 +00:00
|
|
|
continue;
|
2002-08-16 23:46:11 +00:00
|
|
|
}
|
2000-02-07 18:47:43 +00:00
|
|
|
|
2021-09-07 14:40:19 +02:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
}
|
2017-10-06 15:13:27 -07:00
|
|
|
|
2022-03-14 12:38:46 +01:00
|
|
|
result = setup_locals(&interface, localhost, localnets);
|
2021-09-07 14:40:19 +02:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
goto ignore_interface;
|
2001-10-12 23:05:58 +00:00
|
|
|
}
|
|
|
|
|
2017-10-06 15:13:27 -07:00
|
|
|
listenon:
|
2002-08-16 23:46:11 +00:00
|
|
|
ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6;
|
2018-04-17 08:29:14 -07:00
|
|
|
dolistenon = true;
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH (ll->elts, le, link) {
|
2000-01-13 23:32:41 +00:00
|
|
|
int match;
|
2021-12-09 14:49:51 +00:00
|
|
|
bool addr_in_use = false;
|
2000-02-15 19:53:05 +00:00
|
|
|
isc_sockaddr_t listen_sockaddr;
|
1999-07-24 01:17:28 +00:00
|
|
|
|
2000-02-15 19:53:05 +00:00
|
|
|
isc_sockaddr_fromnetaddr(&listen_sockaddr,
|
2021-12-14 16:51:02 -08:00
|
|
|
&interface.address, le->port);
|
2000-01-13 23:32:41 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* See if the address matches the listen-on statement;
|
2021-12-14 16:51:02 -08:00
|
|
|
* if not, ignore the interface, but store it in
|
|
|
|
* the interface table so we know we've seen it
|
|
|
|
* before.
|
2000-01-13 23:32:41 +00:00
|
|
|
*/
|
2021-12-14 16:51:02 -08:00
|
|
|
(void)dns_acl_match(&interface.address, NULL, le->acl,
|
2021-05-22 18:12:11 +02:00
|
|
|
mgr->aclenv, &match, NULL);
|
2018-04-26 20:57:41 -07:00
|
|
|
if (match <= 0) {
|
2021-12-14 16:51:02 -08:00
|
|
|
ns_interface_t *new = NULL;
|
2023-01-31 13:30:12 -08:00
|
|
|
ns_interface_create(mgr, &listen_sockaddr,
|
|
|
|
interface.name, &new);
|
2000-01-13 23:32:41 +00:00
|
|
|
continue;
|
2018-04-26 20:57:41 -07:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2021-09-07 14:40:19 +02:00
|
|
|
if (dolistenon) {
|
2005-02-10 05:53:43 +00:00
|
|
|
setup_listenon(mgr, &interface, le->port);
|
2018-04-17 08:29:14 -07:00
|
|
|
dolistenon = false;
|
2005-02-10 05:53:43 +00:00
|
|
|
}
|
|
|
|
|
2000-02-15 19:53:05 +00:00
|
|
|
ifp = find_matching_interface(mgr, &listen_sockaddr);
|
2000-01-13 23:32:41 +00:00
|
|
|
if (ifp != NULL) {
|
2024-01-09 19:16:26 +02:00
|
|
|
bool cont = interface_update_or_shutdown(
|
|
|
|
mgr, ifp, le, config);
|
|
|
|
if (cont) {
|
2022-03-31 13:48:14 +03:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2021-12-09 14:49:51 +00:00
|
|
|
}
|
2002-08-30 02:05:30 +00:00
|
|
|
|
2021-12-09 14:49:51 +00:00
|
|
|
isc_sockaddr_format(&listen_sockaddr, sabuf,
|
|
|
|
sizeof(sabuf));
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK,
|
|
|
|
NS_LOGMODULE_INTERFACEMGR, ISC_LOG_INFO,
|
2021-12-09 14:49:51 +00:00
|
|
|
"listening on %s interface "
|
|
|
|
"%s, %s",
|
|
|
|
(family == AF_INET) ? "IPv4" : "IPv6",
|
|
|
|
interface.name, sabuf);
|
|
|
|
|
2021-12-14 16:51:02 -08:00
|
|
|
result = interface_setup(mgr, &listen_sockaddr,
|
|
|
|
interface.name, &ifp, le,
|
|
|
|
&addr_in_use);
|
2021-12-09 14:49:51 +00:00
|
|
|
|
|
|
|
tried_listening = true;
|
|
|
|
if (!addr_in_use) {
|
|
|
|
all_addresses_in_use = false;
|
|
|
|
}
|
2002-08-30 02:05:30 +00:00
|
|
|
|
2021-12-09 14:49:51 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK,
|
|
|
|
NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_ERROR,
|
|
|
|
"creating %s interface "
|
|
|
|
"%s failed; interface ignored",
|
|
|
|
(family == AF_INET) ? "IPv4"
|
|
|
|
: "IPv6",
|
|
|
|
interface.name);
|
1999-05-20 12:37:35 +00:00
|
|
|
}
|
2021-12-09 14:49:51 +00:00
|
|
|
/* Continue. */
|
1999-05-20 12:37:35 +00:00
|
|
|
}
|
2000-02-09 22:59:40 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
ignore_interface:
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_ERROR, "ignoring %s interface %s: %s",
|
2002-08-16 23:46:11 +00:00
|
|
|
(family == AF_INET) ? "IPv4" : "IPv6",
|
2000-02-09 22:59:40 +00:00
|
|
|
interface.name, isc_result_totext(result));
|
|
|
|
continue;
|
1999-05-20 12:37:35 +00:00
|
|
|
}
|
1999-07-24 01:17:28 +00:00
|
|
|
if (result != ISC_R_NOMORE) {
|
2022-10-14 16:07:07 +01:00
|
|
|
UNEXPECTED_ERROR("interface iteration failed: %s",
|
1999-07-24 01:17:28 +00:00
|
|
|
isc_result_totext(result));
|
2008-07-22 23:47:04 +00:00
|
|
|
} else {
|
2014-12-18 11:58:50 +05:30
|
|
|
result = ((tried_listening && all_addresses_in_use)
|
|
|
|
? ISC_R_ADDRINUSE
|
|
|
|
: ISC_R_SUCCESS);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2022-03-14 12:38:46 +01:00
|
|
|
|
|
|
|
dns_aclenv_set(mgr->aclenv, localhost, localnets);
|
|
|
|
|
|
|
|
dns_acl_detach(&localnets);
|
|
|
|
dns_acl_detach(&localhost);
|
|
|
|
|
1999-05-20 12:37:35 +00:00
|
|
|
isc_interfaceiter_destroy(&iter);
|
2001-10-22 03:31:24 +00:00
|
|
|
return result;
|
1999-07-24 01:17:28 +00:00
|
|
|
}
|
|
|
|
|
2022-03-14 12:38:46 +01:00
|
|
|
isc_result_t
|
|
|
|
ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
2014-12-18 11:58:50 +05:30
|
|
|
isc_result_t result;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool purge = true;
|
1999-08-18 00:36:24 +00:00
|
|
|
|
2000-01-11 21:18:22 +00:00
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
2022-07-26 13:03:45 +02:00
|
|
|
REQUIRE(isc_tid() == 0);
|
1999-07-24 01:17:28 +00:00
|
|
|
|
|
|
|
mgr->generation++; /* Increment the generation count. */
|
|
|
|
|
2021-12-14 09:28:01 +00:00
|
|
|
result = do_scan(mgr, verbose, config);
|
2014-12-18 11:58:50 +05:30
|
|
|
if ((result != ISC_R_SUCCESS) && (result != ISC_R_ADDRINUSE)) {
|
2018-04-17 08:29:14 -07:00
|
|
|
purge = false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-05-20 12:37:35 +00:00
|
|
|
|
2000-12-11 19:24:30 +00:00
|
|
|
/*
|
|
|
|
* Now go through the interface list and delete anything that
|
|
|
|
* does not have the current generation number. This is
|
|
|
|
* how we catch interfaces that go away or change their
|
|
|
|
* addresses.
|
1999-05-20 12:37:35 +00:00
|
|
|
*/
|
2001-10-22 03:31:24 +00:00
|
|
|
if (purge) {
|
|
|
|
purge_old_interfaces(mgr);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-05-20 12:37:35 +00:00
|
|
|
|
2001-06-15 23:18:04 +00:00
|
|
|
/*
|
2017-09-08 13:39:09 -07:00
|
|
|
* Warn if we are not listening on any interface.
|
2001-06-15 23:18:04 +00:00
|
|
|
*/
|
2021-09-07 14:40:19 +02:00
|
|
|
if (ISC_LIST_EMPTY(mgr->interfaces)) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR,
|
|
|
|
ISC_LOG_WARNING,
|
1999-10-23 00:02:23 +00:00
|
|
|
"not listening on any interfaces");
|
2002-08-30 02:05:30 +00:00
|
|
|
}
|
2014-12-18 11:58:50 +05:30
|
|
|
|
|
|
|
return result;
|
2002-08-30 02:05:30 +00:00
|
|
|
}
|
|
|
|
|
2000-01-13 23:32:41 +00:00
|
|
|
void
|
2000-06-05 19:10:13 +00:00
|
|
|
ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {
|
2017-09-08 13:39:09 -07:00
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
|
|
|
|
2000-06-05 19:10:13 +00:00
|
|
|
LOCK(&mgr->lock);
|
|
|
|
ns_listenlist_detach(&mgr->listenon4);
|
|
|
|
ns_listenlist_attach(value, &mgr->listenon4);
|
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {
|
2017-09-08 13:39:09 -07:00
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
|
|
|
|
2000-01-13 23:32:41 +00:00
|
|
|
LOCK(&mgr->lock);
|
2000-06-05 19:10:13 +00:00
|
|
|
ns_listenlist_detach(&mgr->listenon6);
|
|
|
|
ns_listenlist_attach(value, &mgr->listenon6);
|
2000-01-13 23:32:41 +00:00
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
}
|
2002-09-10 04:45:54 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr) {
|
2017-09-08 13:39:09 -07:00
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
|
|
|
|
2002-09-10 04:45:54 +00:00
|
|
|
LOCK(&mgr->lock);
|
2022-03-18 09:50:58 +01:00
|
|
|
for (size_t i = 0; i < mgr->ncpus; i++) {
|
2021-05-22 18:12:11 +02:00
|
|
|
ns_client_dumprecursing(f, mgr->clientmgrs[i]);
|
2002-09-10 04:45:54 +00:00
|
|
|
}
|
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
}
|
2005-02-10 05:53:43 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2016-12-30 15:45:08 +11:00
|
|
|
ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr,
|
|
|
|
const isc_sockaddr_t *addr) {
|
2019-07-04 15:45:06 +02:00
|
|
|
bool result = false;
|
2005-02-10 05:53:43 +00:00
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
2019-12-07 23:44:16 +01:00
|
|
|
/*
|
|
|
|
* If the manager is shutting down it's safer to
|
|
|
|
* return true.
|
|
|
|
*/
|
|
|
|
if (atomic_load(&mgr->shuttingdown)) {
|
|
|
|
return true;
|
|
|
|
}
|
2019-07-04 15:45:06 +02:00
|
|
|
LOCK(&mgr->lock);
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH (mgr->listenon, old, link) {
|
2019-07-04 15:45:06 +02:00
|
|
|
if (isc_sockaddr_equal(old, addr)) {
|
|
|
|
result = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
UNLOCK(&mgr->lock);
|
|
|
|
|
|
|
|
return result;
|
2005-02-10 05:53:43 +00:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2020-06-17 12:09:10 -07:00
|
|
|
ns_server_t *
|
|
|
|
ns_interfacemgr_getserver(ns_interfacemgr_t *mgr) {
|
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
|
|
|
|
|
|
|
return mgr->sctx;
|
|
|
|
}
|
|
|
|
|
2021-05-22 18:12:11 +02:00
|
|
|
ns_clientmgr_t *
|
|
|
|
ns_interfacemgr_getclientmgr(ns_interfacemgr_t *mgr) {
|
2022-07-26 13:03:45 +02:00
|
|
|
int tid = isc_tid();
|
2021-05-22 18:12:11 +02:00
|
|
|
|
|
|
|
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
|
|
|
REQUIRE(tid >= 0);
|
2022-03-18 09:50:58 +01:00
|
|
|
REQUIRE((uint32_t)tid < mgr->ncpus);
|
2021-05-22 18:12:11 +02:00
|
|
|
|
|
|
|
return mgr->clientmgrs[tid];
|
|
|
|
}
|
2022-04-08 15:32:10 +03:00
|
|
|
|
|
|
|
bool
|
|
|
|
ns_interfacemgr_dynamic_updates_are_reliable(void) {
|
|
|
|
#if defined(LINUX_NETLINK_AVAILABLE)
|
|
|
|
/*
|
|
|
|
* Let's disable periodic interface rescans on Linux, as there a
|
|
|
|
* reliable kernel-based mechanism for tracking interface state
|
|
|
|
* changes is available.
|
|
|
|
*/
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif /* LINUX_NETLINK_AVAILABLE */
|
|
|
|
}
|