mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +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.
|
||||
|
||||
1358. [func] log the reason for rejecting a server when resolving
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* 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>
|
||||
|
||||
@@ -478,13 +478,75 @@ clearacl(isc_mem_t *mctx, dns_acl_t **aclp) {
|
||||
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
|
||||
do_ipv4(ns_interfacemgr_t *mgr) {
|
||||
do_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) {
|
||||
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_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_any6(&zero_address6);
|
||||
|
||||
result = isc_interfaceiter_create(mgr->mctx, &iter);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
@@ -501,17 +563,22 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
||||
result == ISC_R_SUCCESS;
|
||||
result = isc_interfaceiter_next(iter))
|
||||
{
|
||||
ns_interface_t *ifp;
|
||||
isc_interface_t interface;
|
||||
ns_listenelt_t *le;
|
||||
ns_listenlist_t *ll;
|
||||
dns_aclelement_t elt;
|
||||
unsigned int prefixlen;
|
||||
unsigned int family;
|
||||
|
||||
result = isc_interfaceiter_current(iter, &interface);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
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;
|
||||
|
||||
/*
|
||||
@@ -521,19 +588,30 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
||||
* the interface for an entire rescan interval due to
|
||||
* 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;
|
||||
}
|
||||
if (family == AF_INET6 &&
|
||||
isc_netaddr_equal(&interface.address, &zero_address6)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
elt.type = dns_aclelementtype_ipprefix;
|
||||
elt.negative = ISC_FALSE;
|
||||
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);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto ignore_interface;
|
||||
|
||||
result = isc_netaddr_masktoprefixlen(&interface.netmask,
|
||||
&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) {
|
||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||
ISC_LOG_WARNING,
|
||||
@@ -550,7 +628,15 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
||||
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 = ISC_LIST_NEXT(le, link))
|
||||
{
|
||||
@@ -562,8 +648,13 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
||||
* Construct a socket address for this IP/port
|
||||
* combination.
|
||||
*/
|
||||
isc_netaddr_fromin(&listen_netaddr,
|
||||
&interface.address.type.in);
|
||||
if (family == AF_INET) {
|
||||
isc_netaddr_fromin(&listen_netaddr,
|
||||
&interface.address.type.in);
|
||||
} else {
|
||||
isc_netaddr_fromin6(&listen_netaddr,
|
||||
&interface.address.type.in6);
|
||||
}
|
||||
isc_sockaddr_fromnetaddr(&listen_sockaddr,
|
||||
&listen_netaddr,
|
||||
le->port);
|
||||
@@ -587,8 +678,11 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
||||
sabuf, sizeof(sabuf));
|
||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||
ISC_LOG_INFO,
|
||||
"listening on IPv4 interface "
|
||||
"%s, %s", interface.name, sabuf);
|
||||
"listening on %s interface "
|
||||
"%s, %s",
|
||||
(family == AF_INET) ?
|
||||
"IPv4" : "IPv6",
|
||||
interface.name, sabuf);
|
||||
|
||||
result = ns_interface_setup(mgr,
|
||||
&listen_sockaddr,
|
||||
@@ -596,10 +690,13 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
||||
&ifp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||
ISC_LOG_ERROR,
|
||||
"creating IPv4 interface %s "
|
||||
"failed; interface ignored",
|
||||
interface.name);
|
||||
ISC_LOG_ERROR,
|
||||
"creating %s interface "
|
||||
"%s failed; interface "
|
||||
"ignored",
|
||||
(family == AF_INET) ?
|
||||
"IPv4" : "IPv6",
|
||||
interface.name);
|
||||
}
|
||||
/* Continue. */
|
||||
}
|
||||
@@ -610,13 +707,14 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
||||
ignore_interface:
|
||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||
ISC_LOG_ERROR,
|
||||
"ignoring IPv4 interface %s: %s",
|
||||
"ignoring %s interface %s: %s",
|
||||
(family == AF_INET) ? "IPv4" : "IPv6",
|
||||
interface.name, isc_result_totext(result));
|
||||
continue;
|
||||
}
|
||||
if (result != ISC_R_NOMORE)
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"IPv4: interface iteration failed: %s",
|
||||
"interface iteration failed: %s",
|
||||
isc_result_totext(result));
|
||||
else
|
||||
result = ISC_R_SUCCESS;
|
||||
@@ -625,74 +723,6 @@ do_ipv4(ns_interfacemgr_t *mgr) {
|
||||
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
|
||||
ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) {
|
||||
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. */
|
||||
|
||||
if (isc_net_probeipv6() == ISC_R_SUCCESS) {
|
||||
if (do_ipv6(mgr) != ISC_R_SUCCESS)
|
||||
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");
|
||||
if (do_scan(mgr, verbose) != ISC_R_SUCCESS)
|
||||
purge = ISC_FALSE;
|
||||
|
||||
/*
|
||||
* Now go through the interface list and delete anything that
|
||||
|
Reference in New Issue
Block a user