# HG changeset patch # User Anthony Doeraene <anthony.doeraene....@gmail.com> # Date 1723532563 -7200 # Tue Aug 13 09:02:43 2024 +0200 # Node ID 3bc05b0a87ba68fc436444294f7ec1529a13c10e # Parent 19780d9b772a8b7192c20fc0fe7890dd381f0cce 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-developed-by: Maxime Dourov <mu...@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] diff -r 19780d9b772a -r 3bc05b0a87ba src/stream/ngx_stream.c --- a/src/stream/ngx_stream.c Tue Aug 13 08:59:41 2024 +0200 +++ b/src/stream/ngx_stream.c Tue Aug 13 09:02:43 2024 +0200 @@ -486,6 +486,7 @@ ls->handler = ngx_stream_init_connection; ls->pool_size = 256; ls->type = addr[i].opt.type; + ls->protocol = addr[i].opt.protocol; cscf = addr->opt.ctx->srv_conf[ngx_stream_core_module.ctx_index]; diff -r 19780d9b772a -r 3bc05b0a87ba src/stream/ngx_stream.h --- a/src/stream/ngx_stream.h Tue Aug 13 08:59:41 2024 +0200 +++ b/src/stream/ngx_stream.h Tue Aug 13 09:02:43 2024 +0200 @@ -69,6 +69,7 @@ int fastopen; #endif int type; + int protocol; } ngx_stream_listen_t; diff -r 19780d9b772a -r 3bc05b0a87ba src/stream/ngx_stream_core_module.c --- a/src/stream/ngx_stream_core_module.c Tue Aug 13 08:59:41 2024 +0200 +++ b/src/stream/ngx_stream_core_module.c Tue Aug 13 09:02:43 2024 +0200 @@ -654,6 +654,13 @@ } #endif +#ifdef IPPROTO_MPTCP + if (ngx_strcmp(value[i].data, "multipath") == 0) { + ls->protocol = IPPROTO_MPTCP; + continue; + } +#endif + if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) { ls->backlog = ngx_atoi(value[i].data + 8, value[i].len - 8); ls->bind = 1; @@ -886,6 +893,12 @@ #endif } +#ifdef IPPROTO_MPTCP + if (ls->protocol == IPPROTO_MPTCP) { + return "\"multipath\" parameter is incompatible with \"udp\""; + } +#endif + for (n = 0; n < u.naddrs; n++) { for (i = 0; i < n; i++) {