mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
1622. [func] probe the system to see if IPV6_(RECV)PKTINFO is
available, and suppress wildcard binding if not. 1621. [bug] match-destinations did not work for IPv6 TCP queries. [RT# 11156]
This commit is contained in:
6
CHANGES
6
CHANGES
@@ -2,9 +2,11 @@
|
|||||||
"sending notifies" log message when also-notify was
|
"sending notifies" log message when also-notify was
|
||||||
used. [RT #11177]
|
used. [RT #11177]
|
||||||
|
|
||||||
1622. [placeholder] rt11156
|
1622. [func] probe the system to see if IPV6_(RECV)PKTINFO is
|
||||||
|
available, and suppress wildcard binding if not.
|
||||||
|
|
||||||
1621. [placeholder] rt11156
|
1621. [bug] match-destinations did not work for IPv6 TCP queries.
|
||||||
|
[RT# 11156]
|
||||||
|
|
||||||
1620. [func] When loading a zone report if it is signed. [RT #11149]
|
1620. [func] When loading a zone report if it is signed. [RT #11149]
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: client.c,v 1.219 2004/03/05 04:57:46 marka Exp $ */
|
/* $Id: client.c,v 1.220 2004/04/29 01:37:12 marka Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -1344,12 +1344,33 @@ client_request(isc_task_t *task, isc_event_t *event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine the destination address. For IPv6, we get this from the
|
* Determine the destination address. If the receiving interface is
|
||||||
* pktinfo structure (if supported). For IPv4, we have to make do with
|
* bound to a specific address, we simply use it regardless of the
|
||||||
* the address of the interface where the request was received.
|
* address family. All IPv4 queries should fall into this case.
|
||||||
|
* Otherwise, if this is a TCP query, get the address from the
|
||||||
|
* receiving socket (this needs a system call and can be heavy).
|
||||||
|
* For IPv6 UDP queries, we get this from the pktinfo structure (if
|
||||||
|
* supported).
|
||||||
|
* If all the attempts fail (this can happen due to memory shortage,
|
||||||
|
* etc), we regard this as an error for safety.
|
||||||
*/
|
*/
|
||||||
if (client->interface->addr.type.sa.sa_family == AF_INET6) {
|
if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0)
|
||||||
if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0) {
|
isc_netaddr_fromsockaddr(&destaddr, &client->interface->addr);
|
||||||
|
else {
|
||||||
|
result = ISC_R_FAILURE;
|
||||||
|
|
||||||
|
if (TCP_CLIENT(client)) {
|
||||||
|
isc_sockaddr_t destsockaddr;
|
||||||
|
|
||||||
|
result = isc_socket_getsockname(client->tcpsocket,
|
||||||
|
&destsockaddr);
|
||||||
|
if (result == ISC_R_SUCCESS)
|
||||||
|
isc_netaddr_fromsockaddr(&destaddr,
|
||||||
|
&destsockaddr);
|
||||||
|
}
|
||||||
|
if (result != ISC_R_SUCCESS &&
|
||||||
|
client->interface->addr.type.sa.sa_family == AF_INET6 &&
|
||||||
|
(client->attributes & NS_CLIENTATTR_PKTINFO) != 0) {
|
||||||
isc_uint32_t zone = 0;
|
isc_uint32_t zone = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1366,11 +1387,15 @@ client_request(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_netaddr_fromin6(&destaddr,
|
isc_netaddr_fromin6(&destaddr,
|
||||||
&client->pktinfo.ipi6_addr);
|
&client->pktinfo.ipi6_addr);
|
||||||
isc_netaddr_setzone(&destaddr, zone);
|
isc_netaddr_setzone(&destaddr, zone);
|
||||||
|
result = ISC_R_SUCCESS;
|
||||||
} else
|
}
|
||||||
isc_netaddr_any6(&destaddr);
|
if (result != ISC_R_SUCCESS) {
|
||||||
} else {
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||||
isc_netaddr_fromsockaddr(&destaddr, &client->interface->addr);
|
"failed to get request's "
|
||||||
|
"destination: %s",
|
||||||
|
isc_result_totext(result));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: interfacemgr.h,v 1.26 2004/03/05 04:57:55 marka Exp $ */
|
/* $Id: interfacemgr.h,v 1.27 2004/04/29 01:37:13 marka Exp $ */
|
||||||
|
|
||||||
#ifndef NAMED_INTERFACEMGR_H
|
#ifndef NAMED_INTERFACEMGR_H
|
||||||
#define NAMED_INTERFACEMGR_H 1
|
#define NAMED_INTERFACEMGR_H 1
|
||||||
@@ -65,6 +65,8 @@
|
|||||||
#define IFACE_MAGIC ISC_MAGIC('I',':','-',')')
|
#define IFACE_MAGIC ISC_MAGIC('I',':','-',')')
|
||||||
#define NS_INTERFACE_VALID(t) ISC_MAGIC_VALID(t, IFACE_MAGIC)
|
#define NS_INTERFACE_VALID(t) ISC_MAGIC_VALID(t, IFACE_MAGIC)
|
||||||
|
|
||||||
|
#define NS_INTERFACEFLAG_ANYADDR 0x01U /* bound to "any" address */
|
||||||
|
|
||||||
struct ns_interface {
|
struct ns_interface {
|
||||||
unsigned int magic; /* Magic number. */
|
unsigned int magic; /* Magic number. */
|
||||||
ns_interfacemgr_t * mgr; /* Interface manager. */
|
ns_interfacemgr_t * mgr; /* Interface manager. */
|
||||||
@@ -72,6 +74,7 @@ struct ns_interface {
|
|||||||
int references; /* Locked */
|
int references; /* Locked */
|
||||||
unsigned int generation; /* Generation number. */
|
unsigned int generation; /* Generation number. */
|
||||||
isc_sockaddr_t addr; /* Address and port. */
|
isc_sockaddr_t addr; /* Address and port. */
|
||||||
|
unsigned int flags; /* Interface characteristics */
|
||||||
char name[32]; /* Null terminated. */
|
char name[32]; /* Null terminated. */
|
||||||
dns_dispatch_t * udpdispatch; /* UDP dispatcher. */
|
dns_dispatch_t * udpdispatch; /* UDP dispatcher. */
|
||||||
isc_socket_t * tcpsocket; /* TCP socket. */
|
isc_socket_t * tcpsocket; /* TCP socket. */
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: interfacemgr.c,v 1.76 2004/03/05 04:57:46 marka Exp $ */
|
/* $Id: interfacemgr.c,v 1.77 2004/04/29 01:37:12 marka Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -545,6 +545,7 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
|
|||||||
isc_boolean_t scan_ipv6 = ISC_FALSE;
|
isc_boolean_t scan_ipv6 = ISC_FALSE;
|
||||||
isc_boolean_t adjusting = ISC_FALSE;
|
isc_boolean_t adjusting = ISC_FALSE;
|
||||||
isc_boolean_t ipv6only = ISC_TRUE;
|
isc_boolean_t ipv6only = ISC_TRUE;
|
||||||
|
isc_boolean_t ipv6pktinfo = ISC_TRUE;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_netaddr_t zero_address, zero_address6;
|
isc_netaddr_t zero_address, zero_address6;
|
||||||
ns_listenelt_t *le;
|
ns_listenelt_t *le;
|
||||||
@@ -586,7 +587,12 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
|
|||||||
log_explicit = ISC_TRUE;
|
log_explicit = ISC_TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (scan_ipv6 == ISC_TRUE && ipv6only) {
|
if (scan_ipv6 == ISC_TRUE &&
|
||||||
|
isc_net_probe_ipv6pktinfo() != ISC_R_SUCCESS) {
|
||||||
|
ipv6pktinfo = ISC_FALSE;
|
||||||
|
log_explicit = ISC_TRUE;
|
||||||
|
}
|
||||||
|
if (scan_ipv6 == ISC_TRUE && ipv6only && ipv6pktinfo) {
|
||||||
for (le = ISC_LIST_HEAD(mgr->listenon6->elts);
|
for (le = ISC_LIST_HEAD(mgr->listenon6->elts);
|
||||||
le != NULL;
|
le != NULL;
|
||||||
le = ISC_LIST_NEXT(le, link)) {
|
le = ISC_LIST_NEXT(le, link)) {
|
||||||
@@ -610,7 +616,9 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
|
|||||||
result = ns_interface_setup(mgr, &listen_addr,
|
result = ns_interface_setup(mgr, &listen_addr,
|
||||||
"<any>", &ifp,
|
"<any>", &ifp,
|
||||||
ISC_TRUE);
|
ISC_TRUE);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result == ISC_R_SUCCESS)
|
||||||
|
ifp->flags |= NS_INTERFACEFLAG_ANYADDR;
|
||||||
|
else
|
||||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||||
ISC_LOG_ERROR,
|
ISC_LOG_ERROR,
|
||||||
"listening on all IPv6 "
|
"listening on all IPv6 "
|
||||||
@@ -719,7 +727,7 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
|
|||||||
* The case of "any" IPv6 address will require
|
* The case of "any" IPv6 address will require
|
||||||
* special considerations later, so remember it.
|
* special considerations later, so remember it.
|
||||||
*/
|
*/
|
||||||
if (family == AF_INET6 && ipv6only &&
|
if (family == AF_INET6 && ipv6only && ipv6pktinfo &&
|
||||||
listenon_is_ip6_any(le))
|
listenon_is_ip6_any(le))
|
||||||
ipv6_wildcard = ISC_TRUE;
|
ipv6_wildcard = ISC_TRUE;
|
||||||
|
|
||||||
@@ -760,14 +768,14 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (log_explicit && family == AF_INET6 &&
|
if (log_explicit && family == AF_INET6 &&
|
||||||
!adjusting) {
|
!adjusting && listenon_is_ip6_any(le)) {
|
||||||
isc_log_write(IFMGR_COMMON_LOGARGS,
|
isc_log_write(IFMGR_COMMON_LOGARGS,
|
||||||
verbose ? ISC_LOG_INFO :
|
verbose ? ISC_LOG_INFO :
|
||||||
ISC_LOG_DEBUG(1),
|
ISC_LOG_DEBUG(1),
|
||||||
"IPv6-only option is not"
|
"IPv6 socket API is "
|
||||||
" available; explicitly"
|
"incomplete; explicitly "
|
||||||
" binding to all IPv6"
|
"binding to each IPv6 "
|
||||||
" addresses.");
|
"address separately");
|
||||||
log_explicit = ISC_FALSE;
|
log_explicit = ISC_FALSE;
|
||||||
}
|
}
|
||||||
isc_sockaddr_format(&listen_sockaddr,
|
isc_sockaddr_format(&listen_sockaddr,
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: net.h,v 1.39 2004/03/05 05:11:52 marka Exp $ */
|
/* $Id: net.h,v 1.40 2004/04/29 01:37:13 marka Exp $ */
|
||||||
|
|
||||||
#ifndef ISC_NET_H
|
#ifndef ISC_NET_H
|
||||||
#define ISC_NET_H 1
|
#define ISC_NET_H 1
|
||||||
@@ -278,6 +278,19 @@ isc_net_probe_ipv6only(void);
|
|||||||
* ISC_R_UNEXPECTED
|
* ISC_R_UNEXPECTED
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_net_probe_ipv6pktinfo(void);
|
||||||
|
/*
|
||||||
|
* Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
|
||||||
|
* for UDP sockets.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*
|
||||||
|
* ISC_R_SUCCESS the option is supported.
|
||||||
|
* ISC_R_NOTFOUND IPv6 itself or the option is not supported.
|
||||||
|
* ISC_R_UNEXPECTED
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
isc_net_disableipv4(void);
|
isc_net_disableipv4(void);
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: net.c,v 1.29 2004/03/05 05:11:46 marka Exp $ */
|
/* $Id: net.c,v 1.30 2004/04/29 01:37:13 marka Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -40,9 +40,11 @@ const struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT;
|
|||||||
|
|
||||||
static isc_once_t once = ISC_ONCE_INIT;
|
static isc_once_t once = ISC_ONCE_INIT;
|
||||||
static isc_once_t once_ipv6only = ISC_ONCE_INIT;
|
static isc_once_t once_ipv6only = ISC_ONCE_INIT;
|
||||||
|
static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT;
|
||||||
static isc_result_t ipv4_result = ISC_R_NOTFOUND;
|
static isc_result_t ipv4_result = ISC_R_NOTFOUND;
|
||||||
static isc_result_t ipv6_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 ipv6only_result = ISC_R_NOTFOUND;
|
||||||
|
static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND;
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
try_proto(int domain) {
|
try_proto(int domain) {
|
||||||
@@ -225,7 +227,7 @@ try_ipv6only(void) {
|
|||||||
close:
|
close:
|
||||||
close(s);
|
close(s);
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif /* IPV6_V6ONLY */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -233,8 +235,61 @@ initialize_ipv6only(void) {
|
|||||||
RUNTIME_CHECK(isc_once_do(&once_ipv6only,
|
RUNTIME_CHECK(isc_once_do(&once_ipv6only,
|
||||||
try_ipv6only) == ISC_R_SUCCESS);
|
try_ipv6only) == ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
#endif /* IPV6_V6ONLY */
|
||||||
|
|
||||||
|
static void
|
||||||
|
try_ipv6pktinfo(void) {
|
||||||
|
int s, on;
|
||||||
|
char strbuf[ISC_STRERRORSIZE];
|
||||||
|
isc_result_t result;
|
||||||
|
int optname;
|
||||||
|
|
||||||
|
result = isc_net_probeipv6();
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
ipv6pktinfo_result = result;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we only use this for UDP sockets */
|
||||||
|
s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
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);
|
||||||
|
ipv6pktinfo_result = ISC_R_UNEXPECTED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef IPV6_RECVPKTINFO
|
||||||
|
optname = IPV6_RECVPKTINFO;
|
||||||
|
#else
|
||||||
|
optname = IPV6_PKTINFO;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
on = 1;
|
||||||
|
if (setsockopt(s, IPPROTO_IPV6, optname, &on, sizeof(on)) < 0) {
|
||||||
|
ipv6pktinfo_result = ISC_R_NOTFOUND;
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(s);
|
||||||
|
ipv6pktinfo_result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
|
close:
|
||||||
|
close(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
initialize_ipv6pktinfo(void) {
|
||||||
|
RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo,
|
||||||
|
try_ipv6pktinfo) == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
#endif /* WANT_IPV6 */
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_net_probe_ipv6only(void) {
|
isc_net_probe_ipv6only(void) {
|
||||||
@@ -248,6 +303,18 @@ isc_net_probe_ipv6only(void) {
|
|||||||
return (ipv6only_result);
|
return (ipv6only_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_net_probe_ipv6pktinfo(void) {
|
||||||
|
#ifdef ISC_PLATFORM_HAVEIPV6
|
||||||
|
#ifdef WANT_IPV6
|
||||||
|
initialize_ipv6pktinfo();
|
||||||
|
#else
|
||||||
|
ipv6pktinfo_result = ISC_R_NOTFOUND;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return (ipv6pktinfo_result);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
isc_net_disableipv4(void) {
|
isc_net_disableipv4(void) {
|
||||||
initialize();
|
initialize();
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: net.h,v 1.22 2004/04/19 04:16:55 marka Exp $ */
|
/* $Id: net.h,v 1.23 2004/04/29 01:37:14 marka Exp $ */
|
||||||
|
|
||||||
#ifndef ISC_NET_H
|
#ifndef ISC_NET_H
|
||||||
#define ISC_NET_H 1
|
#define ISC_NET_H 1
|
||||||
@@ -270,6 +270,19 @@ isc_net_probe_ipv6only(void);
|
|||||||
* ISC_R_UNEXPECTED
|
* ISC_R_UNEXPECTED
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_net_probe_ipv6pktinfo(void);
|
||||||
|
/*
|
||||||
|
* Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
|
||||||
|
* for UDP sockets.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*
|
||||||
|
* ISC_R_SUCCESS the option is supported.
|
||||||
|
* ISC_R_NOTFOUND IPv6 itself or the option is not supported.
|
||||||
|
* ISC_R_UNEXPECTED
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
isc_net_disableipv4(void);
|
isc_net_disableipv4(void);
|
||||||
|
|
||||||
|
@@ -432,6 +432,7 @@ isc_net_disableipv6
|
|||||||
isc_task_getcurrenttime
|
isc_task_getcurrenttime
|
||||||
isc_net_probe_ipv6only
|
isc_net_probe_ipv6only
|
||||||
isc_timermgr_poke
|
isc_timermgr_poke
|
||||||
|
isc_net_probe_ipv6pktinfo
|
||||||
|
|
||||||
; Exported Data
|
; Exported Data
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: net.c,v 1.9 2004/03/16 05:52:22 marka Exp $ */
|
/* $Id: net.c,v 1.10 2004/04/29 01:37:14 marka Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -36,9 +36,11 @@ const struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT;
|
|||||||
|
|
||||||
static isc_once_t once = ISC_ONCE_INIT;
|
static isc_once_t once = ISC_ONCE_INIT;
|
||||||
static isc_once_t once_ipv6only = ISC_ONCE_INIT;
|
static isc_once_t once_ipv6only = ISC_ONCE_INIT;
|
||||||
|
static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT;
|
||||||
static isc_result_t ipv4_result = ISC_R_NOTFOUND;
|
static isc_result_t ipv4_result = ISC_R_NOTFOUND;
|
||||||
static isc_result_t ipv6_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 ipv6only_result = ISC_R_NOTFOUND;
|
||||||
|
static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND;
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
try_proto(int domain) {
|
try_proto(int domain) {
|
||||||
@@ -218,7 +220,7 @@ try_ipv6only(void) {
|
|||||||
close:
|
close:
|
||||||
close(s);
|
close(s);
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif /* IPV6_V6ONLY */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -226,8 +228,61 @@ initialize_ipv6only(void) {
|
|||||||
RUNTIME_CHECK(isc_once_do(&once_ipv6only,
|
RUNTIME_CHECK(isc_once_do(&once_ipv6only,
|
||||||
try_ipv6only) == ISC_R_SUCCESS);
|
try_ipv6only) == ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
try_ipv6pktinfo(void) {
|
||||||
|
int s, on;
|
||||||
|
char strbuf[ISC_STRERRORSIZE];
|
||||||
|
isc_result_t result;
|
||||||
|
int optname;
|
||||||
|
|
||||||
|
result = isc_net_probeipv6();
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
ipv6pktinfo_result = result;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we only use this for UDP sockets */
|
||||||
|
s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
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);
|
||||||
|
ipv6pktinfo_result = ISC_R_UNEXPECTED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef IPV6_RECVPKTINFO
|
||||||
|
optname = IPV6_RECVPKTINFO;
|
||||||
|
#else
|
||||||
|
optname = IPV6_PKTINFO;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
on = 1;
|
||||||
|
if (setsockopt(s, IPPROTO_IPV6, optname, &on, sizeof(on)) < 0) {
|
||||||
|
ipv6pktinfo_result = ISC_R_NOTFOUND;
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(s);
|
||||||
|
ipv6pktinfo_result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
|
close:
|
||||||
|
close(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
initialize_ipv6pktinfo(void) {
|
||||||
|
RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo,
|
||||||
|
try_ipv6pktinfo) == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
#endif /* WANT_IPV6 */
|
||||||
|
#endif /* ISC_PLATFORM_HAVEIPV6 */
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_net_probe_ipv6only(void) {
|
isc_net_probe_ipv6only(void) {
|
||||||
@@ -241,6 +296,18 @@ isc_net_probe_ipv6only(void) {
|
|||||||
return (ipv6only_result);
|
return (ipv6only_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_net_probe_ipv6pktinfo(void) {
|
||||||
|
#ifdef ISC_PLATFORM_HAVEIPV6
|
||||||
|
#ifdef WANT_IPV6
|
||||||
|
initialize_ipv6pktinfo();
|
||||||
|
#else
|
||||||
|
ipv6pktinfo_result = ISC_R_NOTFOUND;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return (ipv6pktinfo_result);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
isc_net_disableipv4(void) {
|
isc_net_disableipv4(void) {
|
||||||
initialize();
|
initialize();
|
||||||
|
Reference in New Issue
Block a user