mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Merge branch '3229-remove-exclusive-mode-from-ns_interfacemgr' into 'main'
Remove exclusive mode from ns_interfacemgr Closes #3229 See merge request isc-projects/bind9!6023
This commit is contained in:
commit
cadd1a0ab3
13 changed files with 220 additions and 178 deletions
4
CHANGES
4
CHANGES
|
|
@ -1,3 +1,7 @@
|
|||
5849. [cleanup] Remove use of exclusive mode in ns_interfacemgr in
|
||||
favor of rwlocked access to localhost and localnets
|
||||
members of dns_aclenv_t structure. [GL #3229]
|
||||
|
||||
5848. [bug] dig could hang in some cases involving multiple servers
|
||||
in a lookup, when a request fails and the next one
|
||||
refuses to start for some reason, for example if it was
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ dns_acl_isnone(dns_acl_t *acl) {
|
|||
|
||||
isc_result_t
|
||||
dns_acl_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner,
|
||||
const dns_acl_t *acl, const dns_aclenv_t *env, int *match,
|
||||
const dns_acl_t *acl, dns_aclenv_t *env, int *match,
|
||||
const dns_aclelement_t **matchelt) {
|
||||
uint16_t bitlen;
|
||||
isc_prefix_t pfx;
|
||||
|
|
@ -251,7 +251,7 @@ dns_acl_match_port_transport(const isc_netaddr_t *reqaddr,
|
|||
const in_port_t local_port,
|
||||
const isc_nmsocket_type_t transport,
|
||||
const bool encrypted, const dns_name_t *reqsigner,
|
||||
const dns_acl_t *acl, const dns_aclenv_t *env,
|
||||
const dns_acl_t *acl, dns_aclenv_t *env,
|
||||
int *match, const dns_aclelement_t **matchelt) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
dns_acl_port_transports_t *next;
|
||||
|
|
@ -420,7 +420,7 @@ dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, bool pos) {
|
|||
|
||||
bool
|
||||
dns_aclelement_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner,
|
||||
const dns_aclelement_t *e, const dns_aclenv_t *env,
|
||||
const dns_aclelement_t *e, dns_aclenv_t *env,
|
||||
const dns_aclelement_t **matchelt) {
|
||||
dns_acl_t *inner = NULL;
|
||||
int indirectmatch;
|
||||
|
|
@ -439,21 +439,33 @@ dns_aclelement_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner,
|
|||
}
|
||||
|
||||
case dns_aclelementtype_nestedacl:
|
||||
inner = e->nestedacl;
|
||||
dns_acl_attach(e->nestedacl, &inner);
|
||||
break;
|
||||
|
||||
case dns_aclelementtype_localhost:
|
||||
if (env == NULL || env->localhost == NULL) {
|
||||
if (env == NULL) {
|
||||
return (false);
|
||||
}
|
||||
inner = env->localhost;
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
if (env->localhost == NULL) {
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
return (false);
|
||||
}
|
||||
dns_acl_attach(env->localhost, &inner);
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
break;
|
||||
|
||||
case dns_aclelementtype_localnets:
|
||||
if (env == NULL || env->localnets == NULL) {
|
||||
if (env == NULL) {
|
||||
return (false);
|
||||
}
|
||||
inner = env->localnets;
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
if (env->localnets == NULL) {
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
return (false);
|
||||
}
|
||||
dns_acl_attach(env->localnets, &inner);
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
break;
|
||||
|
||||
#if defined(HAVE_GEOIP2)
|
||||
|
|
@ -471,6 +483,8 @@ dns_aclelement_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner,
|
|||
matchelt);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
|
||||
dns_acl_detach(&inner);
|
||||
|
||||
/*
|
||||
* Treat negative matches in indirect ACLs as "no match".
|
||||
* That way, a negated indirect ACL will never become a
|
||||
|
|
@ -695,10 +709,11 @@ dns_aclenv_create(isc_mem_t *mctx, dns_aclenv_t **envp) {
|
|||
|
||||
isc_mem_attach(mctx, &env->mctx);
|
||||
isc_refcount_init(&env->references, 1);
|
||||
isc_rwlock_init(&env->rwlock, 0, 0);
|
||||
|
||||
result = dns_acl_create(mctx, 0, &env->localhost);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_nothing;
|
||||
goto cleanup_rwlock;
|
||||
}
|
||||
result = dns_acl_create(mctx, 0, &env->localnets);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -717,15 +732,31 @@ dns_aclenv_create(isc_mem_t *mctx, dns_aclenv_t **envp) {
|
|||
|
||||
cleanup_localhost:
|
||||
dns_acl_detach(&env->localhost);
|
||||
cleanup_nothing:
|
||||
cleanup_rwlock:
|
||||
isc_rwlock_destroy(&env->rwlock);
|
||||
isc_mem_putanddetach(&env->mctx, env, sizeof(*env));
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
dns_aclenv_set(dns_aclenv_t *env, dns_acl_t *localhost, dns_acl_t *localnets) {
|
||||
REQUIRE(VALID_ACLENV(env));
|
||||
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_write);
|
||||
dns_acl_detach(&env->localhost);
|
||||
dns_acl_attach(localhost, &env->localhost);
|
||||
dns_acl_detach(&env->localnets);
|
||||
dns_acl_attach(localnets, &env->localnets);
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_write);
|
||||
}
|
||||
|
||||
void
|
||||
dns_aclenv_copy(dns_aclenv_t *t, dns_aclenv_t *s) {
|
||||
REQUIRE(VALID_ACLENV(s));
|
||||
REQUIRE(VALID_ACLENV(t));
|
||||
|
||||
RWLOCK(&t->rwlock, isc_rwlocktype_write);
|
||||
RWLOCK(&s->rwlock, isc_rwlocktype_read);
|
||||
dns_acl_detach(&t->localhost);
|
||||
dns_acl_attach(s->localhost, &t->localhost);
|
||||
dns_acl_detach(&t->localnets);
|
||||
|
|
@ -735,6 +766,9 @@ dns_aclenv_copy(dns_aclenv_t *t, dns_aclenv_t *s) {
|
|||
#if defined(HAVE_GEOIP2)
|
||||
t->geoip = s->geoip;
|
||||
#endif /* if defined(HAVE_GEOIP2) */
|
||||
|
||||
RWUNLOCK(&s->rwlock, isc_rwlocktype_read);
|
||||
RWUNLOCK(&t->rwlock, isc_rwlocktype_write);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -743,12 +777,10 @@ dns__aclenv_destroy(dns_aclenv_t *aclenv) {
|
|||
|
||||
aclenv->magic = 0;
|
||||
|
||||
if (aclenv->localhost != NULL) {
|
||||
dns_acl_detach(&aclenv->localhost);
|
||||
}
|
||||
if (aclenv->localnets != NULL) {
|
||||
dns_acl_detach(&aclenv->localnets);
|
||||
}
|
||||
isc_refcount_destroy(&aclenv->references);
|
||||
dns_acl_detach(&aclenv->localhost);
|
||||
dns_acl_detach(&aclenv->localnets);
|
||||
isc_rwlock_destroy(&aclenv->rwlock);
|
||||
|
||||
isc_mem_putanddetach(&aclenv->mctx, aclenv, sizeof(*aclenv));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ dns_dns64_destroy(dns_dns64_t **dns64p) {
|
|||
|
||||
isc_result_t
|
||||
dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
|
||||
const dns_name_t *reqsigner, const dns_aclenv_t *env,
|
||||
const dns_name_t *reqsigner, dns_aclenv_t *env,
|
||||
unsigned int flags, unsigned char *a, unsigned char *aaaa) {
|
||||
unsigned int nbytes, i;
|
||||
isc_result_t result;
|
||||
|
|
@ -212,7 +212,7 @@ dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64) {
|
|||
|
||||
bool
|
||||
dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
|
||||
const dns_name_t *reqsigner, const dns_aclenv_t *env,
|
||||
const dns_name_t *reqsigner, dns_aclenv_t *env,
|
||||
unsigned int flags, dns_rdataset_t *rdataset, bool *aaaaok,
|
||||
size_t aaaaoklen) {
|
||||
struct in6_addr in6;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <isc/magic.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/rwlock.h>
|
||||
|
||||
#include <dns/geoip.h>
|
||||
#include <dns/iptable.h>
|
||||
|
|
@ -101,9 +102,12 @@ struct dns_aclenv {
|
|||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
isc_refcount_t references;
|
||||
|
||||
isc_rwlock_t rwlock; /*%< Locks localhost and localnets */
|
||||
dns_acl_t *localhost;
|
||||
dns_acl_t *localnets;
|
||||
bool match_mapped;
|
||||
|
||||
bool match_mapped;
|
||||
#if defined(HAVE_GEOIP2)
|
||||
dns_geoip_databases_t *geoip;
|
||||
#endif /* HAVE_GEOIP2 */
|
||||
|
|
@ -219,6 +223,12 @@ dns_aclenv_copy(dns_aclenv_t *t, dns_aclenv_t *s);
|
|||
*\li both 's' and 't' are valid ACL environments.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_aclenv_set(dns_aclenv_t *env, dns_acl_t *localhost, dns_acl_t *localnets);
|
||||
/*%<
|
||||
* Attach the 'localhost' and 'localnets' arguments to 'env' ACL environment
|
||||
*/
|
||||
|
||||
void
|
||||
dns_aclenv_attach(dns_aclenv_t *source, dns_aclenv_t **targetp);
|
||||
/*%<
|
||||
|
|
@ -240,7 +250,7 @@ dns_aclenv_detach(dns_aclenv_t **aclenvp);
|
|||
|
||||
isc_result_t
|
||||
dns_acl_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner,
|
||||
const dns_acl_t *acl, const dns_aclenv_t *env, int *match,
|
||||
const dns_acl_t *acl, dns_aclenv_t *env, int *match,
|
||||
const dns_aclelement_t **matchelt);
|
||||
/*%<
|
||||
* General, low-level ACL matching. This is expected to
|
||||
|
|
@ -270,7 +280,7 @@ dns_acl_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner,
|
|||
|
||||
bool
|
||||
dns_aclelement_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner,
|
||||
const dns_aclelement_t *e, const dns_aclenv_t *env,
|
||||
const dns_aclelement_t *e, dns_aclenv_t *env,
|
||||
const dns_aclelement_t **matchelt);
|
||||
/*%<
|
||||
* Like dns_acl_match, but matches against the single ACL element 'e'
|
||||
|
|
@ -287,7 +297,7 @@ dns_acl_match_port_transport(const isc_netaddr_t *reqaddr,
|
|||
const in_port_t local_port,
|
||||
const isc_nmsocket_type_t transport,
|
||||
const bool encrypted, const dns_name_t *reqsigner,
|
||||
const dns_acl_t *acl, const dns_aclenv_t *env,
|
||||
const dns_acl_t *acl, dns_aclenv_t *env,
|
||||
int *match, const dns_aclelement_t **matchelt);
|
||||
/*%<
|
||||
* Like dns_acl_match, but able to match the server port and
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ dns_dns64_destroy(dns_dns64_t **dns64p);
|
|||
|
||||
isc_result_t
|
||||
dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
|
||||
const dns_name_t *reqsigner, const dns_aclenv_t *env,
|
||||
const dns_name_t *reqsigner, dns_aclenv_t *env,
|
||||
unsigned int flags, unsigned char *a, unsigned char *aaaa);
|
||||
/*
|
||||
* dns_dns64_aaaafroma() determines whether to perform a DNS64 address
|
||||
|
|
@ -147,7 +147,7 @@ dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64);
|
|||
|
||||
bool
|
||||
dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
|
||||
const dns_name_t *reqsigner, const dns_aclenv_t *env,
|
||||
const dns_name_t *reqsigner, dns_aclenv_t *env,
|
||||
unsigned int flags, dns_rdataset_t *rdataset, bool *aaaaok,
|
||||
size_t aaaaoklen);
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ typedef struct dns_msgblock dns_msgblock_t;
|
|||
|
||||
struct dns_sortlist_arg {
|
||||
dns_aclenv_t *env;
|
||||
const dns_acl_t *acl;
|
||||
dns_acl_t *acl;
|
||||
const dns_aclelement_t *element;
|
||||
};
|
||||
|
||||
|
|
@ -1417,7 +1417,7 @@ dns_message_getrawmessage(dns_message_t *msg);
|
|||
|
||||
void
|
||||
dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
|
||||
dns_aclenv_t *env, const dns_acl_t *acl,
|
||||
dns_aclenv_t *env, dns_acl_t *acl,
|
||||
const dns_aclelement_t *element);
|
||||
/*%<
|
||||
* Define the order in which RR sets get rendered by
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ dns_ssutable_addrule(dns_ssutable_t *table, bool grant,
|
|||
bool
|
||||
dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer,
|
||||
const dns_name_t *name, const isc_netaddr_t *addr,
|
||||
bool tcp, const dns_aclenv_t *env, dns_rdatatype_t type,
|
||||
bool tcp, dns_aclenv_t *env, dns_rdatatype_t type,
|
||||
const dns_name_t *target, const dst_key_t *key,
|
||||
const dns_ssurule_t **rulep);
|
||||
/*%<
|
||||
|
|
|
|||
|
|
@ -642,6 +642,13 @@ msgreset(dns_message_t *msg, bool everything) {
|
|||
dynbuf = next_dynbuf;
|
||||
}
|
||||
|
||||
if (msg->order_arg.env != NULL) {
|
||||
dns_aclenv_detach(&msg->order_arg.env);
|
||||
}
|
||||
if (msg->order_arg.acl != NULL) {
|
||||
dns_acl_detach(&msg->order_arg.acl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set other bits to normal default values.
|
||||
*/
|
||||
|
|
@ -4457,15 +4464,19 @@ dns_message_getrawmessage(dns_message_t *msg) {
|
|||
|
||||
void
|
||||
dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
|
||||
dns_aclenv_t *env, const dns_acl_t *acl,
|
||||
dns_aclenv_t *env, dns_acl_t *acl,
|
||||
const dns_aclelement_t *elem) {
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE((order == NULL) == (env == NULL));
|
||||
REQUIRE(env == NULL || (acl != NULL || elem != NULL));
|
||||
|
||||
msg->order = order;
|
||||
msg->order_arg.env = env;
|
||||
msg->order_arg.acl = acl;
|
||||
if (env != NULL) {
|
||||
dns_aclenv_attach(env, &msg->order_arg.env);
|
||||
}
|
||||
if (acl != NULL) {
|
||||
dns_acl_attach(acl, &msg->order_arg.acl);
|
||||
}
|
||||
msg->order_arg.element = elem;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ stf_from_address(dns_name_t *stfself, const isc_netaddr_t *tcpaddr) {
|
|||
bool
|
||||
dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer,
|
||||
const dns_name_t *name, const isc_netaddr_t *addr,
|
||||
bool tcp, const dns_aclenv_t *env, dns_rdatatype_t type,
|
||||
bool tcp, dns_aclenv_t *env, dns_rdatatype_t type,
|
||||
const dns_name_t *target, const dst_key_t *key,
|
||||
const dns_ssurule_t **rulep) {
|
||||
dns_fixedname_t fixed;
|
||||
|
|
@ -367,8 +367,10 @@ dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer,
|
|||
if (!dns_name_issubdomain(name, rule->name)) {
|
||||
continue;
|
||||
}
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
dns_acl_match(addr, NULL, env->localhost, NULL, &match,
|
||||
NULL);
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
if (match == 0) {
|
||||
if (signer != NULL) {
|
||||
isc_log_write(dns_lctx,
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ typedef enum {
|
|||
|
||||
ns_sortlisttype_t
|
||||
ns_sortlist_setup(dns_acl_t *acl, dns_aclenv_t *env, isc_netaddr_t *clientaddr,
|
||||
const void **argp);
|
||||
void **argp);
|
||||
/*%<
|
||||
* Find the sortlist statement in 'acl' (for ACL environment 'env')
|
||||
* that applies to 'clientaddr', if any.
|
||||
|
|
@ -70,7 +70,7 @@ ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg);
|
|||
void
|
||||
ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, dns_aclenv_t *env,
|
||||
isc_netaddr_t *client_addr,
|
||||
dns_addressorderfunc_t *orderp, const void **argp);
|
||||
dns_addressorderfunc_t *orderp, void **argp);
|
||||
/*%<
|
||||
* Find the sortlist statement in 'acl' that applies to 'clientaddr', if any.
|
||||
* If a sortlist statement applies, return in '*orderp' a pointer to a function
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ struct ns_interfacemgr {
|
|||
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 */
|
||||
|
|
@ -97,16 +97,6 @@ purge_old_interfaces(ns_interfacemgr_t *mgr);
|
|||
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) {
|
||||
|
|
@ -216,7 +206,6 @@ 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;
|
||||
bool done = true;
|
||||
size_t rtmlen;
|
||||
|
||||
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 */
|
||||
|
||||
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);
|
||||
|
||||
if (need_rescan(mgr, rtm, rtmlen) && mgr->sctx->interface_auto) {
|
||||
ns_interfacemgr_scan(mgr, false, false);
|
||||
}
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
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);
|
||||
}
|
||||
isc_nm_read(handle, route_recv, mgr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -333,7 +309,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
@ -348,7 +324,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
|
|||
*/
|
||||
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);
|
||||
|
||||
|
|
@ -389,9 +365,10 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
|
|||
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);
|
||||
|
|
@ -417,9 +394,7 @@ ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) {
|
|||
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));
|
||||
}
|
||||
|
|
@ -434,9 +409,15 @@ ns_interfacemgr_setbacklog(ns_interfacemgr_t *mgr, int backlog) {
|
|||
|
||||
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
|
||||
|
|
@ -810,9 +791,9 @@ purge_old_interfaces(ns_interfacemgr_t *mgr) {
|
|||
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(
|
||||
|
|
@ -826,20 +807,6 @@ purge_old_interfaces(ns_interfacemgr_t *mgr) {
|
|||
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);
|
||||
|
|
@ -847,7 +814,8 @@ listenon_is_ip6_any(ns_listenelt_t *elt) {
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
@ -856,8 +824,8 @@ setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) {
|
|||
|
||||
/* 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);
|
||||
}
|
||||
|
|
@ -887,8 +855,8 @@ setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) {
|
|||
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);
|
||||
}
|
||||
|
|
@ -911,30 +879,34 @@ setup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface,
|
|||
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);
|
||||
while (old != NULL) {
|
||||
ISC_LIST_UNLINK(mgr->listenon, old, link);
|
||||
isc_mem_put(mgr->mctx, old, sizeof(*old));
|
||||
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(listenon, old, link);
|
||||
isc_mem_put(mgr->mctx, old, sizeof(*old));
|
||||
old = ISC_LIST_HEAD(listenon);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
|
@ -946,7 +918,7 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||
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;
|
||||
|
|
@ -954,6 +926,8 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||
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;
|
||||
|
|
@ -1067,14 +1041,15 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||
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;
|
||||
|
|
@ -1083,7 +1058,7 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||
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);
|
||||
|
|
@ -1128,7 +1103,7 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||
goto listenon;
|
||||
}
|
||||
|
||||
result = setup_locals(mgr, &interface);
|
||||
result = setup_locals(&interface, localhost, localnets);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto ignore_interface;
|
||||
}
|
||||
|
|
@ -1276,17 +1251,27 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||
? 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. */
|
||||
|
||||
|
|
@ -1323,30 +1308,6 @@ ns_interfacemgr_islistening(ns_interfacemgr_t *mgr) {
|
|||
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));
|
||||
|
|
|
|||
|
|
@ -11584,20 +11584,25 @@ query_setup_sortlist(query_ctx_t *qctx) {
|
|||
isc_netaddr_t netaddr;
|
||||
ns_client_t *client = qctx->client;
|
||||
dns_aclenv_t *env = client->manager->aclenv;
|
||||
const void *order_arg = NULL;
|
||||
dns_acl_t *acl = NULL;
|
||||
dns_aclelement_t *elt = NULL;
|
||||
void *order_arg = NULL;
|
||||
|
||||
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
|
||||
switch (ns_sortlist_setup(client->view->sortlist, env, &netaddr,
|
||||
&order_arg)) {
|
||||
case NS_SORTLISTTYPE_1ELEMENT:
|
||||
elt = order_arg;
|
||||
dns_message_setsortorder(client->message,
|
||||
query_sortlist_order_1element, env,
|
||||
NULL, order_arg);
|
||||
NULL, elt);
|
||||
break;
|
||||
case NS_SORTLISTTYPE_2ELEMENT:
|
||||
acl = order_arg;
|
||||
dns_message_setsortorder(client->message,
|
||||
query_sortlist_order_2element, env,
|
||||
order_arg, NULL);
|
||||
acl, NULL);
|
||||
dns_acl_detach(&acl);
|
||||
break;
|
||||
case NS_SORTLISTTYPE_NONE:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -25,14 +25,12 @@
|
|||
|
||||
ns_sortlisttype_t
|
||||
ns_sortlist_setup(dns_acl_t *acl, dns_aclenv_t *env, isc_netaddr_t *clientaddr,
|
||||
const void **argp) {
|
||||
unsigned int i;
|
||||
|
||||
void **argp) {
|
||||
if (acl == NULL) {
|
||||
goto dont_sort;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl->length; i++) {
|
||||
for (size_t i = 0; i < acl->length; i++) {
|
||||
/*
|
||||
* 'e' refers to the current 'top level statement'
|
||||
* in the sortlist (see ARM).
|
||||
|
|
@ -40,7 +38,7 @@ ns_sortlist_setup(dns_acl_t *acl, dns_aclenv_t *env, isc_netaddr_t *clientaddr,
|
|||
dns_aclelement_t *e = &acl->elements[i];
|
||||
dns_aclelement_t *try_elt;
|
||||
dns_aclelement_t *order_elt = NULL;
|
||||
const dns_aclelement_t *matched_elt = NULL;
|
||||
dns_aclelement_t *matched_elt = NULL;
|
||||
|
||||
if (e->type == dns_aclelementtype_nestedacl) {
|
||||
dns_acl_t *inner = e->nestedacl;
|
||||
|
|
@ -65,43 +63,62 @@ ns_sortlist_setup(dns_acl_t *acl, dns_aclenv_t *env, isc_netaddr_t *clientaddr,
|
|||
try_elt = e;
|
||||
}
|
||||
|
||||
if (dns_aclelement_match(clientaddr, NULL, try_elt, env,
|
||||
&matched_elt)) {
|
||||
if (order_elt != NULL) {
|
||||
if (order_elt->type ==
|
||||
dns_aclelementtype_nestedacl) {
|
||||
*argp = order_elt->nestedacl;
|
||||
return (NS_SORTLISTTYPE_2ELEMENT);
|
||||
} else if (order_elt->type ==
|
||||
dns_aclelementtype_localhost &&
|
||||
env->localhost != NULL)
|
||||
{
|
||||
*argp = env->localhost;
|
||||
return (NS_SORTLISTTYPE_2ELEMENT);
|
||||
} else if (order_elt->type ==
|
||||
dns_aclelementtype_localnets &&
|
||||
env->localnets != NULL)
|
||||
{
|
||||
*argp = env->localnets;
|
||||
return (NS_SORTLISTTYPE_2ELEMENT);
|
||||
} else {
|
||||
/*
|
||||
* BIND 8 allows a bare IP prefix as
|
||||
* the 2nd element of a 2-element
|
||||
* sortlist statement.
|
||||
*/
|
||||
*argp = order_elt;
|
||||
return (NS_SORTLISTTYPE_1ELEMENT);
|
||||
}
|
||||
} else {
|
||||
INSIST(matched_elt != NULL);
|
||||
*argp = matched_elt;
|
||||
return (NS_SORTLISTTYPE_1ELEMENT);
|
||||
if (!dns_aclelement_match(
|
||||
clientaddr, NULL, try_elt, env,
|
||||
(const dns_aclelement_t **)&matched_elt))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (order_elt == NULL) {
|
||||
INSIST(matched_elt != NULL);
|
||||
*argp = matched_elt;
|
||||
return (NS_SORTLISTTYPE_1ELEMENT);
|
||||
}
|
||||
|
||||
if (order_elt->type == dns_aclelementtype_nestedacl) {
|
||||
dns_acl_t *inner = NULL;
|
||||
dns_acl_attach(order_elt->nestedacl, &inner);
|
||||
*argp = inner;
|
||||
return (NS_SORTLISTTYPE_2ELEMENT);
|
||||
}
|
||||
|
||||
if (order_elt->type == dns_aclelementtype_localhost) {
|
||||
dns_acl_t *inner = NULL;
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
if (env->localhost != NULL) {
|
||||
dns_acl_attach(env->localhost, &inner);
|
||||
}
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
|
||||
if (inner != NULL) {
|
||||
*argp = inner;
|
||||
return (NS_SORTLISTTYPE_2ELEMENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (order_elt->type == dns_aclelementtype_localnets) {
|
||||
dns_acl_t *inner = NULL;
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
if (env->localnets != NULL) {
|
||||
dns_acl_attach(env->localnets, &inner);
|
||||
}
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
if (inner != NULL) {
|
||||
*argp = inner;
|
||||
return (NS_SORTLISTTYPE_2ELEMENT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* BIND 8 allows a bare IP prefix as
|
||||
* the 2nd element of a 2-element
|
||||
* sortlist statement.
|
||||
*/
|
||||
*argp = order_elt;
|
||||
return (NS_SORTLISTTYPE_1ELEMENT);
|
||||
}
|
||||
|
||||
/* No match; don't sort. */
|
||||
dont_sort:
|
||||
*argp = NULL;
|
||||
return (NS_SORTLISTTYPE_NONE);
|
||||
|
|
@ -110,7 +127,7 @@ dont_sort:
|
|||
int
|
||||
ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg) {
|
||||
const dns_sortlist_arg_t *sla = (const dns_sortlist_arg_t *)arg;
|
||||
const dns_aclenv_t *env = sla->env;
|
||||
dns_aclenv_t *env = sla->env;
|
||||
const dns_acl_t *sortacl = sla->acl;
|
||||
int match;
|
||||
|
||||
|
|
@ -127,7 +144,7 @@ ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg) {
|
|||
int
|
||||
ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg) {
|
||||
const dns_sortlist_arg_t *sla = (const dns_sortlist_arg_t *)arg;
|
||||
const dns_aclenv_t *env = sla->env;
|
||||
dns_aclenv_t *env = sla->env;
|
||||
const dns_aclelement_t *element = sla->element;
|
||||
|
||||
if (dns_aclelement_match(addr, NULL, element, env, NULL)) {
|
||||
|
|
@ -140,7 +157,7 @@ ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg) {
|
|||
void
|
||||
ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, dns_aclenv_t *env,
|
||||
isc_netaddr_t *client_addr,
|
||||
dns_addressorderfunc_t *orderp, const void **argp) {
|
||||
dns_addressorderfunc_t *orderp, void **argp) {
|
||||
ns_sortlisttype_t sortlisttype;
|
||||
|
||||
sortlisttype = ns_sortlist_setup(sortlist_acl, env, client_addr, argp);
|
||||
|
|
|
|||
Loading…
Reference in a new issue