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 APIs for enabling,
disabling and fetching the flag, 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/libnbd.pod | 3 +++
generator/API.ml | 48 +++++++++++++++++++++++++++++++++++++++++++++---
lib/handle.c | 15 +++++++++++++++
lib/internal.h | 1 +
4 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/docs/libnbd.pod b/docs/libnbd.pod
index af6a10008..0c8027b82 100644
--- a/docs/libnbd.pod
+++ b/docs/libnbd.pod
@@ -770,6 +770,9 @@ If you are issuing multiple in-flight requests (see above) and
limiting the number, then the limit should be applied to each
individual NBD connection.
+If opening multiple connections over TCP, TCP fastopen (TFO)
+may be beneficial in some circumstances. See L<nbd_set_tcp_fastopen(3)>.
+
=head1 ENCRYPTION AND AUTHENTICATION
The NBD protocol and libnbd supports TLS (sometimes incorrectly called
diff --git a/generator/API.ml b/generator/API.ml
index 8ee1843ae..a19e193d0 100644
--- a/generator/API.ml
+++ b/generator/API.ml
@@ -2204,7 +2204,8 @@ "connect_tcp", {
as C<\"nbd\">, or it may be a port number as a string
such as C<\"10809\">.
" ^ blocking_connect_call_description;
- see_also = [Link "aio_connect_tcp"; Link "set_opt_mode"];
+ see_also = [Link "aio_connect_tcp"; Link "set_opt_mode";
+ Link "set_tcp_fastopen"];
};
"connect_socket", {
@@ -2516,7 +2517,7 @@ "can_multi_conn", {
required."
^ non_blocking_test_call_description;
see_also = [SectionLink "Flag calls"; SectionLink "Multi-conn";
- Link "opt_info"];
+ Link "opt_info"; Link "set_tcp_fastopen"];
example = Some "examples/server-flags.c";
};
@@ -3307,7 +3308,8 @@ "aio_connect_tcp", {
Begin connecting to the NBD server listening on C<hostname:port>.
Parameters behave as documented in L<nbd_connect_tcp(3)>.
" ^ async_connect_call_description;
- see_also = [ Link "connect_tcp"; Link "set_opt_mode" ];
+ see_also = [ Link "connect_tcp"; Link "set_opt_mode";
+ Link "set_tcp_fastopen" ];
};
"aio_connect_socket", {
@@ -4335,6 +4337,44 @@ "is_uri", {
see_also = [Link "connect_uri"; Link "aio_connect_uri";
Link "supports_uri"; Link "get_uri"];
};
+
+ "set_tcp_fastopen", {
+ default_call with
+ args = [ Bool "enable" ]; ret = RErr;
+ permitted_states = [ Created ];
+ shortdesc = "enable or disable TCP fastopen (TFO)";
+ longdesc = "\
+Enable or disable TCP fastopen (TFO). You should call this
+before L<nbd_connect_tcp(3)>. 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).
+Furthermore the server must also support TFO, which only
+L<nbdkit(1)> does at the time of writing. There are several
+other restrictions which may prevent TFO from working — see the articles
+linked below. In the case where TFO is not supported, setting this
+flag does nothing.
+
+Note the default is not defined and may vary depending on
+the platform and may change in future. You can read the
+default by opening the handle and calling L<nbd_get_tcp_fastopen(3)>.";
+ see_also = [Link "get_tcp_fastopen";
+ URLLink
"https://blog.apnic.net/2021/07/05/tcp-fast-open-not-so-fast/";
+ URLLink
"https://candrews.integralblue.com/2019/03/the-sad-story-of-tcp-fast-open/"];
+ };
+
+ "get_tcp_fastopen", {
+ default_call with
+ args = []; ret = RBool;
+ may_set_error = false;
+ shortdesc = "get the TCP fastopen (TFO) setting";
+ longdesc = "\
+Get the TCP fastopen (TFO) setting.
+
+Note the default is not defined and may vary depending on
+the platform and may change in future.";
+ see_also = [Link "set_tcp_fastopen"];
+ };
]
(* The first stable version that the symbol appeared in, for
@@ -4514,6 +4554,8 @@ let first_version =
"get_tls_hostname", (1, 22);
"is_uri", (1, 22);
"get_subprocess_pid", (1, 22);
+ "set_tcp_fastopen", (1, 22);
+ "get_tcp_fastopen", (1, 22);
(* These calls are proposed for a future version of libnbd, but
* have not been added to any released version so far.
diff --git a/lib/handle.c b/lib/handle.c
index a263cc4c6..f297b78c3 100644
--- a/lib/handle.c
+++ b/lib/handle.c
@@ -69,6 +69,7 @@ nbd_create (void)
}
h->unique = 1;
+ h->fastopen = false;
h->tls_verify_peer = true;
h->request_eh = true;
h->request_sr = true;
@@ -697,3 +698,17 @@ nbd_unlocked_stats_chunks_received (struct nbd_handle *h)
{
return h->chunks_received;
}
+
+int
+nbd_unlocked_set_tcp_fastopen (struct nbd_handle *h, bool enable)
+{
+ h->fastopen = enable;
+ return 0;
+}
+
+/* NB: may_set_error = false. */
+int
+nbd_unlocked_get_tcp_fastopen (struct nbd_handle *h)
+{
+ return h->fastopen;
+}
diff --git a/lib/internal.h b/lib/internal.h
index d1fc971f0..7e76ee674 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -111,6 +111,7 @@ struct nbd_handle {
char *export_name; /* Export name, never NULL. */
char *sact_name; /* Socket activation name, can be NULL. */
+ bool fastopen; /* TCP fastopen (TFO). */
/* TLS settings. */
int tls; /* 0 = disable, 1 = enable, 2 = require */
--
2.46.0