Report information
The Basics
Id:
44754
Status:
resolved
Priority:
Medium/Medium
Queue:

BugTracker
Version Fixed:
9.10.7(sub), 9.11.3, 9.12.0
Version Found:
(no value)
Versions Affected:
(no value)
Versions Planned:
(no value)
Priority:
P2 Normal
Severity:
S3 Low
CVSS Score:
(no value)
CVE ID:
(no value)
Component:
BIND Server
Area:
server

Dates
Created:Fri, 24 Feb 2017 09:43:26 -0500
Updated:Mon, 18 Sep 2017 23:09:03 -0400
Closed:Mon, 18 Sep 2017 23:09:03 -0400



This bug tracker is no longer active.

Please go to our Gitlab to submit issues (both feature requests and bug reports) for active projects maintained by Internet Systems Consortium (ISC).

Due to security and confidentiality requirements, full access is limited to the primary maintainers.

Subject: TCP_FASTOPEN, again.
Date: Fri, 24 Feb 2017 15:43:14 +0100
To: bind9-bugs@isc.org
From: "Mathieu Arnold" <mat@FreeBSD.org>
Subject: TCP_FASTOPEN, again.
To: bind9-bugs@isc.org
From: "Mathieu Arnold" <mat@FreeBSD.org>
Hi, It seems users are quite keen on not having anything in their logs, as the people in the threads quoted in this PR https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=217288 are saying. Maybe the "error" message could be less "hey, it's broken" and more "everything is fine but this bit won't work". I don't know. Anyway, thanks :-) -- Mathieu Arnold

Message body not shown because it is not plain text.

On Fri Feb 24 14:43:26 2017, mat@FreeBSD.org wrote: > It seems users are quite keen on not having anything in their logs, as > the people in the threads quoted in this PR > https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=217288 are saying. > > > Maybe the "error" message could be less "hey, it's broken" and more > "everything is fine but this bit won't work". I don't know. => It seems to change the error/warning message or to add a configure option won't be enough (for the first users want no message, for the second they use packages). My only idea is to add a FreeBSD specific code which checks if the TCP_FASTOPEN feature was enabled: - the service socket is opened at start up so there is no need to handle system configuration changes - sysctl should provide the required information - I have used FreeBSD since more than 20 years (I can remember 2.x versions) - unfortunately the new release will be published soon so this will be at least for the next one... Thanks
Subject: Re: [ISC-Bugs #44754] TCP_FASTOPEN, again.
Date: Mon, 27 Feb 2017 15:11:30 +1100
To: bind9-bugs@isc.org
From: "Mark Andrews" <marka@isc.org>
In message <rt-4.2.8-38168-1487947406-1820.44754-3-0@isc.org>, "Mathieu Arnold via RT" writes: > Hi, > > It seems users are quite keen on not having anything in their logs, as > the people in the threads quoted in this PR > https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=217288 are saying. > > Maybe the "error" message could be less "hey, it's broken" and more > "everything is fine but this bit won't work". I don't know. > > Anyway, thanks :-) > > -- > Mathieu Arnold I actually think that FreeBSD is doing a dis-service by defaulting FASTOPEN off. It already requires applications to take explict steps to enable it for incoming connections. That is a big enough hurdle. Mark -- Mark Andrews, ISC 1 Seymour St., Dundas Valley, NSW 2117, Australia PHONE: +61 2 9871 4742 INTERNET: marka@isc.org
I agree with Mark, as of today enabling TCP Fast Open for a listening socket on FreeBSD requires compiling a custom kernel, tuning a sysctl value *and* an explicit setsockopt() call. That being said, the current state of things causes confusion for users and thus there is room for improvement. I implemented two things in rt44754: - an additional sysctl-based runtime check for TCP Fast Open support on FreeBSD, as suggested by Francis, which logs a one-time notice if TCP Fast Open support is available, but disabled by sysctl, - a configure option to forcibly disable TCP Fast Open support, as suggested in #45376. Thanks to the above: - BIND will no longer log setsockopt() errors when running on FreeBSD kernels completely lacking TCP Fast Open support. - BIND will only notify the user once that it is running on a FreeBSD kernel with TCP Fast Open support available, but disabled via sysctl. - BIND will still generate a proper error message when TCP Fast Open is available and enabled, but setsockopt() fails. - If at some point in the future FreeBSD decides to enable TCP Fast Open support by default, neither we nor BIND packagers will have to do anything in order for BIND to start using it. - If any other OS out there turns out to suffer from similar issues, we will have a ready-to-use compile-time workaround. Any thoughts on this are welcome.
On Tue Aug 22 13:48:56 2017, michal wrote: > I implemented two things in rt44754: > > - an additional sysctl-based runtime check for TCP Fast Open support > on FreeBSD, as suggested by Francis, which logs a one-time notice if > TCP Fast Open support is available, but disabled by sysctl, => seems good but it needs to be check on FreeBSD (I have a FreeBSD VM if required but IMHO the best should be to ask the reporter...). > - a configure option to forcibly disable TCP Fast Open support, as > suggested in #45376. => s/autodetect/auto/ (mostly to be consistent with similar existing options). Note you did not regenerate configure.
> On Tue Aug 22 13:48:56 2017, michal wrote: > > I implemented two things in rt44754: > > > > - an additional sysctl-based runtime check for TCP Fast Open support > > on FreeBSD, as suggested by Francis, which logs a one-time notice if > > TCP Fast Open support is available, but disabled by sysctl, > > => seems good but it needs to be check on FreeBSD (I have a FreeBSD VM > if required but IMHO the best should be to ask the reporter...). I checked it on a FreeBSD VM before submitting, but I agree it would be best if Mathieu reviewed it as well. Mathieu, if we send you a patch, would you be willing to test it? > > - a configure option to forcibly disable TCP Fast Open support, as > > suggested in #45376. > > => s/autodetect/auto/ (mostly to be consistent with similar existing options). Well, we are hardly consistent in this regard. In fact, current master has two --enable-* options with "default=autodetect" (--enable-atomic, --enable-ipv6) and just one with "default=auto" (--enable-epoll). "auto" is only used as an implicit default value for --with-* options when they are not specified on the ./configure command line. That being said, I am happy to open another ticket to make the default values consistent. > Note you did not regenerate configure. Well, yes, as it should be automatically regenerated upon a git push which involves configure.in. See "git log --grep regen configure".
Date: Fri, 1 Sep 2017 10:05:00 +0200
Subject: Re: [ISC-Bugs #44754] TCP_FASTOPEN, again.
To: bind9-public@isc.org
From: "Mathieu Arnold" <mat@FreeBSD.org>
Le 01/09/2017 à 09:09, Michał Kępień via RT a écrit : >> On Tue Aug 22 13:48:56 2017, michal wrote: >>> I implemented two things in rt44754: >>> >>> - an additional sysctl-based runtime check for TCP Fast Open support >>> on FreeBSD, as suggested by Francis, which logs a one-time notice if >>> TCP Fast Open support is available, but disabled by sysctl, >> => seems good but it needs to be check on FreeBSD (I have a FreeBSD VM >> if required but IMHO the best should be to ask the reporter...). > I checked it on a FreeBSD VM before submitting, but I agree it would be > best if Mathieu reviewed it as well. > > Mathieu, if we send you a patch, would you be willing to test it? Of course. >>> - a configure option to forcibly disable TCP Fast Open support, as >>> suggested in #45376. >> => s/autodetect/auto/ (mostly to be consistent with similar existing options). > Well, we are hardly consistent in this regard. In fact, current master > has two --enable-* options with "default=autodetect" (--enable-atomic, > --enable-ipv6) and just one with "default=auto" (--enable-epoll). > "auto" is only used as an implicit default value for --with-* options > when they are not specified on the ./configure command line. > > That being said, I am happy to open another ticket to make the default > values consistent. > >> Note you did not regenerate configure. > Well, yes, as it should be automatically regenerated upon a git push > which involves configure.in. See "git log --grep regen configure". > > -- Mathieu Arnold
Mathieu, As the original issue was reported for BIND 9.11, I prepared a patch (attached) which applies cleanly on top of BIND 9.11.2, which is the latest maintenance release in the 9.11 branch. Could you please test it and tell me whether the modified BIND behavior it causes is acceptable to you? If it is, please do not pass the patch on just yet; once it gets merged, I will refer you to the relevant git commit. Just applying the patch and recompiling BIND should be all that is needed for FreeBSD to be handled in a bit more friendly manner. As I mentioned before, the new configure option (--disable-tcp-fastopen) is only there for other systems that we currently do not know of which might exhibit a similar behavior. Thanks!
Subject: bind-9.11.2-freebsd-tcp-fastopen.patch
diff --git a/configure b/configure index e10f5134b9..44eb1d4865 100755 --- a/configure +++ b/configure @@ -1031,6 +1031,7 @@ enable_backtrace enable_symtable enable_ipv6 with_kame +enable_tcp_fastopen enable_getifaddrs with_readline enable_isc_spnego @@ -1714,6 +1715,7 @@ Optional Features: --enable-symtable use internal symbol table for backtrace [all|minimal(default)|none] --enable-ipv6 use IPv6 default=autodetect + --disable-tcp-fastopen disable TCP Fast Open support [default=autodetect] --enable-getifaddrs enable the use of getifaddrs() [yes|no]. --disable-isc-spnego use SPNEGO from GSSAPI library --disable-chroot disable chroot @@ -18565,11 +18567,22 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # -# Look for TCP_FASTOPEN +# Allow forcibly disabling TCP Fast Open support as autodetection might yield +# confusing results on some systems (e.g. FreeBSD; see set_tcp_fastopen() +# comment in lib/isc/unix/socket.c). # + +# Check whether --enable-tcp_fastopen was given. +if test "${enable_tcp_fastopen+set}" = set; then : + enableval=$enable_tcp_fastopen; +fi + + { $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 +case "$enable_tcp_fastopen" in +yes|''|autodetect) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <sys/types.h> @@ -18584,15 +18597,23 @@ 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" + 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" + ISC_PLATFORM_HAVETFO="#undef ISC_PLATFORM_HAVETFO" fi rm -f conftest* + ;; + no) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 +$as_echo "disabled" >&6; } + ISC_PLATFORM_HAVETFO="#undef ISC_PLATFORM_HAVETFO" + ;; +esac + # # Check for addrinfo diff --git a/configure.in b/configure.in index 7886208d6f..cb8061041b 100644 --- a/configure.in +++ b/configure.in @@ -3204,10 +3204,18 @@ AC_TRY_COMPILE([ AC_SUBST(ISC_PLATFORM_NEEDPORTT) # -# Look for TCP_FASTOPEN +# Allow forcibly disabling TCP Fast Open support as autodetection might yield +# confusing results on some systems (e.g. FreeBSD; see set_tcp_fastopen() +# comment in lib/isc/unix/socket.c). # + +AC_ARG_ENABLE(tcp_fastopen, + [ --disable-tcp-fastopen disable TCP Fast Open support [[default=autodetect]]]) + AC_MSG_CHECKING(for TCP_FASTOPEN socket option) -AC_EGREP_CPP(has_tfo, [ +case "$enable_tcp_fastopen" in +yes|''|autodetect) + AC_EGREP_CPP(has_tfo, [ #include <sys/types.h> #include <sys/socket.h> #include <netinet/tcp.h> @@ -3215,10 +3223,17 @@ AC_EGREP_CPP(has_tfo, [ 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_MSG_RESULT(yes) + ISC_PLATFORM_HAVETFO="#define ISC_PLATFORM_HAVETFO 1"], + [AC_MSG_RESULT(no) + ISC_PLATFORM_HAVETFO="#undef ISC_PLATFORM_HAVETFO"]) + + ;; + no) + AC_MSG_RESULT(disabled) + ISC_PLATFORM_HAVETFO="#undef ISC_PLATFORM_HAVETFO" + ;; +esac AC_SUBST(ISC_PLATFORM_HAVETFO) # diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index d820a6df01..25b2464a22 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -14,6 +14,9 @@ #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> +#ifdef HAVE_SYS_SYSCTL_H +#include <sys/sysctl.h> +#endif #include <sys/time.h> #include <sys/uio.h> @@ -5645,6 +5648,69 @@ isc__socket_filter(isc_socket_t *sock0, const char *filter) { #endif } +/* + * Try enabling TCP Fast Open for a given socket if the OS supports it. + */ +static void +set_tcp_fastopen(isc__socket_t *sock, unsigned int backlog) { +#if defined(ISC_PLATFORM_HAVETFO) && defined(TCP_FASTOPEN) + char strbuf[ISC_STRERRORSIZE]; + +/* + * FreeBSD, as of versions 10.3 and 11.0, defines TCP_FASTOPEN while also + * shipping a default kernel without TFO support, so we special-case it by + * performing an additional runtime check for TFO support using sysctl to + * prevent setsockopt() errors from being logged. + */ +#if defined(__FreeBSD__) && defined(HAVE_SYSCTLBYNAME) +#define SYSCTL_TFO "net.inet.tcp.fastopen.enabled" + unsigned int enabled; + size_t enabledlen = sizeof(enabled); + static isc_boolean_t tfo_notice_logged = ISC_FALSE; + + if (sysctlbyname(SYSCTL_TFO, &enabled, &enabledlen, NULL, 0) < 0) { + /* + * This kernel does not support TCP Fast Open. There is + * nothing more we can do. + */ + return; + } else if (enabled == 0) { + /* + * This kernel does support TCP Fast Open, but it is disabled + * by sysctl. Notify the user, but do not nag. + */ + if (!tfo_notice_logged) { + isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, + ISC_LOGMODULE_SOCKET, ISC_LOG_NOTICE, + "TCP_FASTOPEN support is disabled by " + "sysctl (" SYSCTL_TFO " = 0)"); + tfo_notice_logged = ISC_TRUE; + } + return; + } +#endif + +#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 */ + } +#else + UNUSED(sock); + UNUSED(backlog); +#endif +} + /* * Set up to listen on a given socket. We do this by creating an internal * event that will be dispatched when the socket has read activity. The @@ -5681,23 +5747,7 @@ 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 + set_tcp_fastopen(sock, backlog); sock->listener = 1;
Date: Mon, 4 Sep 2017 17:23:16 +0200
Subject: Re: [ISC-Bugs #44754] TCP_FASTOPEN, again.
From: "Mathieu Arnold" <mat@FreeBSD.org>
To: bind9-public@isc.org
Hi, Le 01/09/2017 à 13:01, Michał Kępień via RT a écrit : > As the original issue was reported for BIND 9.11, I prepared a patch > (attached) which applies cleanly on top of BIND 9.11.2, which is the > latest maintenance release in the 9.11 branch. > > Could you please test it and tell me whether the modified BIND behavior > it causes is acceptable to you? If it is, please do not pass the patch > on just yet; once it gets merged, I will refer you to the relevant git > commit. > > Just applying the patch and recompiling BIND should be all that is > needed for FreeBSD to be handled in a bit more friendly manner. As I > mentioned before, the new configure option (--disable-tcp-fastopen) is > only there for other systems that we currently do not know of which > might exhibit a similar behavior. I can confirm that the patch does not break BIND9 and that it still works on my workstation and does not log anything superflous that I can find. I do not have any FreeBSD with a kernel where TCP fastopen is enabled though, so I cannot really test any further. Kind regards, -- Mathieu Arnold
4726. [port] Prevent setsockopt() errors related to TCP_FASTOPEN from being logged on FreeBSD if the kernel does not support it. Notify the user when the kernel does support TCP_FASTOPEN, but it is disabled by sysctl. Add a new configure option, --disable-tcp-fastopen, to disable use of TCP_FASTOPEN altogether. [RT #44754] 9.11.3, 9.12.0