]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4435. [tuning] Only set IPV6_USE_MIN_MTU for UDP when the message
authorMark Andrews <marka@isc.org>
Thu, 11 Aug 2016 23:41:59 +0000 (09:41 +1000)
committerMark Andrews <marka@isc.org>
Thu, 11 Aug 2016 23:41:59 +0000 (09:41 +1000)
                        will not fit into a single IPv4 encapsulated IPv6
                        UDP packet when transmitted over a Ethernet link.
                        [RT #42871]

CHANGES
bin/named/client.c
lib/isc/include/isc/socket.h
lib/isc/unix/socket.c

diff --git a/CHANGES b/CHANGES
index 296fcac1caf0a3b456ee63cc314de5b1d4371510..b1b55177a8f44fa9585b984c137588d3cb449242 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+4435.  [tuning]        Only set IPV6_USE_MIN_MTU for UDP when the message
+                       will not fit into a single IPv4 encapsulated IPv6
+                       UDP packet when transmitted over a Ethernet link.
+                       [RT #42871]
+
 4434.  [protocol]      Return EDNS EXPIRE option for master zones in addition
                        to slave zones. [RT #43008]
 
index 3faf6d2e11b24c5e5556f1581b34037f31186e3c..20963eb46fe5bb6530b54e9c7bce60144d6d2939 100644 (file)
@@ -923,6 +923,15 @@ client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {
 
        isc_buffer_usedregion(buffer, &r);
 
+       /*
+        * If this is a UDP client and the IPv6 packet can't be
+        * encapsulated without generating a PTB on a 1500 octet
+        * MTU link force fragmentation at 1280 if it is a IPv6
+        * response.
+        */
+       if (!TCP_CLIENT(client) && r.length > 1432)
+               client->sendevent->attributes |= ISC_SOCKEVENTATTR_USEMINMTU;
+
        CTRACE("sendto");
 
        result = isc_socket_sendto2(sock, &r, client->task,
index 1acfed5239d4060c9b38908f5d2eb436ac6a4c45..d8956740ef77efb560a5c3f22636649d822c782f 100644 (file)
@@ -251,6 +251,7 @@ struct isc_socket_connev {
  * _PKTINFO:   The pktinfo member is valid.
  * _MULTICAST: The UDP packet was received via a multicast transmission.
  * _DSCP:      The UDP DSCP value is valid.
+ * _USEMINMTU: Set the per packet IPV6_USE_MIN_MTU flag.
  */
 #define ISC_SOCKEVENTATTR_ATTACHED             0x80000000U /* internal */
 #define ISC_SOCKEVENTATTR_TRUNC                        0x00800000U /* public */
@@ -259,6 +260,7 @@ struct isc_socket_connev {
 #define ISC_SOCKEVENTATTR_PKTINFO              0x00100000U /* public */
 #define ISC_SOCKEVENTATTR_MULTICAST            0x00080000U /* public */
 #define ISC_SOCKEVENTATTR_DSCP                 0x00040000U /* public */
+#define ISC_SOCKEVENTATTR_USEMINMTU            0x00020000U /* public */
 /*@}*/
 
 #define ISC_SOCKEVENT_ANYEVENT  (0)
index 2496bd1f6195b91dfb6b94c6061c3584e95284ec..47606b29970c5b7a06cbc0895bdcdab314ba0f39 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id$ */
-
 /*! \file */
 
 #include <config.h>
@@ -1505,12 +1503,12 @@ build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev,
        msg->msg_control = NULL;
        msg->msg_controllen = 0;
        msg->msg_flags = 0;
-#if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIN6PKTINFO)
-       if ((sock->type == isc_sockettype_udp)
-           && ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0)) {
-#if defined(IPV6_USE_MIN_MTU)
-               int use_min_mtu = 1;    /* -1, 0, 1 */
-#endif
+#if defined(USE_CMSG)
+
+#if defined(ISC_PLATFORM_HAVEIN6PKTINFO)
+       if ((sock->type == isc_sockettype_udp) &&
+           ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0))
+       {
                struct in6_pktinfo *pktinfop;
 
                socket_log(sock, NULL, TRACE,
@@ -1528,12 +1526,15 @@ build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev,
                cmsgp->cmsg_len = cmsg_len(sizeof(struct in6_pktinfo));
                pktinfop = (struct in6_pktinfo *)CMSG_DATA(cmsgp);
                memmove(pktinfop, &dev->pktinfo, sizeof(struct in6_pktinfo));
+       } 
+#endif
+
 #if defined(IPV6_USE_MIN_MTU)
-               /*
-                * Set IPV6_USE_MIN_MTU as a per packet option as FreeBSD
-                * ignores setsockopt(IPV6_USE_MIN_MTU) when IPV6_PKTINFO
-                * is used.
-                */
+       if ((sock->type == isc_sockettype_udp) &&
+           ((dev->attributes & ISC_SOCKEVENTATTR_USEMINMTU) != 0))
+       {
+               int use_min_mtu = 1;    /* -1, 0, 1 */
+
                cmsgp = (struct cmsghdr *)(sock->sendcmsgbuf +
                                           msg->msg_controllen);
                msg->msg_controllen += cmsg_space(sizeof(use_min_mtu));
@@ -1543,8 +1544,8 @@ build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev,
                cmsgp->cmsg_type = IPV6_USE_MIN_MTU;
                cmsgp->cmsg_len = cmsg_len(sizeof(use_min_mtu));
                memmove(CMSG_DATA(cmsgp), &use_min_mtu, sizeof(use_min_mtu));
-#endif
        }
+#endif
 
        if (isc_dscp_check_value > -1) {
                if (sock->type == isc_sockettype_udp)
@@ -1622,7 +1623,7 @@ build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev,
                }
 #endif
        }
-#endif /* USE_CMSG && ISC_PLATFORM_HAVEIPV6 */
+#endif /* USE_CMSG */
 #else /* ISC_NET_BSD44MSGHDR */
        msg->msg_accrights = NULL;
        msg->msg_accrightslen = 0;
@@ -2756,7 +2757,8 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
        /*
         * Use minimum mtu if possible.
         */
-       use_min_mtu(sock);
+       if (sock->type == isc_sockettype_tcp)
+               use_min_mtu(sock);
 
 #if defined(USE_CMSG) || defined(SO_RCVBUF)
        if (sock->type == isc_sockettype_udp) {