diff --git a/CHANGES b/CHANGES index 296fcac1ca..b1b55177a8 100644 --- 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] diff --git a/bin/named/client.c b/bin/named/client.c index 3faf6d2e11..20963eb46f 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -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, diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h index 1acfed5239..d8956740ef 100644 --- a/lib/isc/include/isc/socket.h +++ b/lib/isc/include/isc/socket.h @@ -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) diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index 2496bd1f61..47606b2997 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -6,8 +6,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* $Id$ */ - /*! \file */ #include @@ -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) {