]> 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>
Tue, 11 Jul 2017 01:42:43 +0000 (11:42 +1000)
                        will not fit into a single IPv4 encapsulated IPv6
                        UDP packet when transmitted over a Ethernet link.
                        [RT #42871]

(cherry picked from commit 31ffec154117cd33d8b300ec8ac9cddfe83cbb68)

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

diff --git a/CHANGES b/CHANGES
index d24462003f56065ba5a76adc35440793b7b86e7d..e8f163a8513236fdc92974ca0fb87d27f2f63d46 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,10 @@
        --- 9.9.11rc1 released ---
 
+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]
+
 4647.  [bug]           Change 4643 broke verification of TSIG signed TCP
                        message sequences where not all the messages contain
                        TSIG records.  These may be used in AXFR and IXFR
index 1d7ee5de2407cb911530163a78877bfacdefe621..e541edc6c1f6fd0b1bb9d246cfaf7f07066d9da1 100644 (file)
@@ -859,6 +859,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 0ee305c894b4b4c956d5ea722f7281ce893313c1..4916674a8c635c2eeb095727334ac9554f0674ab 100644 (file)
@@ -196,6 +196,7 @@ struct isc_socket_connev {
  * _TIMESTAMP: The timestamp member is valid.
  * _PKTINFO:   The pktinfo member is valid.
  * _MULTICAST: The UDP packet was received via a multicast transmission.
+ * _USEMINMTU: Set the per packet IPV6_USE_MIN_MTU flag.
  */
 #define ISC_SOCKEVENTATTR_ATTACHED             0x80000000U /* internal */
 #define ISC_SOCKEVENTATTR_TRUNC                        0x00800000U /* public */
@@ -203,6 +204,7 @@ struct isc_socket_connev {
 #define ISC_SOCKEVENTATTR_TIMESTAMP            0x00200000U /* public */
 #define ISC_SOCKEVENTATTR_PKTINFO              0x00100000U /* public */
 #define ISC_SOCKEVENTATTR_MULTICAST            0x00080000U /* public */
+#define ISC_SOCKEVENTATTR_USEMINMTU            0x00020000U /* public */
 /*@}*/
 
 #define ISC_SOCKEVENT_ANYEVENT  (0)
index 05dec9fda799ae0bf5933ad903fea22f1c0781cd..2d89f191bdbb1dd4eb6c6fbbe49c8bf0f84041b8 100644 (file)
@@ -15,8 +15,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id$ */
-
 /*! \file */
 
 #include <config.h>
@@ -1344,6 +1342,9 @@ build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev,
        isc_region_t used;
        size_t write_count;
        size_t skip_count;
+#ifdef ISC_NET_BSD44MSGHDR
+       struct cmsghdr *cmsgp;
+#endif
 
        memset(msg, 0, sizeof(*msg));
 
@@ -1410,13 +1411,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
-               struct cmsghdr *cmsgp;
+#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,
@@ -1434,12 +1434,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));
@@ -1449,9 +1452,10 @@ 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 /* USE_CMSG && ISC_PLATFORM_HAVEIPV6 */
+#endif
+
+#endif /* USE_CMSG */
 #else /* ISC_NET_BSD44MSGHDR */
        msg->msg_accrights = NULL;
        msg->msg_accrightslen = 0;
@@ -2481,8 +2485,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 && sock->pf == AF_INET6) {
+               use_min_mtu(sock);
                set_tcp_maxseg(sock, 1280 - 20 - 40); /* 1280 - TCP - IPV6 */
        }