2
0
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:
Mark Andrews
2004-04-29 01:37:14 +00:00
parent 08b40678f3
commit cc32d38366
9 changed files with 230 additions and 31 deletions

View File

@@ -15,7 +15,7 @@
* 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
#define ISC_NET_H 1
@@ -270,6 +270,19 @@ isc_net_probe_ipv6only(void);
* 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
isc_net_disableipv4(void);

View File

@@ -432,6 +432,7 @@ isc_net_disableipv6
isc_task_getcurrenttime
isc_net_probe_ipv6only
isc_timermgr_poke
isc_net_probe_ipv6pktinfo
; Exported Data

View File

@@ -15,7 +15,7 @@
* 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>
@@ -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_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 ipv6_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
try_proto(int domain) {
@@ -218,7 +220,7 @@ try_ipv6only(void) {
close:
close(s);
return;
#endif
#endif /* IPV6_V6ONLY */
}
static void
@@ -226,8 +228,61 @@ initialize_ipv6only(void) {
RUNTIME_CHECK(isc_once_do(&once_ipv6only,
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
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_net_probe_ipv6only(void) {
@@ -241,6 +296,18 @@ isc_net_probe_ipv6only(void) {
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
isc_net_disableipv4(void) {
initialize();