Commit a55d0a90 authored by Andreas Gustafsson's avatar Andreas Gustafsson
Browse files

obey the 'listen-on' configuration option

parent ad61cbe0
......@@ -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,
......
/*
* 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);
}
/*
* 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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment