]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4440. [func] Enable TCP fast open support when available on the
authorMark Andrews <marka@isc.org>
Fri, 12 Aug 2016 05:31:33 +0000 (15:31 +1000)
committerMark Andrews <marka@isc.org>
Fri, 12 Aug 2016 05:31:33 +0000 (15:31 +1000)
                        server side. [RT #42866]

CHANGES
configure
configure.in
doc/misc/tcp-fast-open [new file with mode: 0644]
lib/isc/include/isc/platform.h.in
lib/isc/unix/socket.c
lib/isc/win32/include/isc/platform.h.in
lib/isc/win32/socket.c

diff --git a/CHANGES b/CHANGES
index 2e557ae642e477c676d72ea6afeda0aa53ab9888..f961844ff14024d641697445e049dc7c4de3356c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+4440.  [func]          Enable TCP fast open support when available on the
+                       server side. [RT #42866]
+
 4439.  [bug]           Address race conditions getting ownernames of nodes.
                        [RT #43005]
 
index 09227423fba7f289f25079f100682e5dddf58c1c..05a64a96004d1cd974ffecff5d5befee31956672 100755 (executable)
--- a/configure
+++ b/configure
@@ -761,6 +761,7 @@ ISC_LWRES_SETHOSTENTINT
 ISC_LWRES_NEEDRRSETINFO
 ISC_IRS_NEEDADDRINFO
 ISC_LWRES_NEEDADDRINFO
+ISC_PLATFORM_HAVETFO
 ISC_PLATFORM_NEEDPORTT
 ISC_PLATFORM_MSGHDRFLAVOR
 LWRES_PLATFORM_HAVESALEN
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 
+#
+# Look for TCP_FASTOPEN
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for TCP_FASTOPEN socket option" >&5
+$as_echo_n "checking for TCP_FASTOPEN socket option... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+#ifdef TCP_FASTOPEN
+int has_tfo() { return (0); }
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "has_tfo" >/dev/null 2>&1; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       ISC_PLATFORM_HAVETFO="#define ISC_PLATFORM_HAVETFO 1"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+       ISC_PLATFORM_HAVETFO="#undef ISC_PLATFORM_HAVETFO"
+fi
+rm -f conftest*
+
+
+
 #
 # Check for addrinfo
 #
index d3509c0a3b9818441e9ca994403982d102ff154b..c3696d0c7b31accefad680d19b20ada681a7051c 100644 (file)
@@ -3107,6 +3107,24 @@ AC_TRY_COMPILE([
        ISC_PLATFORM_NEEDPORTT="#define ISC_PLATFORM_NEEDPORTT 1"])
 AC_SUBST(ISC_PLATFORM_NEEDPORTT)
 
+#
+# Look for TCP_FASTOPEN
+#
+AC_MSG_CHECKING(for TCP_FASTOPEN socket option)
+AC_EGREP_CPP(has_tfo, [
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+#ifdef TCP_FASTOPEN
+int has_tfo() { return (0); }
+#endif
+],
+       [AC_MSG_RESULT(yes)
+       ISC_PLATFORM_HAVETFO="#define ISC_PLATFORM_HAVETFO 1"],
+       [AC_MSG_RESULT(no)
+       ISC_PLATFORM_HAVETFO="#undef ISC_PLATFORM_HAVETFO"])
+AC_SUBST(ISC_PLATFORM_HAVETFO)
+
 #
 # Check for addrinfo
 #
diff --git a/doc/misc/tcp-fast-open b/doc/misc/tcp-fast-open
new file mode 100644 (file)
index 0000000..a102706
--- /dev/null
@@ -0,0 +1,27 @@
+Copyright (C) 2016  Internet Systems Consortium, Inc. ("ISC")
+
+This Source Code Form is subject to the terms of the Mozilla Public
+License, v. 2.0. If a copy of the MPL was not distributed with this
+file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+Some systems (Linux, FreeBSD, OS X/macOS and Windows 10) support
+the TCP Fast Open (RFC 7413) mechanism in their recent versions.
+
+BIND 9 supports this on the server side.
+
+When the TCP_FASTOPEN socket option is defined after the listen()
+system call the socket code in the libisc set the option with
+the half of the listen backlog (so the fast open maximum queue length
+is the half of the pending connection queue length).
+Any failure is logged and ignored.
+
+System specific notes:
+ - FreeBSD doesn't interpret the argument as a queue length but
+  only as an on/off switch.
+
+ - Apple OS X/macOS allows only 0 or 1 so the code puts 1 for this system.
+
+ - Windows 10 uses a 0/1 char flag and perhaps as not yet server support?
+
+ - the only other system known to support this is Linux.
+
index 82d02249bf919e215dda18e19099efe2c97a8020..24b61db1f05bffb80d879f1674b25816cc8e10e1 100644 (file)
  */
 @ISC_PLATFORM_HAVESOCKADDRSTORAGE@
 
+/*! \brief
+ * Define if the system has TCP_FASTOPEN socket option.
+ */
+@ISC_PLATFORM_HAVETFO@
+
 /*! \brief
  * Define if the system supports kqueue multiplexing
  */
index cef85fa86bedec2287290421fb2334155c13e563..dbc981062c162b3813be3ecb752941c5e5fa95e6 100644 (file)
 #include <sys/utsname.h>
 #endif
 
+#ifdef ISC_PLATFORM_HAVETFO
+#include <netinet/tcp.h>
+#endif
+
 /*%
  * Choose the most preferable multiplex method.
  */
@@ -5648,6 +5652,24 @@ isc__socket_listen(isc_socket_t *sock0, unsigned int backlog) {
                return (ISC_R_UNEXPECTED);
        }
 
+#if defined(ISC_PLATFORM_HAVETFO) && defined(TCP_FASTOPEN)
+#ifdef __APPLE__
+       backlog = 1;
+#else
+       backlog = backlog / 2;
+       if (backlog == 0)
+               backlog = 1;
+#endif
+       if (setsockopt(sock->fd, IPPROTO_TCP, TCP_FASTOPEN,
+                      (void *)&backlog, sizeof(backlog)) < 0) {
+               isc__strerror(errno, strbuf, sizeof(strbuf));
+               UNEXPECTED_ERROR(__FILE__, __LINE__,
+                                "setsockopt(%d, TCP_FASTOPEN) failed with %s",
+                                sock->fd, strbuf);
+               /* TCP_FASTOPEN is experimental so ignore failures */
+       }
+#endif
+
        sock->listener = 1;
 
        UNLOCK(&sock->lock);
index eea9a3e74ee5323b307a81b3c033ecabef42e80b..ac9b5e205d66a05dea2226795b7115518cd45f36 100644 (file)
@@ -31,6 +31,9 @@
 #define ISC_PLATFORM_NEEDNTOP
 #define ISC_PLATFORM_NEEDPTON
 #define ISC_PLATFORM_HAVESOCKADDRSTORAGE
+#ifdef _MSC_VER >= 1900
+#define ISC_PLATFORM_HAVETFO
+#endif
 
 #define ISC_PLATFORM_QUADFORMAT "I64"
 
index 3eee2f5c990a15e04a51d01a2149056b5f001d1c..d4d158d60a83fe3d3941b23e7b8585f5e2dc8ace 100644 (file)
@@ -3319,6 +3319,9 @@ isc__socket_filter(isc_socket_t *sock, const char *filter) {
 isc_result_t
 isc__socket_listen(isc_socket_t *sock, unsigned int backlog) {
        char strbuf[ISC_STRERRORSIZE];
+#if defined(ISC_PLATFORM_HAVETFO) && defined(TCP_FASTOPEN)
+       char on = 1;
+#endif
 
        REQUIRE(VALID_SOCKET(sock));
 
@@ -3349,6 +3352,17 @@ isc__socket_listen(isc_socket_t *sock, unsigned int backlog) {
                return (ISC_R_UNEXPECTED);
        }
 
+#if defined(ISC_PLATFORM_HAVETFO) && defined(TCP_FASTOPEN)
+       if (setsockopt(sock->fd, IPPROTO_TCP, TCP_FASTOPEN,
+                      &on, sizeof(on)) < 0) {
+               isc__strerror(errno, strbuf, sizeof(strbuf));
+               UNEXPECTED_ERROR(__FILE__, __LINE__,
+                                "setsockopt(%d, TCP_FASTOPEN) failed with %s",
+                                sock->fd, strbuf);
+               /* TCP_FASTOPEN is experimental so ignore failures */
+       }
+#endif
+
        socket_log(__LINE__, sock, NULL, TRACE,
                   isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_BOUND, "listening");
        sock->listener = 1;