curl: (on linux) add 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.

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 [1]
Link: https://www.tessares.net/apples-mptcp-story-so-far/ [2]
Link: https://www.mptcp.dev [3]
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
This commit is contained in:
Dorian Craps 2024-04-04 11:42:50 +02:00 committed by Daniel Stenberg
parent 3c20ae08b9
commit ab6d5442e8
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
12 changed files with 156 additions and 0 deletions

View 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

View File

@ -162,6 +162,7 @@ DPAGES = \
max-redirs.md \
max-time.md \
metalink.md \
mptcp.md \
negotiate.md \
netrc-file.md \
netrc-optional.md \

View File

@ -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.

View File

@ -127,6 +127,7 @@
--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

View 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, -

View 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 \

58
src/tool_cb_soc.c Normal file
View File

@ -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);
}

36
src/tool_cb_soc.h Normal file
View File

@ -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 */

View 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 */

View 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;

View 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},

View 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);