mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 22:15:20 +00:00
obey the 'listen-on' configuration option
This commit is contained in:
@@ -37,12 +37,14 @@ SUBDIRS = unix
|
||||
|
||||
TARGETS = named
|
||||
|
||||
OBJS = client.@O@ interfacemgr.@O@ log.@O@ main.@O@ notify.@O@ \
|
||||
OBJS = client.@O@ interfacemgr.@O@ listenlist.@O@ \
|
||||
log.@O@ main.@O@ notify.@O@ \
|
||||
query.@O@ rootns.@O@ server.@O@ update.@O@ xfrout.@O@
|
||||
|
||||
UOBJS = unix/os.@O@
|
||||
|
||||
SRCS = client.c interfacemgr.c log.c main.c notify.c \
|
||||
SRCS = client.c interfacemgr.c listenlist.c \
|
||||
log.c main.c notify.c \
|
||||
query.c rootns.c server.c update.c xfrout.c
|
||||
|
||||
@BIND9_MAKE_RULES@
|
||||
|
@@ -54,6 +54,7 @@
|
||||
|
||||
#include <dns/result.h>
|
||||
|
||||
#include <named/listenlist.h>
|
||||
#include <named/types.h>
|
||||
|
||||
/***
|
||||
@@ -113,6 +114,13 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr);
|
||||
* in named.conf.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_interfacemgr_setlistenon(ns_interfacemgr_t *mgr,
|
||||
ns_listenlist_t *value);
|
||||
/*
|
||||
* Set the "listen-on" list of 'mgr' to 'value'.
|
||||
* The previous listen-on list is freed.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_interface_attach(ns_interface_t *source,
|
||||
|
91
bin/named/include/named/listenlist.h
Normal file
91
bin/named/include/named/listenlist.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2000 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef NS_LISTENLIST_H
|
||||
#define NS_LISTENLIST_H 1
|
||||
|
||||
/*****
|
||||
***** Module Info
|
||||
*****/
|
||||
|
||||
/*
|
||||
* "Listen lists", as in the "listen-on" configuration statement.
|
||||
*/
|
||||
|
||||
/***
|
||||
*** Imports
|
||||
***/
|
||||
|
||||
#include <dns/aclconf.h>
|
||||
#include <dns/confacl.h>
|
||||
#include <dns/confctx.h>
|
||||
#include <dns/confip.h>
|
||||
|
||||
/***
|
||||
*** Types
|
||||
***/
|
||||
|
||||
typedef struct ns_listenelt ns_listenelt_t;
|
||||
typedef struct ns_listenlist ns_listenlist_t;
|
||||
|
||||
struct ns_listenelt {
|
||||
isc_mem_t * mctx;
|
||||
in_port_t port;
|
||||
dns_acl_t * acl;
|
||||
ISC_LINK(ns_listenelt_t) link;
|
||||
};
|
||||
|
||||
struct ns_listenlist {
|
||||
isc_mem_t * mctx;
|
||||
int refcount;
|
||||
ISC_LIST(ns_listenelt_t) elts;
|
||||
};
|
||||
|
||||
/***
|
||||
*** Functions
|
||||
***/
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
isc_result_t
|
||||
ns_listenlist_fromconfig(dns_c_lstnlist_t *clist, dns_c_ctx_t *cctx,
|
||||
dns_aclconfctx_t *actx,
|
||||
isc_mem_t *mctx, ns_listenlist_t **target);
|
||||
/*
|
||||
* Create a listen list from the corresponding configuration
|
||||
* data structure.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_listenlist_default(isc_mem_t *mctx, in_port_t port,
|
||||
ns_listenlist_t **target);
|
||||
/*
|
||||
* Create a listen-on list with default contents, matching
|
||||
* all addresses with port 'port'.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target);
|
||||
|
||||
void
|
||||
ns_listenlist_detach(ns_listenlist_t **listp);
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* NS_LISTENLIST_H */
|
||||
|
||||
|
@@ -37,6 +37,7 @@
|
||||
|
||||
#include <named/client.h>
|
||||
#include <named/globals.h>
|
||||
#include <named/listenlist.h>
|
||||
#include <named/log.h>
|
||||
#include <named/interfacemgr.h>
|
||||
|
||||
@@ -52,6 +53,7 @@ struct ns_interfacemgr {
|
||||
isc_socketmgr_t * socketmgr; /* Socket manager. */
|
||||
ns_clientmgr_t * clientmgr; /* Client manager. */
|
||||
unsigned int generation; /* Current generation no. */
|
||||
ns_listenlist_t * listenon;
|
||||
ISC_LIST(ns_interface_t) interfaces; /* List of interfaces. */
|
||||
};
|
||||
|
||||
@@ -74,28 +76,37 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
||||
return (DNS_R_NOMEMORY);
|
||||
|
||||
result = isc_mutex_init(&mgr->lock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_mem_put(mctx, mgr, sizeof(*mgr));
|
||||
return (result);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
mgr->mctx = mctx;
|
||||
mgr->taskmgr = taskmgr;
|
||||
mgr->socketmgr = socketmgr;
|
||||
mgr->clientmgr = clientmgr;
|
||||
mgr->generation = 1;
|
||||
mgr->listenon = NULL;
|
||||
ISC_LIST_INIT(mgr->interfaces);
|
||||
|
||||
result = ns_listenlist_default(mctx, ns_g_port,
|
||||
&mgr->listenon);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
mgr->references = 1;
|
||||
mgr->magic = IFMGR_MAGIC;
|
||||
*mgrp = mgr;
|
||||
return (DNS_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
isc_mem_put(mctx, mgr, sizeof(*mgr));
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
ns_interfacemgr_destroy(ns_interfacemgr_t *mgr)
|
||||
{
|
||||
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
||||
ns_listenlist_detach(&mgr->listenon);
|
||||
isc_mutex_destroy(&mgr->lock);
|
||||
mgr->magic = 0;
|
||||
isc_mem_put(mgr->mctx, mgr, sizeof *mgr);
|
||||
@@ -447,8 +458,8 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
ns_interface_t *ifp;
|
||||
isc_interface_t interface;
|
||||
isc_sockaddr_t listen_addr;
|
||||
|
||||
ns_listenelt_t *le;
|
||||
|
||||
/*
|
||||
* XXX insert code to match against named.conf
|
||||
* "listen-on" statements here. Also build list of
|
||||
@@ -458,36 +469,60 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
||||
result = isc_interfaceiter_current(iter, &interface);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
break;
|
||||
|
||||
isc_sockaddr_fromin(&listen_addr,
|
||||
&interface.address.type.in,
|
||||
ns_g_port);
|
||||
|
||||
ifp = find_matching_interface(mgr, &listen_addr);
|
||||
if (ifp != NULL) {
|
||||
ifp->generation = mgr->generation;
|
||||
} else {
|
||||
for (le = ISC_LIST_HEAD(mgr->listenon->elts);
|
||||
le != NULL;
|
||||
le = ISC_LIST_NEXT(le, link))
|
||||
{
|
||||
int match;
|
||||
isc_sockaddr_t listen_addr;
|
||||
char buf[128];
|
||||
const char *addrstr;
|
||||
|
||||
/*
|
||||
* Construct a socket address for this IP/port
|
||||
* combination.
|
||||
*/
|
||||
isc_sockaddr_fromin(&listen_addr,
|
||||
&interface.address.type.in,
|
||||
le->port);
|
||||
|
||||
/*
|
||||
* Construct a human-readable version of same.
|
||||
*/
|
||||
addrstr = inet_ntop(listen_addr.type.sin.sin_family,
|
||||
&listen_addr.type.sin.sin_addr,
|
||||
buf, sizeof(buf));
|
||||
if (addrstr == NULL)
|
||||
addrstr = "(bad address)";
|
||||
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_NETWORK,
|
||||
NS_LOGMODULE_INTERFACEMGR,
|
||||
ISC_LOG_INFO,
|
||||
"listening on IPv4 interface %s, %s port %u",
|
||||
interface.name, addrstr,
|
||||
ntohs(listen_addr.type.sin.sin_port));
|
||||
|
||||
result = ns_interface_setup(mgr, &listen_addr, &ifp);
|
||||
if (result != DNS_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"creating IPv4 interface %s "
|
||||
"failed; interface ignored",
|
||||
interface.name);
|
||||
|
||||
/*
|
||||
* See if the address matches the listen-on statement;
|
||||
* if not, ignore the interface.
|
||||
*/
|
||||
result = dns_acl_match(&listen_addr, NULL,
|
||||
le->acl, &match, NULL);
|
||||
if (match <= 0)
|
||||
continue;
|
||||
|
||||
ifp = find_matching_interface(mgr, &listen_addr);
|
||||
if (ifp != NULL) {
|
||||
ifp->generation = mgr->generation;
|
||||
} else {
|
||||
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_NETWORK,
|
||||
NS_LOGMODULE_INTERFACEMGR,
|
||||
ISC_LOG_INFO,
|
||||
"listening on IPv4 interface %s, %s port %u",
|
||||
interface.name, addrstr,
|
||||
ntohs(listen_addr.type.sin.sin_port));
|
||||
|
||||
result = ns_interface_setup(mgr, &listen_addr, &ifp);
|
||||
if (result != DNS_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"creating IPv4 interface %s "
|
||||
"failed; interface ignored",
|
||||
interface.name);
|
||||
}
|
||||
/* Continue. */
|
||||
}
|
||||
|
||||
@@ -566,3 +601,13 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr) {
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ns_interfacemgr_setlistenon(ns_interfacemgr_t *mgr,
|
||||
ns_listenlist_t *value)
|
||||
{
|
||||
LOCK(&mgr->lock);
|
||||
ns_listenlist_detach(&mgr->listenon);
|
||||
ns_listenlist_attach(value, &mgr->listenon);
|
||||
UNLOCK(&mgr->lock);
|
||||
}
|
||||
|
185
bin/named/listenlist.c
Normal file
185
bin/named/listenlist.c
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (C) 2000 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/result.h>
|
||||
|
||||
#include <named/listenlist.h>
|
||||
|
||||
static void destroy(ns_listenlist_t *list);
|
||||
|
||||
static isc_result_t
|
||||
ns_listenelt_create(isc_mem_t *mctx, in_port_t port,
|
||||
dns_acl_t *acl, ns_listenelt_t **target)
|
||||
{
|
||||
ns_listenelt_t *elt = NULL;
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
elt = isc_mem_get(mctx, sizeof(*elt));
|
||||
if (elt == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
elt->mctx = mctx;
|
||||
ISC_LINK_INIT(elt, link);
|
||||
elt->port = port;
|
||||
elt->acl = acl;
|
||||
*target = elt;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
ns_listenelt_destroy(ns_listenelt_t *elt) {
|
||||
if (elt->acl != NULL)
|
||||
dns_acl_detach(&elt->acl);
|
||||
isc_mem_put(elt->mctx, elt, sizeof(*elt));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
ns_listenelt_fromconfig(dns_c_lstnon_t *celt, dns_c_ctx_t *cctx,
|
||||
dns_aclconfctx_t *actx,
|
||||
isc_mem_t *mctx, ns_listenelt_t **target)
|
||||
{
|
||||
isc_result_t result;
|
||||
ns_listenelt_t *delt = NULL;
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
result = ns_listenelt_create(mctx, celt->port, NULL, &delt);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
result = dns_acl_fromconfig(celt->iml, cctx, actx, mctx, &delt->acl);
|
||||
if (result != DNS_R_SUCCESS) {
|
||||
ns_listenelt_destroy(delt);
|
||||
return (result);
|
||||
}
|
||||
*target = delt;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target) {
|
||||
ns_listenlist_t *list = NULL;
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
list = isc_mem_get(mctx, sizeof(*list));
|
||||
if (list == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
list->mctx = mctx;
|
||||
list->refcount = 1;
|
||||
ISC_LIST_INIT(list->elts);
|
||||
*target = list;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_listenlist_fromconfig(dns_c_lstnlist_t *clist, dns_c_ctx_t *cctx,
|
||||
dns_aclconfctx_t *actx,
|
||||
isc_mem_t *mctx, ns_listenlist_t **target)
|
||||
{
|
||||
dns_c_lstnon_t *ce;
|
||||
isc_result_t result;
|
||||
ns_listenlist_t *dlist = NULL;
|
||||
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
|
||||
result = ns_listenlist_create(mctx, &dlist);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
for (ce = ISC_LIST_HEAD(clist->elements);
|
||||
ce != NULL;
|
||||
ce = ISC_LIST_NEXT(ce, next))
|
||||
{
|
||||
ns_listenelt_t *delt = NULL;
|
||||
result = ns_listenelt_fromconfig(ce, cctx, actx, mctx, &delt);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
goto cleanup;
|
||||
ISC_LIST_APPEND(dlist->elts, delt, link);
|
||||
}
|
||||
*target = dlist;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
destroy(dlist);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy(ns_listenlist_t *list) {
|
||||
ns_listenelt_t *elt, *next;
|
||||
for (elt = ISC_LIST_HEAD(list->elts);
|
||||
elt != NULL;
|
||||
elt = next)
|
||||
{
|
||||
next = ISC_LIST_NEXT(elt, link);
|
||||
ns_listenelt_destroy(elt);
|
||||
}
|
||||
isc_mem_put(list->mctx, list, sizeof(*list));
|
||||
}
|
||||
|
||||
void
|
||||
ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target)
|
||||
{
|
||||
INSIST(source->refcount > 0);
|
||||
source->refcount++;
|
||||
*target = source;
|
||||
}
|
||||
|
||||
void
|
||||
ns_listenlist_detach(ns_listenlist_t **listp)
|
||||
{
|
||||
ns_listenlist_t *list = *listp;
|
||||
INSIST(list->refcount > 0);
|
||||
list->refcount--;
|
||||
if (list->refcount == 0)
|
||||
destroy(list);
|
||||
*listp = NULL;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_listenlist_default(isc_mem_t *mctx, in_port_t port,
|
||||
ns_listenlist_t **target)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_acl_t *acl = NULL;
|
||||
ns_listenelt_t *elt = NULL;
|
||||
ns_listenlist_t *list = NULL;
|
||||
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
result = dns_acl_any(mctx, &acl);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
result = ns_listenelt_create(mctx, port, acl, &elt);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_acl;
|
||||
|
||||
result = ns_listenlist_create(mctx, &list);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_listenelt;
|
||||
|
||||
ISC_LIST_APPEND(list->elts, elt, link);
|
||||
|
||||
*target = list;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup_listenelt:
|
||||
ns_listenelt_destroy(elt);
|
||||
cleanup_acl:
|
||||
dns_acl_detach(&acl);
|
||||
cleanup:
|
||||
return (result);
|
||||
}
|
@@ -59,12 +59,13 @@
|
||||
#include <dns/tsig.h>
|
||||
#include <dns/tkey.h>
|
||||
|
||||
#include <named/types.h>
|
||||
#include <named/globals.h>
|
||||
#include <named/interfacemgr.h>
|
||||
#include <named/listenlist.h>
|
||||
#include <named/log.h>
|
||||
#include <named/rootns.h>
|
||||
#include <named/server.h>
|
||||
#include <named/interfacemgr.h>
|
||||
#include <named/types.h>
|
||||
|
||||
typedef struct {
|
||||
isc_mem_t * mctx;
|
||||
@@ -459,6 +460,31 @@ load_configuration(const char *filename, ns_server_t *server) {
|
||||
configure_server_acl(configctx, &aclconfctx, ns_g_mctx,
|
||||
dns_c_ctx_gettransferacl, &server->transferacl);
|
||||
|
||||
|
||||
/*
|
||||
* Configure the interface manager according to the "listen-on"
|
||||
* statement.
|
||||
*/
|
||||
{
|
||||
dns_c_lstnlist_t *clistenon = NULL;
|
||||
ns_listenlist_t *listenon = NULL;
|
||||
|
||||
(void) dns_c_ctx_getlistenlist(configctx, &clistenon);
|
||||
if (clistenon != NULL) {
|
||||
result = ns_listenlist_fromconfig(clistenon,
|
||||
configctx,
|
||||
&aclconfctx,
|
||||
ns_g_mctx, &listenon);
|
||||
} else {
|
||||
/* Not specified, use default. */
|
||||
result = ns_listenlist_default(ns_g_mctx, ns_g_port,
|
||||
&listenon);
|
||||
}
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
ns_interfacemgr_setlistenon(server->interfacemgr, listenon);
|
||||
ns_listenlist_detach(&listenon);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we haven't created any views, create a default view for class
|
||||
* IN. (We're a caching-only server.)
|
||||
|
@@ -12,6 +12,7 @@
|
||||
./bin/named/include/named/client.h C 1999,2000
|
||||
./bin/named/include/named/globals.h C 1999,2000
|
||||
./bin/named/include/named/interfacemgr.h C 1999,2000
|
||||
./bin/named/include/named/listenlist.h C 2000
|
||||
./bin/named/include/named/log.h C 1999,2000
|
||||
./bin/named/include/named/main.h C 1999,2000
|
||||
./bin/named/include/named/notify.h C 1999,2000
|
||||
@@ -23,6 +24,7 @@
|
||||
./bin/named/include/named/xfrout.h C 1999,2000
|
||||
./bin/named/interfacemgr.c C 1999,2000
|
||||
./bin/named/log.c C 1999,2000
|
||||
./bin/named/listenlist.c C 2000
|
||||
./bin/named/main.c C 1999,2000
|
||||
./bin/named/named.conf.test X 1999,2000
|
||||
./bin/named/notify.c C 1999,2000
|
||||
|
Reference in New Issue
Block a user