mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
1394. [func] It is now possible to check if a particular element is
in a acl. Remove duplicate entries from the localnets acl. 1393. [port] Bind to individual IPv6 interfaces if IPV6_IPV6ONLY is not available in the kernel to prevent accidently listening on IPv4 interfaces. developer: jinmei reviewer: marka
This commit is contained in:
8
CHANGES
8
CHANGES
@@ -1,3 +1,11 @@
|
||||
1394. [func] It is now possible to check if a particular element is
|
||||
in a acl. Remove duplicate entries from the localnets
|
||||
acl.
|
||||
|
||||
1393. [port] Bind to individual IPv6 interfaces if IPV6_IPV6ONLY
|
||||
is not available in the kernel to prevent accidently
|
||||
listening on IPv4 interfaces.
|
||||
|
||||
1392. [bug] named-checkzone: update usage.
|
||||
|
||||
1391. [func] Add support for IPv6 scoped addresses in named.
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: interfacemgr.c,v 1.72 2002/10/24 03:52:31 marka Exp $ */
|
||||
/* $Id: interfacemgr.c,v 1.73 2002/10/29 04:40:23 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -524,11 +524,13 @@ setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) {
|
||||
isc_result_totext(result));
|
||||
} else {
|
||||
elt.u.ip_prefix.prefixlen = prefixlen;
|
||||
/* XXX suppress duplicates */
|
||||
result = dns_acl_appendelement(mgr->aclenv.localnets,
|
||||
&elt);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
if (dns_acl_elementmatch(mgr->aclenv.localnets, &elt,
|
||||
NULL) == ISC_R_NOTFOUND) {
|
||||
result = dns_acl_appendelement(mgr->aclenv.localnets,
|
||||
&elt);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
@@ -542,6 +544,7 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
|
||||
isc_boolean_t scan_ipv4 = ISC_FALSE;
|
||||
isc_boolean_t scan_ipv6 = ISC_FALSE;
|
||||
isc_boolean_t adjusting = ISC_FALSE;
|
||||
isc_boolean_t ipv6only = ISC_TRUE;
|
||||
isc_result_t result;
|
||||
isc_netaddr_t zero_address, zero_address6;
|
||||
ns_listenelt_t *le;
|
||||
@@ -567,9 +570,25 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
|
||||
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) {
|
||||
/*
|
||||
* A special, but typical case; listen-on-v6 { any; }.
|
||||
* When we can make the socket IPv6-only, open a single wildcard
|
||||
* socket for IPv6 communication. Otherwise, make separate socket
|
||||
* for each IPv6 address in order to avoid accepting IPv4 packets
|
||||
* as the form of mapped addresses unintentionally unless explicitly
|
||||
* allowed.
|
||||
*/
|
||||
#ifndef ISC_ALLOW_MAPPED
|
||||
if (scan_ipv6 == ISC_TRUE &&
|
||||
isc_net_probe_ipv6only() != ISC_R_SUCCESS) {
|
||||
ipv6only = ISC_FALSE;
|
||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||
verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
|
||||
"IPv6-only option is not available."
|
||||
" use explicit binding");
|
||||
}
|
||||
#endif
|
||||
if (scan_ipv6 == ISC_TRUE && ipv6only) {
|
||||
for (le = ISC_LIST_HEAD(mgr->listenon6->elts);
|
||||
le != NULL;
|
||||
le = ISC_LIST_NEXT(le, link)) {
|
||||
@@ -702,7 +721,8 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
|
||||
* The case of "any" IPv6 address will require
|
||||
* special considerations later, so remember it.
|
||||
*/
|
||||
if (family == AF_INET6 && listenon_is_ip6_any(le))
|
||||
if (family == AF_INET6 && ipv6only &&
|
||||
listenon_is_ip6_any(le))
|
||||
ipv6_wildcard = ISC_TRUE;
|
||||
|
||||
/*
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd">
|
||||
|
||||
<!-- File: $Id: Bv9ARM-book.xml,v 1.206 2002/10/24 03:52:32 marka Exp $ -->
|
||||
<!-- File: $Id: Bv9ARM-book.xml,v 1.207 2002/10/29 04:40:23 marka Exp $ -->
|
||||
|
||||
<book>
|
||||
<title>BIND 9 Administrator Reference Manual</title>
|
||||
@@ -3549,11 +3549,10 @@ listen-on port 1234 { !1.2.3.4; 1.2/16; };
|
||||
server will listen on port 53 on all interfaces.</para>
|
||||
|
||||
<para>By default, the server does not bind a separate socket to each
|
||||
IPv6 interface address as it does for IPv4. Instead, it always
|
||||
listens on the IPv6 wildcard address.
|
||||
However, some particular IPv6 addresses can also be specified,
|
||||
in which case the server makes a separate socket for each specified
|
||||
address.</para>
|
||||
IPv6 interface address as it does for IPv4. Instead, it listens on the
|
||||
IPv6 wildcard address.
|
||||
Alternatively, a list of IPv6 addresses can be specified, in which case
|
||||
the server listens on a separate socket for each specified address.</para>
|
||||
|
||||
<para>Multiple <command>listen-on-v6</command> options can be used.
|
||||
For example,</para>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: acl.c,v 1.23 2001/05/31 10:43:37 tale Exp $ */
|
||||
/* $Id: acl.c,v 1.24 2002/10/29 04:40:23 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -149,6 +149,29 @@ dns_acl_match(isc_netaddr_t *reqaddr,
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_acl_elementmatch(dns_acl_t *acl,
|
||||
dns_aclelement_t *elt,
|
||||
dns_aclelement_t **matchelt)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
REQUIRE(elt != NULL);
|
||||
REQUIRE(matchelt == NULL || *matchelt == NULL);
|
||||
|
||||
for (i = 0; i < acl->length; i++) {
|
||||
dns_aclelement_t *e = &acl->elements[i];
|
||||
|
||||
if (dns_aclelement_equal(e, elt) == ISC_TRUE) {
|
||||
if (matchelt != NULL)
|
||||
*matchelt = e;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_aclelement_match(isc_netaddr_t *reqaddr,
|
||||
dns_name_t *reqsigner,
|
||||
@@ -297,8 +320,9 @@ dns_aclelement_equal(dns_aclelement_t *ea, dns_aclelement_t *eb) {
|
||||
if (ea->u.ip_prefix.prefixlen !=
|
||||
eb->u.ip_prefix.prefixlen)
|
||||
return (ISC_FALSE);
|
||||
return (isc_netaddr_equal(&ea->u.ip_prefix.address,
|
||||
&eb->u.ip_prefix.address));
|
||||
return (isc_netaddr_eqprefix(&ea->u.ip_prefix.address,
|
||||
&eb->u.ip_prefix.address,
|
||||
ea->u.ip_prefix.prefixlen));
|
||||
case dns_aclelementtype_keyname:
|
||||
return (dns_name_equal(&ea->u.keyname, &eb->u.keyname));
|
||||
case dns_aclelementtype_nestedacl:
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: acl.h,v 1.20 2001/08/28 03:58:11 marka Exp $ */
|
||||
/* $Id: acl.h,v 1.21 2002/10/29 04:40:24 marka Exp $ */
|
||||
|
||||
#ifndef DNS_ACL_H
|
||||
#define DNS_ACL_H 1
|
||||
@@ -199,6 +199,23 @@ dns_aclelement_match(isc_netaddr_t *reqaddr,
|
||||
* returned through 'matchelt' is not necessarily 'e' itself.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_acl_elementmatch(dns_acl_t *acl,
|
||||
dns_aclelement_t *elt,
|
||||
dns_aclelement_t **matchelt);
|
||||
/*
|
||||
* Search for an ACL element in 'acl' which is exactly the same as 'elt'.
|
||||
* If there is one, and 'matchelt' is non NULL, then '*matchelt' will point
|
||||
* to the entry.
|
||||
*
|
||||
* This function is intended to be used for avoiding duplicated ACL entries
|
||||
* before adding an entry.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS Match succeeds.
|
||||
* ISC_R_NOTFOUND Match fails.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_ACL_H */
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: net.h,v 1.35 2002/10/24 03:52:35 marka Exp $ */
|
||||
/* $Id: net.h,v 1.36 2002/10/29 04:40:25 marka Exp $ */
|
||||
|
||||
#ifndef ISC_NET_H
|
||||
#define ISC_NET_H 1
|
||||
@@ -260,6 +260,18 @@ isc_net_probeipv6(void);
|
||||
* ISC_R_UNEXPECTED
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_net_probe_ipv6only(void);
|
||||
/*
|
||||
* Check if the system's kernel supports the IPV6_V6ONLY socket option.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* ISC_R_SUCCESS the option is supported for both TCP and UDP.
|
||||
* ISC_R_NOTFOUND IPv6 itself or the option is not supported.
|
||||
* ISC_R_UNEXPECTED
|
||||
*/
|
||||
|
||||
#ifdef ISC_PLATFORM_NEEDNTOP
|
||||
const char *
|
||||
isc_net_ntop(int af, const void *src, char *dst, size_t size);
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: net.c,v 1.25 2001/11/30 01:59:45 gson Exp $ */
|
||||
/* $Id: net.c,v 1.26 2002/10/29 04:40:25 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -39,8 +39,10 @@ const struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT;
|
||||
#endif
|
||||
|
||||
static isc_once_t once = ISC_ONCE_INIT;
|
||||
static isc_once_t once_ipv6only = ISC_ONCE_INIT;
|
||||
static isc_result_t ipv4_result = ISC_R_NOTFOUND;
|
||||
static isc_result_t ipv6_result = ISC_R_NOTFOUND;
|
||||
static isc_result_t ipv6only_result = ISC_R_NOTFOUND;
|
||||
|
||||
static isc_result_t
|
||||
try_proto(int domain) {
|
||||
@@ -146,8 +148,102 @@ isc_net_probeipv4(void) {
|
||||
return (ipv4_result);
|
||||
}
|
||||
|
||||
#ifdef ISC_PLATFORM_HAVEIPV6
|
||||
#ifdef WANT_IPV6
|
||||
isc_result_t
|
||||
isc_net_probeipv6(void) {
|
||||
initialize();
|
||||
return (ipv6_result);
|
||||
}
|
||||
|
||||
static void
|
||||
try_ipv6only(void) {
|
||||
#ifdef IPV6_V6ONLY
|
||||
int s, on;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
#endif
|
||||
isc_result_t result;
|
||||
|
||||
result = isc_net_probeipv6();
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
ipv6only_result = result;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef IPV6_V6ONLY
|
||||
ipv6only_result = ISC_R_NOTFOUND;
|
||||
return;
|
||||
#else
|
||||
/* check for TCP sockets */
|
||||
s = socket(PF_INET6, SOCK_STREAM, 0);
|
||||
if (s == -1) {
|
||||
isc__strerror(errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"socket() %s: %s",
|
||||
isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED,
|
||||
"failed"),
|
||||
strbuf);
|
||||
ipv6only_result = ISC_R_UNEXPECTED;
|
||||
return;
|
||||
}
|
||||
|
||||
on = 1;
|
||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
|
||||
ipv6only_result = ISC_R_NOTFOUND;
|
||||
goto close;
|
||||
}
|
||||
|
||||
close(s);
|
||||
|
||||
/* check for UDP sockets */
|
||||
s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
if (s == -1) {
|
||||
isc__strerror(errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"socket() %s: %s",
|
||||
isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED,
|
||||
"failed"),
|
||||
strbuf);
|
||||
ipv6only_result = ISC_R_UNEXPECTED;
|
||||
return;
|
||||
}
|
||||
|
||||
on = 1;
|
||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
|
||||
ipv6only_result = ISC_R_NOTFOUND;
|
||||
goto close;
|
||||
}
|
||||
|
||||
close(s);
|
||||
|
||||
ipv6only_result = ISC_R_SUCCESS;
|
||||
|
||||
close:
|
||||
close(s);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_ipv6only(void) {
|
||||
RUNTIME_CHECK(isc_once_do(&once_ipv6only,
|
||||
try_ipv6only) == ISC_R_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
isc_result_t
|
||||
isc_net_probe_ipv6only(void) {
|
||||
#ifdef ISC_PLATFORM_HAVEIPV6
|
||||
#ifdef WANT_IPV6
|
||||
initialize_ipv6only();
|
||||
#else
|
||||
ipv6only_result = ISC_R_NOTFOUND;
|
||||
#endif
|
||||
#endif
|
||||
return (ipv6only_result);
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: net.h,v 1.17 2002/08/01 03:56:08 mayer Exp $ */
|
||||
/* $Id: net.h,v 1.18 2002/10/29 04:40:26 marka Exp $ */
|
||||
|
||||
#ifndef ISC_NET_H
|
||||
#define ISC_NET_H 1
|
||||
@@ -247,6 +247,18 @@ isc_net_probeipv6(void);
|
||||
* ISC_R_UNEXPECTED
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_net_probe_ipv6only(void);
|
||||
/*
|
||||
* Check if the system's kernel supports the IPV6_V6ONLY socket option.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* ISC_R_SUCCESS the option is supported for both TCP and UDP.
|
||||
* ISC_R_NOTFOUND IPv6 itself or the option is not supported.
|
||||
* ISC_R_UNEXPECTED
|
||||
*/
|
||||
|
||||
#ifdef ISC_PLATFORM_NEEDNTOP
|
||||
const char *
|
||||
isc_net_ntop(int af, const void *src, char *dst, size_t size);
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: net.c,v 1.4 2001/11/21 05:07:25 mayer Exp $ */
|
||||
/* $Id: net.c,v 1.5 2002/10/29 04:40:25 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -35,8 +35,10 @@ const struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT;
|
||||
#endif
|
||||
|
||||
static isc_once_t once = ISC_ONCE_INIT;
|
||||
static isc_once_t once_ipv6only = ISC_ONCE_INIT;
|
||||
static isc_result_t ipv4_result = ISC_R_NOTFOUND;
|
||||
static isc_result_t ipv6_result = ISC_R_NOTFOUND;
|
||||
static isc_result_t ipv6only_result = ISC_R_NOTFOUND;
|
||||
|
||||
static isc_result_t
|
||||
try_proto(int domain) {
|
||||
@@ -140,8 +142,102 @@ isc_net_probeipv4(void) {
|
||||
return (ipv4_result);
|
||||
}
|
||||
|
||||
#ifdef ISC_PLATFORM_HAVEIPV6
|
||||
#ifdef WANT_IPV6
|
||||
isc_result_t
|
||||
isc_net_probeipv6(void) {
|
||||
initialize();
|
||||
return (ipv6_result);
|
||||
}
|
||||
|
||||
static void
|
||||
try_ipv6only(void) {
|
||||
#ifdef IPV6_V6ONLY
|
||||
int s, on;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
#endif
|
||||
isc_result_t result;
|
||||
|
||||
result = isc_net_probeipv6();
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
ipv6only_result = result;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef IPV6_V6ONLY
|
||||
ipv6only_result = ISC_R_NOTFOUND;
|
||||
return;
|
||||
#else
|
||||
/* check for TCP sockets */
|
||||
s = socket(PF_INET6, SOCK_STREAM, 0);
|
||||
if (s == -1) {
|
||||
isc__strerror(errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"socket() %s: %s",
|
||||
isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED,
|
||||
"failed"),
|
||||
strbuf);
|
||||
ipv6only_result = ISC_R_UNEXPECTED;
|
||||
return;
|
||||
}
|
||||
|
||||
on = 1;
|
||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
|
||||
ipv6only_result = ISC_R_NOTFOUND;
|
||||
goto close;
|
||||
}
|
||||
|
||||
close(s);
|
||||
|
||||
/* check for UDP sockets */
|
||||
s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
if (s == -1) {
|
||||
isc__strerror(errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"socket() %s: %s",
|
||||
isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED,
|
||||
"failed"),
|
||||
strbuf);
|
||||
ipv6only_result = ISC_R_UNEXPECTED;
|
||||
return;
|
||||
}
|
||||
|
||||
on = 1;
|
||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
|
||||
ipv6only_result = ISC_R_NOTFOUND;
|
||||
goto close;
|
||||
}
|
||||
|
||||
close(s);
|
||||
|
||||
ipv6only_result = ISC_R_SUCCESS;
|
||||
|
||||
close:
|
||||
close(s);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_ipv6only(void) {
|
||||
RUNTIME_CHECK(isc_once_do(&once_ipv6only,
|
||||
try_ipv6only) == ISC_R_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
isc_result_t
|
||||
isc_net_probe_ipv6only(void) {
|
||||
#ifdef ISC_PLATFORM_HAVEIPV6
|
||||
#ifdef WANT_IPV6
|
||||
initialize_ipv6only();
|
||||
#else
|
||||
ipv6only_result = ISC_R_NOTFOUND;
|
||||
#endif
|
||||
#endif
|
||||
return (ipv6only_result);
|
||||
}
|
||||
|
Reference in New Issue
Block a user