]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2490. [port] aix: work around a kernel bug where IPV6_RECVPKTINFO
authorMark Andrews <marka@isc.org>
Wed, 12 Nov 2008 03:58:36 +0000 (03:58 +0000)
committerMark Andrews <marka@isc.org>
Wed, 12 Nov 2008 03:58:36 +0000 (03:58 +0000)
                        is cleared when IPV6_V6ONLY is set. [RT #18785]

CHANGES
lib/isc/unix/socket.c

diff --git a/CHANGES b/CHANGES
index c4b8a663497f3d2a1a80eedbb5f4d43e1a80ffe3..e3794b29dc6b2c18aca020dbc95403761ddcc7cb 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -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
index a2a535f9b24571f2c6391fae1321d8b3c895b2d2..32396148ae02b2b3ad5b624e2bdaef19221215e3 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.c,v 1.237.18.55 2008/11/08 22:40:39 jinmei Exp $ */
+/* $Id: socket.c,v 1.237.18.56 2008/11/12 03:58:36 marka Exp $ */
 
 /*! \file */
 
@@ -484,6 +484,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;
@@ -1275,15 +1307,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
@@ -4865,9 +4899,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
 }