]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curl: (on linux) add MPTCP support
authorDorian Craps <dorian.craps@student.vinci.be>
Thu, 4 Apr 2024 09:42:50 +0000 (11:42 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 7 Jun 2024 08:54:19 +0000 (10:54 +0200)
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.

This attached patch adds an --mptcp option which allows the creation of
an MPTCP socket instead of TCP on Linux. If Multipath TCP is not
supported on the system, an error will be reported. It is important to
note that if the end server doesn't support MPTCP, the connection will
continue after a seamless fallback to TCP.

Link: https://www.rfc-editor.org/rfc/rfc8684.html
Link: https://www.tessares.net/apples-mptcp-story-so-far/
Link: https://www.mptcp.dev
Co-developed-by: Dorian Craps (@CrapsDorian) <doriancraps@gmail.com>
Co-developed-by: Olivier Bonaventure (@obonaventure) <Olivier.Bonaventure@uclouvain.be>
Co-developed-by: Matthieu Baerts (@matttbe) <matttbe@kernel.org>
Signed-off-by: Dorian Craps <dorian.craps@student.vinci.be>
Closes #13278

12 files changed:
.github/scripts/spellcheck.words
docs/cmdline-opts/Makefile.inc
docs/cmdline-opts/mptcp.md [new file with mode: 0644]
docs/options-in-versions
packages/vms/gnv_link_curl.com
src/Makefile.inc
src/tool_cb_soc.c [new file with mode: 0644]
src/tool_cb_soc.h [new file with mode: 0644]
src/tool_cfgable.h
src/tool_getparam.c
src/tool_listhelp.c
src/tool_operate.c

index 333b128fcba15cfad629476c06ccc37b1f32727c..ff09e286204d581d17ffbdca81fa96faa7ecbca0 100644 (file)
@@ -508,6 +508,7 @@ monospace
 MorphOS
 MPE
 MPL
+MPTCP
 mprintf
 MQTT
 mqtt
@@ -528,6 +529,7 @@ mTLS
 MUA
 multicwd
 multiparts
+multipath
 MultiSSL
 mumbo
 musedev
index 2a8ce0c9fdc45c80c61fc6764015fa0264dd5143..f8e0da680def891a11cb9a78f0a20320c30e12af 100644 (file)
@@ -162,6 +162,7 @@ DPAGES = \
   max-redirs.md \
   max-time.md \
   metalink.md \
+  mptcp.md \
   negotiate.md \
   netrc-file.md \
   netrc-optional.md \
diff --git a/docs/cmdline-opts/mptcp.md b/docs/cmdline-opts/mptcp.md
new file mode 100644 (file)
index 0000000..b9212bb
--- /dev/null
@@ -0,0 +1,41 @@
+---
+c: Copyright (C) Dorian Craps, <dorian.craps@student.vinci.be>
+SPDX-License-Identifier: curl
+Long: mptcp
+Added: 8.9.0
+Help: Enable Multipath TCP
+Category: connection
+Multi: boolean
+See-also:
+  - tcp-fastopen
+Example:
+  - --mptcp $URL
+---
+
+# `--mptcp`
+
+Enables the use of Multipath TCP (MPTCP) for connections. MPTCP is an extension
+to the standard TCP that allows multiple TCP streams over different network
+paths between the same source and destination. This can enhance bandwidth and
+improve reliability by using multiple paths simultaneously.
+
+MPTCP is beneficial in networks where multiple paths exist between clients and
+servers, such as mobile networks where a device may switch between WiFi and
+cellular data or in wired networks with multiple Internet Service Providers.
+
+## Usage
+
+To use MPTCP for your connections, add the `--mptcp` option when using `curl'.
+
+## Requirements
+
+This feature is currently only supported on Linux starting from kernel 5.6. Only
+TCP connections are modified, hence this option does not effect HTTP/3 (QUIC)
+connections.
+
+The server you are connecting to must also support MPTCP. If not, the connection
+seamlessly falls back to TCP.
+
+## Availability
+
+The `--mptcp` option is available starting from `curl` version 8.9.0.
index e1375da5c3f1c44642a40c5e7b918fe61b172690..bdeab85dbf96bc6bed0a5b427b70e96eba68c6e3 100644 (file)
 --max-redirs                         7.5
 --max-time (-m)                      4.0
 --metalink                           7.27.0
+--mptcp                              8.9.0
 --negotiate                          7.10.6
 --netrc (-n)                         4.6
 --netrc-file                         7.21.5
index 247987ae874695e9d13dd82bfcea35f352e9a6a2..552d7d45dd7114e90a101b049cd002d1a358055a 100644 (file)
@@ -400,6 +400,7 @@ $       link'ldebug'/exe=[.src]curl.exe/dsf=[.src]curl.dsf -
            [.src]curl-tool_bname.o, [.src]curl-tool_cb_dbg.o, -
            [.src]curl-tool_cb_hdr.o, [.src]curl-tool_cb_prg.o, -
            [.src]curl-tool_cb_rea.o, [.src]curl-tool_cb_see.o, -
+           [.src]curl-tool_cb_soc.o, -
            [.src]curl-tool_cb_wrt.o, [.src]curl-tool_cfgable.o, -
            [.src]curl-tool_convert.o, [.src]curl-tool_dirhie.o, -
            [.src]curl-tool_doswin.o, [.src]curl-tool_easysrc.o, -
index 92efa2756aff78fa7b778593541829f9e4cedb21..12737735de46727039339f26a5647d2965d2b4bd 100644 (file)
@@ -67,6 +67,7 @@ CURL_CFILES = \
   tool_cb_prg.c \
   tool_cb_rea.c \
   tool_cb_see.c \
+  tool_cb_soc.c \
   tool_cb_wrt.c \
   tool_cfgable.c \
   tool_dirhie.c \
@@ -112,6 +113,7 @@ CURL_HFILES = \
   tool_cb_prg.h \
   tool_cb_rea.h \
   tool_cb_see.h \
+  tool_cb_soc.h \
   tool_cb_wrt.h \
   tool_cfgable.h \
   tool_dirhie.h \
diff --git a/src/tool_cb_soc.c b/src/tool_cb_soc.c
new file mode 100644 (file)
index 0000000..22048ee
--- /dev/null
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h> /* IPPROTO_TCP */
+#endif
+
+#include "tool_cb_soc.h"
+
+/*
+** callback for CURLOPT_OPENSOCKETFUNCTION
+**
+** Notice that only Linux is supported for the moment.
+*/
+
+curl_socket_t tool_socket_open_mptcp_cb(void *clientp,
+                                        curlsocktype purpose,
+                                        struct curl_sockaddr *addr)
+{
+  int protocol = addr->protocol;
+
+  (void)clientp;
+  (void)purpose;
+
+  if(protocol == IPPROTO_TCP)
+#if defined(__linux__)
+#  ifndef IPPROTO_MPTCP
+#  define IPPROTO_MPTCP 262
+#  endif
+    protocol = IPPROTO_MPTCP;
+#else
+    return CURL_SOCKET_BAD;
+#endif
+
+  return socket(addr->family, addr->socktype, protocol);
+}
diff --git a/src/tool_cb_soc.h b/src/tool_cb_soc.h
new file mode 100644 (file)
index 0000000..f02150a
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef HEADER_CURL_TOOL_CB_SOC_H
+#define HEADER_CURL_TOOL_CB_SOC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+/*
+** callback for CURLOPT_OPENSOCKETFUNCTION
+*/
+
+curl_socket_t tool_socket_open_mptcp_cb(void *clientp,
+                                        curlsocktype purpose,
+                                        struct curl_sockaddr *addr);
+
+#endif /* HEADER_CURL_TOOL_CB_SOC_H */
index 27f15055b0a057eed7cd51809ea0e0c4112e8244..7a8e023c506eaf1d3dbeafde36a90d3c5d160eb0 100644 (file)
@@ -293,6 +293,7 @@ struct OperationConfig {
     CLOBBER_NEVER, /* If the file exists, always fail */
     CLOBBER_ALWAYS /* If the file exists, always overwrite it */
   } file_clobber_mode;
+  bool mptcp;                     /* enable MPTCP support */
   struct GlobalConfig *global;
   struct OperationConfig *prev;
   struct OperationConfig *next;   /* Always last in the struct */
index d524f092ebbdb5dd0ef25bac5b455f038473e35f..5b1ced0295757f986a1a8f3a3184b0372a161eff 100644 (file)
@@ -200,6 +200,7 @@ typedef enum {
   C_MAX_REDIRS,
   C_MAX_TIME,
   C_METALINK,
+  C_MPTCP,
   C_NEGOTIATE,
   C_NETRC,
   C_NETRC_FILE,
@@ -484,6 +485,7 @@ static const struct LongShort aliases[]= {
   {"max-redirs",                 ARG_STRG, ' ', C_MAX_REDIRS},
   {"max-time",                   ARG_STRG, 'm', C_MAX_TIME},
   {"metalink",                   ARG_BOOL, ' ', C_METALINK},
+  {"mptcp",                      ARG_BOOL, ' ', C_MPTCP},
   {"negotiate",                  ARG_BOOL, ' ', C_NEGOTIATE},
   {"netrc",                      ARG_BOOL, 'n', C_NETRC},
   {"netrc-file",                 ARG_FILE, ' ', C_NETRC_FILE},
@@ -2851,6 +2853,9 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
         }
       }
       break;
+    case C_MPTCP: /* --mptcp */
+      config->mptcp = TRUE;
+      break;
     default: /* unknown flag */
       err = PARAM_OPTION_UNKNOWN;
       break;
index 250a0c28b380542440f75abfb43bbc9d72adbf0f..e77a9f4c37556087d700e037646f0a706a8ba52c 100644 (file)
@@ -384,6 +384,9 @@ const struct helptxt helptext[] = {
   {"    --metalink",
    "Process given URLs as metalink XML file",
    CURLHELP_MISC},
+  {"    --mptcp",
+   "Enable Multipath TCP",
+   CURLHELP_CONNECTION},
   {"    --negotiate",
    "Use HTTP Negotiate (SPNEGO) authentication",
    CURLHELP_AUTH | CURLHELP_HTTP},
index 471f7833517b5e97329bb0c4d426210a1d6324bf..0f36a08ce86aacdfbae37dd658daede051c1c7e5 100644 (file)
@@ -60,6 +60,7 @@
 #include "tool_cb_prg.h"
 #include "tool_cb_rea.h"
 #include "tool_cb_see.h"
+#include "tool_cb_soc.h"
 #include "tool_cb_wrt.h"
 #include "tool_dirhie.h"
 #include "tool_doswin.h"
@@ -1346,6 +1347,10 @@ static CURLcode single_transfer(struct GlobalConfig *global,
         if(config->tcp_fastopen)
           my_setopt(curl, CURLOPT_TCP_FASTOPEN, 1L);
 
+        if(config->mptcp)
+          my_setopt(curl, CURLOPT_OPENSOCKETFUNCTION,
+                    tool_socket_open_mptcp_cb);
+
         /* where to store */
         my_setopt(curl, CURLOPT_WRITEDATA, per);
         my_setopt(curl, CURLOPT_INTERLEAVEDATA, per);