mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 11:19:59 -04:00
Wired up the new 'port' option. Also, the interface manager now has
both a 'listen-on' and a 'listen-on-v6' ACL. We are still waiting for the 'listen-on-v6' config file option to set the latter explicitly, but at least the default value now tracks the 'port' option and the '-p' command line option.
This commit is contained in:
parent
bffe4c151c
commit
f1f2f8bd47
7 changed files with 165 additions and 21 deletions
|
|
@ -49,7 +49,7 @@ EXTERN isc_timermgr_t * ns_g_timermgr INIT(NULL);
|
|||
EXTERN isc_socketmgr_t * ns_g_socketmgr INIT(NULL);
|
||||
EXTERN omapi_object_t * ns_g_omapimgr INIT(NULL);
|
||||
EXTERN const char * ns_g_version INIT(VERSION);
|
||||
EXTERN in_port_t ns_g_port INIT(53);
|
||||
EXTERN in_port_t ns_g_port INIT(0);
|
||||
|
||||
EXTERN ns_server_t * ns_g_server INIT(NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,13 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
|||
isc_socketmgr_t *socketmgr,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
ns_clientmgr_t *clientmgr, ns_interfacemgr_t **mgrp);
|
||||
/*
|
||||
* Create a new interface manager.
|
||||
*
|
||||
* Initially, the new manager will not listen on any interfaces.
|
||||
* Call ns_interfacemgr_setlistenon() and/or ns_interfacemgr_setlistenon6()
|
||||
* to set nonempty listen-on lists.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target);
|
||||
|
|
@ -113,10 +120,17 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr);
|
|||
*/
|
||||
|
||||
void
|
||||
ns_interfacemgr_setlistenon(ns_interfacemgr_t *mgr, ns_listenlist_t *value);
|
||||
ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value);
|
||||
/*
|
||||
* Set the "listen-on" list of 'mgr' to 'value'.
|
||||
* The previous listen-on list is freed.
|
||||
* Set the IPv4 "listen-on" list of 'mgr' to 'value'.
|
||||
* The previous IPv4 listen-on list is freed.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value);
|
||||
/*
|
||||
* Set the IPv6 "listen-on" list of 'mgr' to 'value'.
|
||||
* The previous IPv6 listen-on list is freed.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
|
|
|
|||
|
|
@ -60,18 +60,33 @@ struct ns_listenlist {
|
|||
isc_result_t
|
||||
ns_listenelt_create(isc_mem_t *mctx, in_port_t port,
|
||||
dns_acl_t *acl, ns_listenelt_t **target);
|
||||
/*
|
||||
* Create a listen-on list element.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_listenelt_destroy(ns_listenelt_t *elt);
|
||||
/*
|
||||
* Destroy a listen-on list element.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target);
|
||||
/*
|
||||
* Create a new, empty listen-on list.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target);
|
||||
/*
|
||||
* Attach '*target' to '*source'.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_listenlist_detach(ns_listenlist_t **listp);
|
||||
/*
|
||||
* Detach 'listp'.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_listenlist_default(isc_mem_t *mctx, in_port_t port,
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ struct ns_interfacemgr {
|
|||
dns_dispatchmgr_t * dispatchmgr;
|
||||
ns_clientmgr_t * clientmgr; /* Client manager. */
|
||||
unsigned int generation; /* Current generation no. */
|
||||
ns_listenlist_t * listenon;
|
||||
ns_listenlist_t * listenon4;
|
||||
ns_listenlist_t * listenon6;
|
||||
dns_aclenv_t aclenv; /* Localhost/localnets ACLs */
|
||||
ISC_LIST(ns_interface_t) interfaces; /* List of interfaces. */
|
||||
};
|
||||
|
|
@ -80,13 +81,17 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
|||
mgr->dispatchmgr = dispatchmgr;
|
||||
mgr->clientmgr = clientmgr;
|
||||
mgr->generation = 1;
|
||||
mgr->listenon = NULL;
|
||||
mgr->listenon4 = NULL;
|
||||
mgr->listenon6 = NULL;
|
||||
ISC_LIST_INIT(mgr->interfaces);
|
||||
|
||||
result = ns_listenlist_default(mctx, ns_g_port,
|
||||
&mgr->listenon);
|
||||
/*
|
||||
* The listen-on lists are initially empty.
|
||||
*/
|
||||
result = ns_listenlist_create(mctx, &mgr->listenon4);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_mem;
|
||||
ns_listenlist_attach(mgr->listenon4, &mgr->listenon6);
|
||||
|
||||
result = dns_aclenv_init(mctx, &mgr->aclenv);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
|
|
@ -98,7 +103,8 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
|||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup_listenon:
|
||||
ns_listenlist_detach(&mgr->listenon);
|
||||
ns_listenlist_detach(&mgr->listenon4);
|
||||
ns_listenlist_detach(&mgr->listenon6);
|
||||
cleanup_mem:
|
||||
isc_mem_put(mctx, mgr, sizeof(*mgr));
|
||||
return (result);
|
||||
|
|
@ -108,7 +114,8 @@ static void
|
|||
ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) {
|
||||
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
|
||||
dns_aclenv_destroy(&mgr->aclenv);
|
||||
ns_listenlist_detach(&mgr->listenon);
|
||||
ns_listenlist_detach(&mgr->listenon4);
|
||||
ns_listenlist_detach(&mgr->listenon6);
|
||||
isc_mutex_destroy(&mgr->lock);
|
||||
mgr->magic = 0;
|
||||
isc_mem_put(mgr->mctx, mgr, sizeof *mgr);
|
||||
|
|
@ -505,7 +512,7 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
|||
if (result != ISC_R_SUCCESS)
|
||||
goto ignore_interface;
|
||||
|
||||
for (le = ISC_LIST_HEAD(mgr->listenon->elts);
|
||||
for (le = ISC_LIST_HEAD(mgr->listenon4->elts);
|
||||
le != NULL;
|
||||
le = ISC_LIST_NEXT(le, link))
|
||||
{
|
||||
|
|
@ -577,23 +584,69 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
|||
isc_interfaceiter_destroy(&iter);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
listenon_is_ip6_none(ns_listenlist_t *p) {
|
||||
ns_listenelt_t *elt;
|
||||
if (ISC_LIST_EMPTY(p->elts))
|
||||
return (ISC_TRUE); /* No listen-on-v6 statements */
|
||||
elt = ISC_LIST_HEAD(p->elts);
|
||||
if (ISC_LIST_NEXT(elt, link) != NULL)
|
||||
return (ISC_FALSE); /* More than one listen-on-v6 stmt */
|
||||
if (elt->acl->length == 0)
|
||||
return (ISC_TRUE); /* listen-on-v6 { } */
|
||||
if (elt->acl->length > 1)
|
||||
return (ISC_FALSE); /* listen-on-v6 { ...; ...; } */
|
||||
if (elt->acl->elements[0].negative == ISC_TRUE &&
|
||||
elt->acl->elements[0].type == dns_aclelementtype_any)
|
||||
return (ISC_TRUE); /* listen-on-v6 { none; } */
|
||||
return (ISC_FALSE); /* All others */
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
listenon_is_ip6_any(ns_listenlist_t *p, in_port_t *portp) {
|
||||
ns_listenelt_t *elt;
|
||||
if (ISC_LIST_EMPTY(p->elts))
|
||||
return (ISC_FALSE); /* No listen-on-v6 statements */
|
||||
elt = ISC_LIST_HEAD(p->elts);
|
||||
if (ISC_LIST_NEXT(elt, link) != NULL)
|
||||
return (ISC_FALSE); /* More than one listen-on-v6 stmt */
|
||||
if (elt->acl->length != 1)
|
||||
return (ISC_FALSE);
|
||||
if (elt->acl->elements[0].negative == ISC_FALSE &&
|
||||
elt->acl->elements[0].type == dns_aclelementtype_any) {
|
||||
*portp = elt->port;
|
||||
return (ISC_TRUE); /* listen-on-v6 { any; } */
|
||||
}
|
||||
return (ISC_FALSE); /* All others */
|
||||
}
|
||||
|
||||
static void
|
||||
do_ipv6(ns_interfacemgr_t *mgr) {
|
||||
isc_result_t result;
|
||||
ns_interface_t *ifp;
|
||||
isc_sockaddr_t listen_addr;
|
||||
struct in6_addr in6a;
|
||||
in_port_t port;
|
||||
|
||||
if (listenon_is_ip6_none(mgr->listenon6))
|
||||
return;
|
||||
|
||||
if (! listenon_is_ip6_any(mgr->listenon6, &port)) {
|
||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||
ISC_LOG_ERROR,
|
||||
"bad IPv6 listen-on list: must be 'any' or 'none'");
|
||||
return;
|
||||
}
|
||||
|
||||
in6a = in6addr_any;
|
||||
isc_sockaddr_fromin6(&listen_addr, &in6a, ns_g_port);
|
||||
isc_sockaddr_fromin6(&listen_addr, &in6a, port);
|
||||
|
||||
ifp = find_matching_interface(mgr, &listen_addr);
|
||||
if (ifp != NULL) {
|
||||
ifp->generation = mgr->generation;
|
||||
} else {
|
||||
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_INFO,
|
||||
"listening on IPv6 interfaces, port %u",
|
||||
ns_g_port);
|
||||
"listening on IPv6 interfaces, port %u", port);
|
||||
result = ns_interface_setup(mgr, &listen_addr, "<any>", &ifp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||
|
|
@ -640,10 +693,18 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr) {
|
|||
}
|
||||
|
||||
void
|
||||
ns_interfacemgr_setlistenon(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {
|
||||
ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {
|
||||
LOCK(&mgr->lock);
|
||||
ns_listenlist_detach(&mgr->listenon);
|
||||
ns_listenlist_attach(value, &mgr->listenon);
|
||||
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) {
|
||||
LOCK(&mgr->lock);
|
||||
ns_listenlist_detach(&mgr->listenon6);
|
||||
ns_listenlist_attach(value, &mgr->listenon6);
|
||||
UNLOCK(&mgr->lock);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -400,6 +400,7 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview,
|
|||
isc_mem_t *cmctx;
|
||||
dns_dispatch_t *dispatch4 = NULL;
|
||||
dns_dispatch_t *dispatch6 = NULL;
|
||||
in_port_t port;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
|
|
@ -407,7 +408,15 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview,
|
|||
cmctx = NULL;
|
||||
|
||||
RWLOCK(&view->conflock, isc_rwlocktype_write);
|
||||
|
||||
|
||||
/*
|
||||
* Set the view's port number for outgoing queries.
|
||||
*/
|
||||
result = dns_c_ctx_getport(cctx, &port);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
port = 53;
|
||||
dns_view_setdstport(view, port);
|
||||
|
||||
/*
|
||||
* Configure the view's cache. Try to reuse an existing
|
||||
* cache if possible, otherwise create a new cache.
|
||||
|
|
@ -1102,6 +1111,7 @@ load_configuration(const char *filename, ns_server_t *server,
|
|||
dns_dispatch_t *dispatchv6 = NULL;
|
||||
char *pidfilename;
|
||||
isc_uint32_t interface_interval;
|
||||
in_port_t listen_port;
|
||||
|
||||
dns_aclconfctx_init(&aclconfctx);
|
||||
|
||||
|
|
@ -1154,6 +1164,16 @@ load_configuration(const char *filename, ns_server_t *server,
|
|||
dns_zonemgr_settransfersperns(server->zonemgr, transfersperns);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine which port to use for listening for incoming connections.
|
||||
*/
|
||||
if (ns_g_port != 0) {
|
||||
listen_port = ns_g_port;
|
||||
} else {
|
||||
result = dns_c_ctx_getport(cctx, &listen_port);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
listen_port = 53;
|
||||
}
|
||||
/*
|
||||
* Configure the interface manager according to the "listen-on"
|
||||
* statement.
|
||||
|
|
@ -1171,12 +1191,21 @@ load_configuration(const char *filename, ns_server_t *server,
|
|||
&listenon);
|
||||
} else {
|
||||
/* Not specified, use default. */
|
||||
CHECK(ns_listenlist_default(ns_g_mctx, ns_g_port,
|
||||
CHECK(ns_listenlist_default(ns_g_mctx, listen_port,
|
||||
&listenon));
|
||||
}
|
||||
ns_interfacemgr_setlistenon(server->interfacemgr, listenon);
|
||||
ns_interfacemgr_setlistenon4(server->interfacemgr, listenon);
|
||||
ns_listenlist_detach(&listenon);
|
||||
}
|
||||
/*
|
||||
* Ditto for IPv6.
|
||||
*/
|
||||
{
|
||||
ns_listenlist_t *listenon = NULL;
|
||||
CHECK(ns_listenlist_default(ns_g_mctx, listen_port, &listenon));
|
||||
ns_interfacemgr_setlistenon6(server->interfacemgr, listenon);
|
||||
ns_listenlist_detach(&listenon);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rescan the interface list to pick up changes in the
|
||||
|
|
|
|||
|
|
@ -303,7 +303,26 @@ dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring);
|
|||
* The static TSIG keyring of 'view' is 'ring'.
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
dns_view_setdstport(dns_view_t *view, in_port_t dstport);
|
||||
/*
|
||||
* Set the view's destination port. This is the port to
|
||||
* which outgoing queries are sent. The default is 53,
|
||||
* the standard DNS port.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* 'view' is a valid view.
|
||||
*
|
||||
* 'dstport' is a valid TCP/UDP port number.
|
||||
*
|
||||
* Ensures:
|
||||
* External name servers will be assumed to be listning
|
||||
* on 'dstport'. For servers whose address has already
|
||||
* obtained obtained at the time of the call, the view may
|
||||
* continue to use the previously set port until the address
|
||||
* times out from the view's address database.
|
||||
*/
|
||||
|
||||
|
||||
isc_result_t
|
||||
|
|
|
|||
|
|
@ -515,6 +515,12 @@ dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
|
|||
view->statickeys = ring;
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_setdstport(dns_view_t *view, in_port_t dstport) {
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
view->dstport = dstport;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
|
||||
isc_result_t result;
|
||||
|
|
|
|||
Loading…
Reference in a new issue