[PATCH 4 of 4] Stream: added MPTCP support

Dourov Maxime mux99 at live.be
Thu Apr 18 13:57:08 UTC 2024


# HG changeset patch
# User maxime <mux99 at live.be>
# Date 1713355437 -7200
#      Wed Apr 17 14:03:57 2024 +0200
# Node ID e2a045fb5e3f6362b9f62cf2353f9db34e031202
# Parent  f7ea7c665964b50f1ef6f3964c3fce9596afac20
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.

To 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 'mptcp' to the  'listen' directive
in the Stream module.

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 --git a/src/stream/ngx_stream.c b/src/stream/ngx_stream.c
--- a/src/stream/ngx_stream.c
+++ b/src/stream/ngx_stream.c
@@ -1010,6 +1010,7 @@ ngx_stream_add_listening(ngx_conf_t *cf,
     ls->log.handler = ngx_accept_log_error;
 
     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 --git a/src/stream/ngx_stream.h b/src/stream/ngx_stream.h
--- a/src/stream/ngx_stream.h
+++ b/src/stream/ngx_stream.h
@@ -62,6 +62,7 @@ typedef struct {
     int                            rcvbuf;
     int                            sndbuf;
     int                            type;
+    int                            protocol;
 #if (NGX_HAVE_SETFIB)
     int                            setfib;
 #endif
diff --git a/src/stream/ngx_stream_core_module.c b/src/stream/ngx_stream_core_module.c
--- a/src/stream/ngx_stream_core_module.c
+++ b/src/stream/ngx_stream_core_module.c
@@ -9,6 +9,10 @@
 #include <ngx_core.h>
 #include <ngx_stream.h>
 
+#ifndef IPPROTO_MPTCP
+#define IPPROTO_MPTCP 262
+#endif
+
 
 static ngx_uint_t ngx_stream_preread_can_peek(ngx_connection_t *c);
 static ngx_int_t ngx_stream_preread_peek(ngx_stream_session_t *s,
@@ -984,6 +988,13 @@ ngx_stream_core_listen(ngx_conf_t *cf, n
         }
 #endif
 
+#if (NGX_LINUX)
+        if (ngx_strcmp(value[i].data, "mptcp") == 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;
@@ -1250,6 +1261,12 @@ ngx_stream_core_listen(ngx_conf_t *cf, n
         if (lsopt.proxy_protocol) {
             return "\"proxy_protocol\" parameter is incompatible with \"udp\"";
         }
+        
+#if (NGX_LINUX)
+        if (lsopt.protocol == IPPROTO_MPTCP) {
+             return "\"mptcp\" parameter is incompatible with \"udp\"";
+        }
+#endif
     }
 
     for (n = 0; n < u.naddrs; n++) {


More information about the nginx-devel mailing list