From c2e80cf47ebb1ceecb4ad2ee01191ba2677f6fee Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 1 Nov 2012 08:42:56 +1100 Subject: [PATCH] 3411. [tuning] Use IPV6_USE_MIN_MTU or equivalent with TCP in addition to UDP. [RT #31690] Squashed commit of the following: commit bcbe9ae7a99e1f7f4236a22739a793b51ace8684 Author: Mark Andrews Date: Wed Oct 31 15:10:53 2012 +1100 Use IPV6_USE_MIN_MTU for TCP as well as UDP --- CHANGES | 3 +++ lib/isc/unix/socket.c | 60 +++++++++++++++++++++++------------------- lib/isc/win32/socket.c | 29 ++++++++++++++------ 3 files changed, 57 insertions(+), 35 deletions(-) diff --git a/CHANGES b/CHANGES index 9ea3a70191..becaa95aed 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3411. [tuning] Use IPV6_USE_MIN_MTU or equivalent with TCP in addition + to UDP. [RT #31690] + 3410. [bug] Addressed Coverity warnings. [RT #31626] 3409. [contrib] contrib/dane/mkdane.sh: Tool to generate TLSA RR's diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index ffe7e02f5f..794374ee61 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -2262,6 +2262,28 @@ clear_bsdcompat(void) { } #endif +static void +use_min_mtu(isc__socket_t *sock) { +#ifdef IPV6_USE_MIN_MTU + /* use minimum MTU */ + if (sock->pf == AF_INET6) { + int on = 1; + (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, + (void *)&on, sizeof(on)); + } +#endif +#if defined(IPV6_MTU) + /* + * Use minimum MTU on IPv6 sockets. + */ + if (sock->pf == AF_INET6) { + int mtu = 1280; + (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU, + &mtu, sizeof(mtu)); + } +#endif +} + static isc_result_t opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, isc__socket_t *dup_socket) @@ -2270,7 +2292,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, char strbuf[ISC_STRERRORSIZE]; const char *err = "socket"; int tries = 0; -#if defined(USE_CMSG) || defined(SO_BSDCOMPAT) +#if defined(USE_CMSG) || defined(SO_BSDCOMPAT) || defined(SO_NOSIGPIPE) int on = 1; #endif #if defined(SO_RCVBUF) @@ -2426,6 +2448,11 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, } #endif + /* + * Use minimum mtu if possible. + */ + use_min_mtu(sock); + #if defined(USE_CMSG) || defined(SO_RCVBUF) if (sock->type == isc_sockettype_udp) { @@ -2490,32 +2517,6 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, } #endif /* IPV6_RECVPKTINFO */ #endif /* ISC_PLATFORM_HAVEIN6PKTINFO */ -#ifdef IPV6_USE_MIN_MTU /* RFC 3542, not too common yet*/ - /* use minimum MTU */ - if (sock->pf == AF_INET6 && - setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, - (void *)&on, sizeof(on)) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "setsockopt(%d, IPV6_USE_MIN_MTU) " - "%s: %s", sock->fd, - isc_msgcat_get(isc_msgcat, - ISC_MSGSET_GENERAL, - ISC_MSG_FAILED, - "failed"), - strbuf); - } -#endif -#if defined(IPV6_MTU) - /* - * Use minimum MTU on IPv6 sockets. - */ - if (sock->pf == AF_INET6) { - int mtu = 1280; - (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU, - &mtu, sizeof(mtu)); - } -#endif #if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT) /* * Turn off Path MTU discovery on IPv6/UDP sockets. @@ -3312,6 +3313,11 @@ internal_accept(isc_task_t *me, isc_event_t *ev) { NEWCONNSOCK(dev)->bound = 1; NEWCONNSOCK(dev)->connected = 1; + /* + * Use minimum mtu if possible. + */ + use_min_mtu(NEWCONNSOCK(dev)); + /* * Save away the remote address */ diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index ffcefb0606..1803de4f7b 100644 --- a/lib/isc/win32/socket.c +++ b/lib/isc/win32/socket.c @@ -1431,6 +1431,18 @@ startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes, return (status); } +static void +use_min_mtu(isc__socket_t *sock) { +#ifdef IPV6_USE_MIN_MTU + /* use minimum MTU */ + if (sock->pf == AF_INET6) { + int on = 1; + (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, + (void *)&on, sizeof(on)); + } +#endif +} + static isc_result_t allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, isc_socket_t **socketp) { @@ -1737,6 +1749,10 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, return (result); } + /* + * Use minimum mtu if possible. + */ + use_min_mtu(sock); #if defined(USE_CMSG) || defined(SO_RCVBUF) if (type == isc_sockettype_udp) { @@ -1774,14 +1790,6 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, strbuf); } #endif /* IPV6_RECVPKTINFO */ -#ifdef IPV6_USE_MIN_MTU /*2292bis, not too common yet*/ - /* use minimum MTU */ - if (pf == AF_INET6) { - (void)setsockopt(sock->fd, IPPROTO_IPV6, - IPV6_USE_MIN_MTU, - (char *)&on, sizeof(on)); - } -#endif #endif /* ISC_PLATFORM_HAVEIPV6 */ #endif /* defined(USE_CMSG) */ @@ -2068,6 +2076,11 @@ internal_accept(isc_socket_t *sock, IoCompletionInfo *lpo, int accept_errno) { result = make_nonblock(adev->newsocket->fd); INSIST(result == ISC_R_SUCCESS); + /* + * Use minimum mtu if possible. + */ + use_min_mtu(adev->newsocket); + INSIST(setsockopt(nsock->fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&sock->fd, sizeof(sock->fd)) == 0);