Skip to content

Commit

Permalink
functional option MPTCP with --mptcp and try to add test
Browse files Browse the repository at this point in the history
try to make mptcp test
  • Loading branch information
CrapsDorian committed Mar 21, 2024
1 parent fd1260d commit 018110c
Show file tree
Hide file tree
Showing 25 changed files with 246 additions and 13 deletions.
1 change: 1 addition & 0 deletions docs/cmdline-opts/Makefile.inc
Expand Up @@ -160,6 +160,7 @@ DPAGES = \
max-redirs.md \
max-time.md \
metalink.md \
mptcp.md \
negotiate.md \
netrc-file.md \
netrc-optional.md \
Expand Down
32 changes: 32 additions & 0 deletions docs/cmdline-opts/mptcp.md
@@ -0,0 +1,32 @@
---
c: Copyright (C) Dorian Craps, <dorian.craps@student.vinci.be>
SPDX-License-Identifier: curl
Long: mptcp
Added: 8.6.1
Help: Enable Multipath TCP (MPTCP)
Category: connection
Multi: boolean
See-also:

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 Wi-Fi and cellular data or in wired networks with multiple ISPs.

## Usage

To use MPTCP for your connections, add the `--mptcp` option when using `curl`:

## Requirements

- Your operating system must support MPTCP, and it must be enabled.
- The server you are connecting to must also support MPTCP.

## Availability

The `--mptcp` option is available starting from `curl` version 8.6.1.
4 changes: 4 additions & 0 deletions docs/libcurl/curl_easy_setopt.md
Expand Up @@ -423,6 +423,10 @@ Path to a Unix domain socket. See CURLOPT_UNIX_SOCKET_PATH(3)
Path to an abstract Unix domain socket. See CURLOPT_ABSTRACT_UNIX_SOCKET(3)
## CURLOPT_MPTCP
Enable Multipath TCP (MPTCP). See CURLOPT_MPTCP(3)
# NAMES and PASSWORDS OPTIONS (Authentication)
## CURLOPT_NETRC
Expand Down
70 changes: 70 additions & 0 deletions docs/libcurl/opts/CURLOPT_MPTCP.md
@@ -0,0 +1,70 @@
---
c: Copyright (C) Dorian Craps, <dorian.craps@student.vinci.be>
SPDX-License-Identifier: curl
Title: CURLOPT_MPTCP
Section: 3
Source: libcurl
See-also:
---

# NAME

CURLOPT_MPTCP - enable Multipath TCP

# SYNOPSIS

~~~c

#include <curl/curl.h>

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_MPTCP, long enable);
~~~
# DESCRIPTION
Pass a long as parameter set to 1L to enable or 0 to disable.
Multipath TCP (MPTCP) is an extension of TCP that allows multiple paths
to be used simultaneously by a single TCP connection, enhancing redundancy,
bandwidth, and potentially reducing latency.
It works by presenting a standard TCP interface to applications while
managing multiple underlying TCP connections.
Enabling MPTCP can improve the performance and reliability of network requests,
particularly in environments where multiple network paths (e.g., WiFi and
cellular) are available.
Note: MPTCP support depends on the underlying operating system and network
infrastructure. Not all networks support MPTCP, and its effectiveness will
vary based on the network configuration and conditions.
# DEFAULT
0
# PROTOCOLS
All
# EXAMPLE
~~~c
int main(void)
{
CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_MPTCP, 1L);
curl_easy_perform(curl);
}
}
~~~

# AVAILABILITY

Support for MPTCP in libcurl requires Linux 5.6 or later. The feature's availability in libcurl can also depend on the version of libcurl. Added in 8.6.1.

# RETURN VALUE

Returns CURLE_OK if MPTCP is successfully enabled for the connection, otherwise returns an error code specific to the reason it could not be enabled, which might include lack of operating system support or libcurl not being built with MPTCP support.
1 change: 1 addition & 0 deletions docs/libcurl/symbols-in-versions
Expand Up @@ -708,6 +708,7 @@ CURLOPT_MAXREDIRS 7.5
CURLOPT_MIME_OPTIONS 7.81.0
CURLOPT_MIMEPOST 7.56.0
CURLOPT_MUTE 7.1 7.8 7.15.5
CURLOPT_MPTCP 8.6.1
CURLOPT_NETRC 7.1
CURLOPT_NETRC_FILE 7.11.0
CURLOPT_NEW_DIRECTORY_PERMS 7.16.4
Expand Down
1 change: 1 addition & 0 deletions docs/options-in-versions
Expand Up @@ -125,6 +125,7 @@
--max-redirs 7.5
--max-time (-m) 4.0
--metalink 7.27.0
--mptcp 8.6.1
--negotiate 7.10.6
--netrc (-n) 4.6
--netrc-file 7.21.5
Expand Down
3 changes: 3 additions & 0 deletions include/curl/curl.h
Expand Up @@ -2206,6 +2206,9 @@ typedef enum {
/* millisecond version */
CURLOPT(CURLOPT_SERVER_RESPONSE_TIMEOUT_MS, CURLOPTTYPE_LONG, 324),

/* Set MPTCP */
CURLOPT(CURLOPT_MPTCP, CURLOPTTYPE_LONG, 325),

CURLOPT_LASTENTRY /* the last unused */
} CURLoption;

Expand Down
9 changes: 9 additions & 0 deletions lib/cf-socket.c
Expand Up @@ -244,6 +244,10 @@ void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
dest->socktype = SOCK_STREAM;
dest->protocol = IPPROTO_IP;
break;
case TRNSPRT_MPTCP:
dest->socktype = SOCK_STREAM;
dest->protocol = IPPROTO_MPTCP;
break;
default: /* UDP and QUIC */
dest->socktype = SOCK_DGRAM;
dest->protocol = IPPROTO_UDP;
Expand Down Expand Up @@ -1601,7 +1605,12 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
if(!ctx) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
#ifdef __linux__
if (data->set.mptcp) {
transport = TRNSPRT_MPTCP;
}
#endif
cf_socket_ctx_init(ctx, ai, transport);

result = Curl_cf_create(&cf, &Curl_cft_tcp, ctx);
Expand Down
4 changes: 4 additions & 0 deletions lib/cf-socket.h
Expand Up @@ -28,6 +28,10 @@
#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
#include "sockaddr.h"

#ifndef IPPROTO_MPTCP
#define IPPROTO_MPTCP 262
#endif

struct Curl_addrinfo;
struct Curl_cfilter;
struct Curl_easy;
Expand Down
3 changes: 2 additions & 1 deletion lib/easyoptions.c
Expand Up @@ -178,6 +178,7 @@ struct curl_easyoption Curl_easyopts[] = {
{"MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE, CURLOT_OFF_T, 0},
{"MIMEPOST", CURLOPT_MIMEPOST, CURLOT_OBJECT, 0},
{"MIME_OPTIONS", CURLOPT_MIME_OPTIONS, CURLOT_LONG, 0},
{"MPTCP", CURLOPT_MPTCP, CURLOT_LONG, 0},
{"NETRC", CURLOPT_NETRC, CURLOT_VALUES, 0},
{"NETRC_FILE", CURLOPT_NETRC_FILE, CURLOT_STRING, 0},
{"NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS, CURLOT_LONG, 0},
Expand Down Expand Up @@ -375,6 +376,6 @@ struct curl_easyoption Curl_easyopts[] = {
*/
int Curl_easyopts_check(void)
{
return ((CURLOPT_LASTENTRY%10000) != (324 + 1));
return ((CURLOPT_LASTENTRY%10000) != (325 + 1));
}
#endif
3 changes: 3 additions & 0 deletions lib/setopt.c
Expand Up @@ -2931,6 +2931,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
result = CURLE_NOT_BUILT_IN;
#endif
break;
case CURLOPT_MPTCP:
data->set.mptcp = TRUE;
break;
case CURLOPT_SSL_ENABLE_NPN:
break;
case CURLOPT_SSL_ENABLE_ALPN:
Expand Down
2 changes: 2 additions & 0 deletions lib/urldata.h
Expand Up @@ -788,6 +788,7 @@ struct ldapconninfo;
#define TRNSPRT_UDP 4
#define TRNSPRT_QUIC 5
#define TRNSPRT_UNIX 6
#define TRNSPRT_MPTCP 7

/*
* The connectdata struct contains all fields and variables that should be
Expand Down Expand Up @@ -1811,6 +1812,7 @@ struct UserDefined {
#ifdef USE_WEBSOCKETS
BIT(ws_raw_mode);
#endif
bool mptcp; /* enable MPTCP support */
};

#ifndef CURL_DISABLE_MIME
Expand Down
1 change: 1 addition & 0 deletions src/tool_cfgable.c
Expand Up @@ -45,6 +45,7 @@ void config_init(struct OperationConfig *config)
config->http09_allowed = FALSE;
config->ftp_skip_ip = TRUE;
config->file_clobber_mode = CLOBBER_DEFAULT;
config->mptcp = FALSE;
curlx_dyn_init(&config->postdata, MAX_FILE2MEMORY);
}

Expand Down
1 change: 1 addition & 0 deletions src/tool_cfgable.h
Expand Up @@ -298,6 +298,7 @@ struct OperationConfig {
struct State state; /* for create_transfer() */
bool rm_partial; /* on error, remove partially written output
files */
bool mptcp;
};

struct GlobalConfig {
Expand Down
5 changes: 5 additions & 0 deletions src/tool_getparam.c
Expand Up @@ -199,6 +199,7 @@ typedef enum {
C_MAX_REDIRS,
C_MAX_TIME,
C_METALINK,
C_MPTCP,
C_NEGOTIATE,
C_NETRC,
C_NETRC_FILE,
Expand Down Expand Up @@ -480,6 +481,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},
Expand Down Expand Up @@ -2742,6 +2744,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;
Expand Down
3 changes: 3 additions & 0 deletions src/tool_listhelp.c
Expand Up @@ -378,6 +378,9 @@ const struct helptxt helptext[] = {
{" --metalink",
"Process given URLs as metalink XML file",
CURLHELP_MISC},
{" --mptcp",
"Enable Multipath TCP (MPTCP)",
CURLHELP_CONNECTION},
{" --negotiate",
"Use HTTP Negotiate (SPNEGO) authentication",
CURLHELP_AUTH | CURLHELP_HTTP},
Expand Down
3 changes: 3 additions & 0 deletions src/tool_operate.c
Expand Up @@ -1291,6 +1291,9 @@ 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_MPTCP, 1L);

/* where to store */
my_setopt(curl, CURLOPT_WRITEDATA, per);
my_setopt(curl, CURLOPT_INTERLEAVEDATA, per);
Expand Down
2 changes: 1 addition & 1 deletion tests/data/Makefile.inc
Expand Up @@ -261,4 +261,4 @@ test3024 test3025 test3026 test3027 test3028 test3029 test3030 \
\
test3100 test3101 test3102 test3103 \
test3200 \
test3201 test3202
test3201 test3202 test3203
49 changes: 49 additions & 0 deletions tests/data/test3203
@@ -0,0 +1,49 @@
<testcase>
<info>
<keywords>
MPTCP
Multipath TCP
mptcp
</keywords>
</info>

<!-- Server-side configuration -->
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Server: swsclose
Content-Type: text/plain

Ceci est une réponse de test MPTCP.
</data>
</reply>

<!-- Client-side commands -->
<client>
<server>
mptcp
</server>
<precheck>
sh -c '[ "$(cat /proc/sys/net/mptcp/enabled 2>/dev/null)" = "1" ]'
</precheck>
<name>
MPTCP GET Request
</name>
<command>
--mptcp http://%HOSTIP:%HTTPPORT/%TESTNUMBER
</command>
</client>

<!-- Verification -->
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<errorcode>
0
</errorcode>
</verify>
</testcase>
5 changes: 5 additions & 0 deletions tests/http-server.pl
Expand Up @@ -56,6 +56,7 @@ BEGIN
my $keepalive_secs; # number of seconds to keep idle connections
my $srcdir;
my $gopher = 0;
my $mptcp = 0;

my $flags = "";
my $path = '.';
Expand Down Expand Up @@ -115,6 +116,9 @@ BEGIN
elsif($ARGV[0] eq '--gopher') {
$gopher = 1;
}
elsif($ARGV[0] eq '--mptcp') {
$mptcp = 1;
}
elsif($ARGV[0] eq '--port') {
if($ARGV[1] =~ /^(\d+)$/) {
$port = $1;
Expand Down Expand Up @@ -177,6 +181,7 @@ BEGIN
"--logdir \"$logdir\" ".
"--portfile \"$portfile\" ";
$flags .= "--gopher " if($gopher);
$flags .= "--mptcp " if($mptcp);
$flags .= "--connect $connect " if($connect);
$flags .= "--keepalive $keepalive_secs " if($keepalive_secs);
if($ipvnum eq 'unix') {
Expand Down
2 changes: 1 addition & 1 deletion tests/runner.pm
Expand Up @@ -590,7 +590,7 @@ sub singletest_startservers {

# timestamp required servers verification start
$$testtimings{"timesrvrini"} = Time::HiRes::time();

my $why;
my $error;
if (!$listonly) {
Expand Down
3 changes: 3 additions & 0 deletions tests/runtests.pl
Expand Up @@ -463,6 +463,9 @@ sub parseprotocols {
# 'http-proxy' is used in test cases to do CONNECT through
push @protocols, 'http-proxy';

# 'mptcp' is used in test cases to do MPTCP
push @protocols, 'mptcp';

# 'none' is used in test cases to mean no server
push @protocols, 'none';
}
Expand Down

0 comments on commit 018110c

Please sign in to comment.