mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-03 16:15:27 +00:00
reviewed: marka
developer: jinmei 1360. [func] Listen-on-v6 now supports specific addresses.
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -1,3 +1,5 @@
|
|||||||
|
1360. [func] Listen-on-v6 now supports specific addresses.
|
||||||
|
|
||||||
1359. [bug] remove IF_RUNNING test when scanning interfaces.
|
1359. [bug] remove IF_RUNNING test when scanning interfaces.
|
||||||
|
|
||||||
1358. [func] log the reason for rejecting a server when resolving
|
1358. [func] log the reason for rejecting a server when resolving
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: interfacemgr.c,v 1.67 2002/05/27 00:40:16 marka Exp $ */
|
/* $Id: interfacemgr.c,v 1.68 2002/08/16 23:46:11 marka Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -478,13 +478,75 @@ clearacl(isc_mem_t *mctx, dns_acl_t **aclp) {
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isc_boolean_t
|
||||||
|
listenon_is_ip6_any(ns_listenelt_t *elt) {
|
||||||
|
if (elt->acl->length != 1)
|
||||||
|
return (ISC_FALSE);
|
||||||
|
if (elt->acl->elements[0].negative == ISC_FALSE &&
|
||||||
|
elt->acl->elements[0].type == dns_aclelementtype_any)
|
||||||
|
return (ISC_TRUE); /* listen-on-v6 { any; } */
|
||||||
|
return (ISC_FALSE); /* All others */
|
||||||
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
do_ipv4(ns_interfacemgr_t *mgr) {
|
do_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) {
|
||||||
isc_interfaceiter_t *iter = NULL;
|
isc_interfaceiter_t *iter = NULL;
|
||||||
|
isc_boolean_t scan_ipv4 = ISC_FALSE;
|
||||||
|
isc_boolean_t scan_ipv6 = ISC_FALSE;
|
||||||
|
isc_boolean_t setup_ipv6 = ISC_TRUE;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_netaddr_t zero_address;
|
isc_netaddr_t zero_address, zero_address6;
|
||||||
|
ns_listenelt_t *le;
|
||||||
|
isc_sockaddr_t listen_addr;
|
||||||
|
ns_interface_t *ifp;
|
||||||
|
|
||||||
|
if (isc_net_probeipv6() == ISC_R_SUCCESS)
|
||||||
|
scan_ipv6 = ISC_TRUE;
|
||||||
|
#ifdef WANT_IPV6
|
||||||
|
else
|
||||||
|
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||||
|
verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
|
||||||
|
"no IPv6 interfaces found");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (isc_net_probeipv4() == ISC_R_SUCCESS)
|
||||||
|
scan_ipv4 = ISC_TRUE;
|
||||||
|
else
|
||||||
|
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||||
|
verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
|
||||||
|
"no IPv4 interfaces found");
|
||||||
|
|
||||||
|
/* A special, but typical case; listen-on-v6 { any; } */
|
||||||
|
/* XXXJT fix when we probe for IPV6_V6ONLY */
|
||||||
|
if (scan_ipv6 == ISC_TRUE &&
|
||||||
|
(le = ISC_LIST_HEAD(mgr->listenon6->elts)) != NULL &&
|
||||||
|
listenon_is_ip6_any(le)) {
|
||||||
|
struct in6_addr in6a;
|
||||||
|
|
||||||
|
in6a = in6addr_any;
|
||||||
|
isc_sockaddr_fromin6(&listen_addr, &in6a, le->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",
|
||||||
|
le->port);
|
||||||
|
result = ns_interface_setup(mgr, &listen_addr,
|
||||||
|
"<any>", &ifp);
|
||||||
|
if (result == ISC_R_SUCCESS)
|
||||||
|
setup_ipv6 = ISC_FALSE;
|
||||||
|
else
|
||||||
|
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||||
|
ISC_LOG_ERROR,
|
||||||
|
"listening on all IPv6 "
|
||||||
|
"interfaces failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isc_netaddr_any(&zero_address);
|
isc_netaddr_any(&zero_address);
|
||||||
|
isc_netaddr_any6(&zero_address6);
|
||||||
|
|
||||||
result = isc_interfaceiter_create(mgr->mctx, &iter);
|
result = isc_interfaceiter_create(mgr->mctx, &iter);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
@@ -501,17 +563,22 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
|||||||
result == ISC_R_SUCCESS;
|
result == ISC_R_SUCCESS;
|
||||||
result = isc_interfaceiter_next(iter))
|
result = isc_interfaceiter_next(iter))
|
||||||
{
|
{
|
||||||
ns_interface_t *ifp;
|
|
||||||
isc_interface_t interface;
|
isc_interface_t interface;
|
||||||
ns_listenelt_t *le;
|
ns_listenlist_t *ll;
|
||||||
dns_aclelement_t elt;
|
dns_aclelement_t elt;
|
||||||
unsigned int prefixlen;
|
unsigned int prefixlen;
|
||||||
|
unsigned int family;
|
||||||
|
|
||||||
result = isc_interfaceiter_current(iter, &interface);
|
result = isc_interfaceiter_current(iter, &interface);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (interface.address.family != AF_INET)
|
family = interface.address.family;
|
||||||
|
if (family != AF_INET && family != AF_INET6)
|
||||||
|
continue;
|
||||||
|
if (scan_ipv4 == ISC_FALSE && family == AF_INET)
|
||||||
|
continue;
|
||||||
|
if (scan_ipv6 == ISC_FALSE && family == AF_INET6)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -521,19 +588,30 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
|||||||
* the interface for an entire rescan interval due to
|
* the interface for an entire rescan interval due to
|
||||||
* a temporary media glitch at rescan time.
|
* a temporary media glitch at rescan time.
|
||||||
*/
|
*/
|
||||||
if (isc_netaddr_equal(&interface.address, &zero_address))
|
if (family == AF_INET &&
|
||||||
|
isc_netaddr_equal(&interface.address, &zero_address)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
if (family == AF_INET6 &&
|
||||||
|
isc_netaddr_equal(&interface.address, &zero_address6)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
elt.type = dns_aclelementtype_ipprefix;
|
elt.type = dns_aclelementtype_ipprefix;
|
||||||
elt.negative = ISC_FALSE;
|
elt.negative = ISC_FALSE;
|
||||||
elt.u.ip_prefix.address = interface.address;
|
elt.u.ip_prefix.address = interface.address;
|
||||||
elt.u.ip_prefix.prefixlen = 32;
|
elt.u.ip_prefix.prefixlen = (family == AF_INET) ? 32 : 128;
|
||||||
result = dns_acl_appendelement(mgr->aclenv.localhost, &elt);
|
result = dns_acl_appendelement(mgr->aclenv.localhost, &elt);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto ignore_interface;
|
goto ignore_interface;
|
||||||
|
|
||||||
result = isc_netaddr_masktoprefixlen(&interface.netmask,
|
result = isc_netaddr_masktoprefixlen(&interface.netmask,
|
||||||
&prefixlen);
|
&prefixlen);
|
||||||
|
|
||||||
|
/* Non contigious netmasks not allowed by IPv6 arch. */
|
||||||
|
if (result != ISC_R_SUCCESS && family == AF_INET6)
|
||||||
|
goto ignore_interface;
|
||||||
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||||
ISC_LOG_WARNING,
|
ISC_LOG_WARNING,
|
||||||
@@ -550,7 +628,15 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
|||||||
goto ignore_interface;
|
goto ignore_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (le = ISC_LIST_HEAD(mgr->listenon4->elts);
|
/*
|
||||||
|
* If we've made a wildcard AF_INET6 socket, silently skip all
|
||||||
|
* IPv6 addresses to bind.
|
||||||
|
*/
|
||||||
|
if (family == AF_INET6 && setup_ipv6 == ISC_FALSE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6;
|
||||||
|
for (le = ISC_LIST_HEAD(ll->elts);
|
||||||
le != NULL;
|
le != NULL;
|
||||||
le = ISC_LIST_NEXT(le, link))
|
le = ISC_LIST_NEXT(le, link))
|
||||||
{
|
{
|
||||||
@@ -562,8 +648,13 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
|||||||
* Construct a socket address for this IP/port
|
* Construct a socket address for this IP/port
|
||||||
* combination.
|
* combination.
|
||||||
*/
|
*/
|
||||||
|
if (family == AF_INET) {
|
||||||
isc_netaddr_fromin(&listen_netaddr,
|
isc_netaddr_fromin(&listen_netaddr,
|
||||||
&interface.address.type.in);
|
&interface.address.type.in);
|
||||||
|
} else {
|
||||||
|
isc_netaddr_fromin6(&listen_netaddr,
|
||||||
|
&interface.address.type.in6);
|
||||||
|
}
|
||||||
isc_sockaddr_fromnetaddr(&listen_sockaddr,
|
isc_sockaddr_fromnetaddr(&listen_sockaddr,
|
||||||
&listen_netaddr,
|
&listen_netaddr,
|
||||||
le->port);
|
le->port);
|
||||||
@@ -587,8 +678,11 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
|||||||
sabuf, sizeof(sabuf));
|
sabuf, sizeof(sabuf));
|
||||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||||
ISC_LOG_INFO,
|
ISC_LOG_INFO,
|
||||||
"listening on IPv4 interface "
|
"listening on %s interface "
|
||||||
"%s, %s", interface.name, sabuf);
|
"%s, %s",
|
||||||
|
(family == AF_INET) ?
|
||||||
|
"IPv4" : "IPv6",
|
||||||
|
interface.name, sabuf);
|
||||||
|
|
||||||
result = ns_interface_setup(mgr,
|
result = ns_interface_setup(mgr,
|
||||||
&listen_sockaddr,
|
&listen_sockaddr,
|
||||||
@@ -597,8 +691,11 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
|||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||||
ISC_LOG_ERROR,
|
ISC_LOG_ERROR,
|
||||||
"creating IPv4 interface %s "
|
"creating %s interface "
|
||||||
"failed; interface ignored",
|
"%s failed; interface "
|
||||||
|
"ignored",
|
||||||
|
(family == AF_INET) ?
|
||||||
|
"IPv4" : "IPv6",
|
||||||
interface.name);
|
interface.name);
|
||||||
}
|
}
|
||||||
/* Continue. */
|
/* Continue. */
|
||||||
@@ -610,13 +707,14 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
|||||||
ignore_interface:
|
ignore_interface:
|
||||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||||
ISC_LOG_ERROR,
|
ISC_LOG_ERROR,
|
||||||
"ignoring IPv4 interface %s: %s",
|
"ignoring %s interface %s: %s",
|
||||||
|
(family == AF_INET) ? "IPv4" : "IPv6",
|
||||||
interface.name, isc_result_totext(result));
|
interface.name, isc_result_totext(result));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (result != ISC_R_NOMORE)
|
if (result != ISC_R_NOMORE)
|
||||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||||
"IPv4: interface iteration failed: %s",
|
"interface iteration failed: %s",
|
||||||
isc_result_totext(result));
|
isc_result_totext(result));
|
||||||
else
|
else
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
@@ -625,74 +723,6 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_boolean_t
|
|
||||||
listenon_is_ip6_none(ns_listenelt_t *elt) {
|
|
||||||
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_listenelt_t *elt) {
|
|
||||||
if (elt->acl->length != 1)
|
|
||||||
return (ISC_FALSE);
|
|
||||||
if (elt->acl->elements[0].negative == ISC_FALSE &&
|
|
||||||
elt->acl->elements[0].type == dns_aclelementtype_any)
|
|
||||||
return (ISC_TRUE); /* listen-on-v6 { any; } */
|
|
||||||
return (ISC_FALSE); /* All others */
|
|
||||||
}
|
|
||||||
|
|
||||||
static isc_result_t
|
|
||||||
do_ipv6(ns_interfacemgr_t *mgr) {
|
|
||||||
isc_result_t result;
|
|
||||||
ns_interface_t *ifp;
|
|
||||||
isc_sockaddr_t listen_addr;
|
|
||||||
struct in6_addr in6a;
|
|
||||||
ns_listenelt_t *le;
|
|
||||||
|
|
||||||
for (le = ISC_LIST_HEAD(mgr->listenon6->elts);
|
|
||||||
le != NULL;
|
|
||||||
le = ISC_LIST_NEXT(le, link))
|
|
||||||
{
|
|
||||||
if (listenon_is_ip6_none(le))
|
|
||||||
continue;
|
|
||||||
if (! listenon_is_ip6_any(le)) {
|
|
||||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
|
||||||
ISC_LOG_ERROR,
|
|
||||||
"bad IPv6 listen-on list: "
|
|
||||||
"must be 'any' or 'none'");
|
|
||||||
return (ISC_R_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
in6a = in6addr_any;
|
|
||||||
isc_sockaddr_fromin6(&listen_addr, &in6a, le->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",
|
|
||||||
le->port);
|
|
||||||
result = ns_interface_setup(mgr, &listen_addr,
|
|
||||||
"<any>", &ifp);
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
|
||||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
|
||||||
ISC_LOG_ERROR,
|
|
||||||
"listening on IPv6 interfaces "
|
|
||||||
"failed");
|
|
||||||
/* Continue. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (ISC_R_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) {
|
ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) {
|
||||||
isc_boolean_t purge = ISC_TRUE;
|
isc_boolean_t purge = ISC_TRUE;
|
||||||
@@ -701,24 +731,8 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) {
|
|||||||
|
|
||||||
mgr->generation++; /* Increment the generation count. */
|
mgr->generation++; /* Increment the generation count. */
|
||||||
|
|
||||||
if (isc_net_probeipv6() == ISC_R_SUCCESS) {
|
if (do_scan(mgr, verbose) != ISC_R_SUCCESS)
|
||||||
if (do_ipv6(mgr) != ISC_R_SUCCESS)
|
|
||||||
purge = ISC_FALSE;
|
purge = ISC_FALSE;
|
||||||
}
|
|
||||||
#ifdef WANT_IPV6
|
|
||||||
else
|
|
||||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
|
||||||
verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
|
|
||||||
"no IPv6 interfaces found");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (isc_net_probeipv4() == ISC_R_SUCCESS) {
|
|
||||||
if (do_ipv4(mgr) != ISC_R_SUCCESS)
|
|
||||||
purge = ISC_FALSE;
|
|
||||||
} else
|
|
||||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
|
||||||
verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
|
|
||||||
"no IPv4 interfaces found");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now go through the interface list and delete anything that
|
* Now go through the interface list and delete anything that
|
||||||
|
Reference in New Issue
Block a user