2490. [port] aix: work around a kernel bug where IPV6_RECVPKTINFO

is cleared when IPV6_V6ONLY is set. [RT #18785]
This commit is contained in:
Mark Andrews
2008-11-12 04:03:37 +00:00
parent c38075337a
commit 30ff6ca75d
2 changed files with 58 additions and 9 deletions

View File

@@ -1,3 +1,6 @@
2490. [port] aix: work around a kernel bug where IPV6_RECVPKTINFO
is cleared when IPV6_V6ONLY is set. [RT #18785]
2489. [port] solaris: Workaround Solaris's kernel bug about
/dev/poll:
http://bugs.opensolaris.org/view_bug.do?bug_id=6724237

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: socket.c,v 1.207.2.19.2.59 2008/11/08 22:42:56 jinmei Exp $ */
/* $Id: socket.c,v 1.207.2.19.2.60 2008/11/12 04:03:37 marka Exp $ */
#include <config.h>
@@ -475,6 +475,38 @@ socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
}
}
#if defined(_AIX) && defined(ISC_NET_BSD44MSGHDR) && \
defined(USE_CMSG) && defined(IPV6_RECVPKTINFO)
/*
* AIX has a kernel bug where IPV6_RECVPKTINFO gets cleared by
* setting IPV6_V6ONLY.
*/
static void
FIX_IPV6_RECVPKTINFO(isc_socket_t *sock)
{
char strbuf[ISC_STRERRORSIZE];
int on = 1;
if (sock->pf != AF_INET6 || sock->type != isc_sockettype_udp)
return;
if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
(void *)&on, sizeof(on)) < 0) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d, IPV6_RECVPKTINFO) "
"%s: %s", sock->fd,
isc_msgcat_get(isc_msgcat,
ISC_MSGSET_GENERAL,
ISC_MSG_FAILED,
"failed"),
strbuf);
}
}
#else
#define FIX_IPV6_RECVPKTINFO(sock) (void)0
#endif
static inline isc_result_t
watch_fd(isc_socketmgr_t *manager, int fd, int msg) {
isc_result_t result = ISC_R_SUCCESS;
@@ -1255,15 +1287,17 @@ dump_msg(struct msghdr *msg) {
unsigned int i;
printf("MSGHDR %p\n", msg);
printf("\tname %p, namelen %d\n", msg->msg_name, msg->msg_namelen);
printf("\tiov %p, iovlen %d\n", msg->msg_iov, msg->msg_iovlen);
printf("\tname %p, namelen %ld\n", msg->msg_name,
(long) msg->msg_namelen);
printf("\tiov %p, iovlen %ld\n", msg->msg_iov,
(long) msg->msg_iovlen);
for (i = 0; i < (unsigned int)msg->msg_iovlen; i++)
printf("\t\t%d\tbase %p, len %d\n", i,
printf("\t\t%d\tbase %p, len %ld\n", i,
msg->msg_iov[i].iov_base,
msg->msg_iov[i].iov_len);
(long) msg->msg_iov[i].iov_len);
#ifdef ISC_NET_BSD44MSGHDR
printf("\tcontrol %p, controllen %d\n", msg->msg_control,
msg->msg_controllen);
printf("\tcontrol %p, controllen %ld\n", msg->msg_control,
(long) msg->msg_controllen);
#endif
}
#endif
@@ -4656,9 +4690,21 @@ isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
#ifdef IPV6_V6ONLY
if (sock->pf == AF_INET6) {
(void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY,
(void *)&onoff, sizeof(onoff));
if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY,
(void *)&onoff, sizeof(int)) < 0) {
char strbuf[ISC_STRERRORSIZE];
UNEXPECTED_ERROR(__FILE__, __LINE__,
"setsockopt(%d, IPV6_V6ONLY) "
"%s: %s", sock->fd,
isc_msgcat_get(isc_msgcat,
ISC_MSGSET_GENERAL,
ISC_MSG_FAILED,
"failed"),
strbuf);
}
}
FIX_IPV6_RECVPKTINFO(sock); /* AIX */
#endif
}