[PATCH 2 of 4] HTTP: added MPTCP support

Anthony Doeraene anthony.doeraene.dev at gmail.com
Tue Aug 13 09:37:04 UTC 2024


# HG changeset patch
# User Anthony Doeraene <anthony.doeraene.dev at gmail.com>
# Date 1723532143 -7200
#      Tue Aug 13 08:55:43 2024 +0200
# Node ID d5b3c722c6796f5b163821b9a8402457420ade4a
# Parent  b72362042b52f378e18ff6d01ec533e447331214
HTTP: 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 HTTP module. This new parameter is only compatible with TCP if
IPPROTO_MPTCP is defined, not with QUIC so far.

Co-developed-by: Maxime Dourov <mux99 at 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 b72362042b52 -r d5b3c722c679 contrib/vim/syntax/nginx.vim
--- a/contrib/vim/syntax/nginx.vim	Tue Aug 13 08:50:15 2024 +0200
+++ b/contrib/vim/syntax/nginx.vim	Tue Aug 13 08:55:43 2024 +0200
@@ -65,7 +65,7 @@
     \ contained
     \ nextgroup=@ngxListenParams skipwhite skipempty
 syn keyword ngxListenOptions contained
-    \ default_server ssl quic proxy_protocol
+    \ default_server ssl quic proxy_protocol multipath
     \ setfib fastopen backlog rcvbuf sndbuf accept_filter deferred bind
     \ ipv6only reuseport so_keepalive
     \ nextgroup=@ngxListenParams skipwhite skipempty
diff -r b72362042b52 -r d5b3c722c679 src/http/ngx_http.c
--- a/src/http/ngx_http.c	Tue Aug 13 08:50:15 2024 +0200
+++ b/src/http/ngx_http.c	Tue Aug 13 08:55:43 2024 +0200
@@ -1845,6 +1845,7 @@
 #endif
 
     ls->type = addr->opt.type;
+    ls->protocol = addr->opt.protocol;
     ls->backlog = addr->opt.backlog;
     ls->rcvbuf = addr->opt.rcvbuf;
     ls->sndbuf = addr->opt.sndbuf;
diff -r b72362042b52 -r d5b3c722c679 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c	Tue Aug 13 08:50:15 2024 +0200
+++ b/src/http/ngx_http_core_module.c	Tue Aug 13 08:55:43 2024 +0200
@@ -4062,6 +4062,13 @@
         }
 #endif
 
+#ifdef IPPROTO_MPTCP
+        if (ngx_strcmp(value[n].data, "multipath") == 0) {
+            lsopt.protocol = IPPROTO_MPTCP;
+            continue;
+        }
+#endif
+
         if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
             lsopt.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
             lsopt.set = 1;
@@ -4351,6 +4358,12 @@
         }
 #endif
 
+#ifdef IPPROTO_MPTCP
+        if (lsopt.protocol == IPPROTO_MPTCP) {
+             return "\"multipath\" parameter is incompatible with \"quic\"";
+        }
+#endif
+
 #if (NGX_HTTP_V2)
         if (lsopt.http2) {
             return "\"http2\" parameter is incompatible with \"quic\"";
diff -r b72362042b52 -r d5b3c722c679 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h	Tue Aug 13 08:50:15 2024 +0200
+++ b/src/http/ngx_http_core_module.h	Tue Aug 13 08:55:43 2024 +0200
@@ -88,6 +88,7 @@
     int                        rcvbuf;
     int                        sndbuf;
     int                        type;
+    int                        protocol;
 #if (NGX_HAVE_SETFIB)
     int                        setfib;
 #endif



More information about the nginx-devel mailing list