Since NBD makes several TCP connections (especially if using multi-conn, as you should), it may benefit from using TFO on platforms which support it. This commit simply adds new command line options for enabling and disabling the flag, a way to fetch the default from --dump-plugin, and updates the documentation.
It does not (yet) implement the feature. I found these articles about TFO interesting: https://blog.apnic.net/2021/07/05/tcp-fast-open-not-so-fast/ https://candrews.integralblue.com/2019/03/the-sad-story-of-tcp-fast-open/ --- docs/nbdkit.pod | 23 ++++++++++++++++++++ docs/synopsis.txt | 1 + tests/Makefile.am | 2 ++ server/internal.h | 1 + server/options.h | 4 ++++ server/main.c | 11 ++++++++++ tests/test-tfo-default.sh | 46 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 88 insertions(+) diff --git a/docs/nbdkit.pod b/docs/nbdkit.pod index b088d4ef19..5b7b87741d 100644 --- a/docs/nbdkit.pod +++ b/docs/nbdkit.pod @@ -476,6 +476,29 @@ may require additional permissions, such as starting the server as root or raising the C<RLIMIT_MEMLOCK> (L<ulimit(1)> I<-l>) limit on the process. +=item B<--tfo> + +=item B<--no-tfo> + +Enable or disable TCP fastopen (TFO). When enabled, this allows +faster connections over TCP by omitting part of the TCP 3-way handshake. + +It is not supported for non-IP sockets (like Unix domain sockets). +The platform must also enable TFO. On Linux you must set +sysctl C<net.ipv4.tcp_fastopen> = 1. + +Currently only libnbd E<ge> 1.22 implements client side support +for TCP fastopen. + +The default is not specified and may depend on the platform and +version of nbdkit. You can find the default for the current version +of nbdkit using: + + $ nbdkit --dump-config | grep ^tfo + tfo_default=1 + +(or C<tfo_default=0>). + =item B<-t> THREADS =item B<--threads=>THREADS diff --git a/docs/synopsis.txt b/docs/synopsis.txt index ecbc6d5c50..ad55dc108b 100644 --- a/docs/synopsis.txt +++ b/docs/synopsis.txt @@ -9,6 +9,7 @@ nbdkit [-4|--ipv4-only] [-6|--ipv6-only] [-P|--pidfile PIDFILE] [-p|--port PORT] [--print-uri] [-r|--readonly] [--run 'COMMAND ARGS ...'] [--selinux-label=LABEL] [-s|--single] [--swap] + [--tfo|--no-tfo] [-t|--threads THREADS] [--timeout=TIMEOUT] [--tls=off|on|require] [--tls-certificates=/path/to/certificates] diff --git a/tests/Makefile.am b/tests/Makefile.am index 29c762b636..4bf9a4568f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -312,6 +312,7 @@ TESTS += \ test-timeout.sh \ test-timeout-cancel.sh \ test-keepalive.sh \ + test-tfo-default.sh \ $(NULL) if !IS_WINDOWS TESTS += \ @@ -369,6 +370,7 @@ EXTRA_DIST += \ test-start.sh \ test-stdio.sh \ test-swap.sh \ + test-tfo-default.sh \ test-timeout.sh \ test-timeout.py \ test-timeout-cancel.sh \ diff --git a/server/internal.h b/server/internal.h index fb838c60d8..4413acecfb 100644 --- a/server/internal.h +++ b/server/internal.h @@ -125,6 +125,7 @@ extern const char *service_mode_string (enum service_mode); extern int tcpip_sock_af; extern struct debug_flag *debug_flags; extern const char *export_name; +extern bool fastopen; extern bool foreground; extern const char *ipaddr; extern bool keepalive; diff --git a/server/options.h b/server/options.h index 0bc8207caf..48c37be880 100644 --- a/server/options.h +++ b/server/options.h @@ -43,11 +43,13 @@ enum { DUMP_CONFIG_OPTION, DUMP_PLUGIN_OPTION, EXIT_WITH_PARENT_OPTION, + FASTOPEN_OPTION, FILTER_OPTION, KEEPALIVE_OPTION, LOG_OPTION, LONG_OPTIONS_OPTION, MASK_HANDSHAKE_OPTION, + NO_FASTOPEN_OPTION, NO_MC_OPTION, NO_SR_OPTION, PRINT_URI, @@ -92,6 +94,7 @@ static const struct option long_options[] = { { "no-meta-contexts", no_argument, NULL, NO_MC_OPTION }, { "no-sr", no_argument, NULL, NO_SR_OPTION }, { "no-structured-replies", no_argument, NULL, NO_SR_OPTION }, + { "no-tfo", no_argument, NULL, NO_FASTOPEN_OPTION }, { "old-style", no_argument, NULL, 'o' }, { "oldstyle", no_argument, NULL, 'o' }, { "pid-file", required_argument, NULL, 'P' }, @@ -109,6 +112,7 @@ static const struct option long_options[] = { { "single", no_argument, NULL, 's' }, { "stdin", no_argument, NULL, 's' }, { "swap", no_argument, NULL, SWAP_OPTION }, + { "tfo", no_argument, NULL, FASTOPEN_OPTION }, { "threads", required_argument, NULL, 't' }, { "timeout", required_argument, NULL, TIMEOUT_OPTION }, { "time-out", required_argument, NULL, TIMEOUT_OPTION }, diff --git a/server/main.c b/server/main.c index 0b558698cb..d6e93a67ff 100644 --- a/server/main.c +++ b/server/main.c @@ -80,6 +80,8 @@ #define main fuzzer_main #endif +#define FASTOPEN_DEFAULT 0 + static char *make_random_fifo (void); static struct backend *open_plugin_so (size_t i, const char *filename, int short_name); @@ -96,6 +98,7 @@ int tcpip_sock_af = AF_UNSPEC; /* -4, -6 */ struct debug_flag *debug_flags; /* -D */ bool exit_with_parent; /* --exit-with-parent */ const char *export_name; /* -e */ +bool fastopen = FASTOPEN_DEFAULT; /* --tfo, --no-tfo */ bool foreground; /* -f */ const char *ipaddr; /* -i */ bool keepalive; /* --keepalive */ @@ -224,6 +227,7 @@ dump_config (void) #endif printf ("%s=%s\n", "soext", SOEXT); printf ("%s=%s\n", "sysconfdir", sysconfdir); + printf ("%s=%d\n", "tfo_default", FASTOPEN_DEFAULT); #ifdef HAVE_GNUTLS printf ("tls=yes\n"); #else @@ -326,6 +330,13 @@ main (int argc, char *argv[]) } break; + case FASTOPEN_OPTION: + fastopen = true; + break; + case NO_FASTOPEN_OPTION: + fastopen = false; + break; + case FILTER_OPTION: { struct filter_filename *t; diff --git a/tests/test-tfo-default.sh b/tests/test-tfo-default.sh new file mode 100755 index 0000000000..7ca35166fe --- /dev/null +++ b/tests/test-tfo-default.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# nbdkit +# Copyright Red Hat +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Red Hat nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +# Test the --dump-plugin / tfo_default setting. + +source ./functions.sh +set -e +set -x + +out=tfo-default.out +rm -f $out +cleanup_fn rm -f $out + +nbdkit --dump-config > $out +# Check the key is present and the format is correct. We do +# not know what the default will be. +grep "^tfo_default=[01]$" $out -- 2.46.0 _______________________________________________ Libguestfs mailing list -- guestfs@lists.libguestfs.org To unsubscribe send an email to guestfs-le...@lists.libguestfs.org