Stream: added MPTCP support.

Multipath TCP (MPTCP), standardized in RFC8684 [1], is a TCP extension
that enables a TCP connection to use different paths.

Multipath TCP has been used for several use cases. On smartphones, MPTCP
enables seamless handovers between cellular and Wi-Fi networks while
preserving Established connections. This use-case is what pushed Apple
to use MPTCP since 2013 in multiple applications [2]. On dual-stack
hosts, Multipath TCP enables the TCP connection to automatically use the
best performing path, either IPv4 or IPv6. If one path fails, MPTCP
automatically uses the other path.

The benefit from MPTCP, both the client and the server have to support
it. Multipath TCP is a backward-compatible TCP extension that is enabled
by default on recent Linux distributions (Debian, Ubuntu, Redhat, ...).
Multipath TCP is included in the Linux kernel since version 5.6 [3].
To use it on Linux, an application must explicitly enable it when
creating the socket. No need to change anything else in the application.

Even if MPTCP is supported by different OS, only Linux supports the
`IPPROTO_MPTCP` protocol, which is why this feature is currently
limited to Linux only.

This patch adds a new parameter 'multipath' to the 'listen' directive
in the Stream module. This new parameter is only compatible with TCP if
IPPROTO_MPTCP is defined, not with QUIC so far.

Co-authored-by: Maxime Dourov <mux99@live.be>

Link: https://www.rfc-editor.org/rfc/rfc8684.html [1]
Link: https://www.tessares.net/apples-mptcp-story-so-far/ [2]
Link: https://www.mptcp.dev [3]
This commit is contained in:
Aperence 2024-09-06 20:35:41 +02:00
parent 8b8e2ed3ef
commit 90f6d08939
No known key found for this signature in database
3 changed files with 15 additions and 0 deletions

View File

@ -1010,6 +1010,7 @@ ngx_stream_add_listening(ngx_conf_t *cf, ngx_stream_conf_addr_t *addr)
ls->log.handler = ngx_accept_log_error;
ls->type = addr->opt.type;
ls->protocol = addr[i].opt.protocol;
ls->backlog = addr->opt.backlog;
ls->rcvbuf = addr->opt.rcvbuf;
ls->sndbuf = addr->opt.sndbuf;

View File

@ -62,6 +62,7 @@ typedef struct {
int rcvbuf;
int sndbuf;
int type;
int protocol;
#if (NGX_HAVE_SETFIB)
int setfib;
#endif

View File

@ -984,6 +984,13 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
#endif
#ifdef IPPROTO_MPTCP
if (ngx_strcmp(value[i].data, "multipath") == 0) {
lsopt.protocol = IPPROTO_MPTCP;
continue;
}
#endif
if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) {
lsopt.backlog = ngx_atoi(value[i].data + 8, value[i].len - 8);
lsopt.set = 1;
@ -1252,6 +1259,12 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
#ifdef IPPROTO_MPTCP
if (lsopt.protocol == IPPROTO_MPTCP) {
return "\"multipath\" parameter is incompatible with \"udp\"";
}
#endif
for (n = 0; n < u.naddrs; n++) {
for (i = 0; i < n; i++) {