Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

functional option MPTCP with --mptcp #2

Open
wants to merge 116 commits into
base: master
Choose a base branch
from
Open

functional option MPTCP with --mptcp #2

wants to merge 116 commits into from

Conversation

CrapsDorian
Copy link
Owner

@CrapsDorian CrapsDorian commented Mar 21, 2024

An HTTP test server indicating whether MPTCP (Multipath TCP) is utilized is now available at the following address: http://test.multipath-tcp.org:5000/.

Attention points:

  • This PR replaces First version of Multipath TCP support in curl curl/curl#9713.
  • Sorry for functional option MPTCP with --mptcp curl/curl#13161, I accidentally opened it while the code was not ready yet, my bad.
  • Regarding the documentation, we didn't find a good reference (See-also). We put tcp-fastopen because we had to put something, but we are happy to change.
  • It is not clear for us if a test is worth it. According to your comments from First version of Multipath TCP support in curl curl/curl#9713, it might not be worth it. We successfully tested it with http://test.multipath-tcp.org:5000 .
  • The transport is changed to TRNSPRT_MPTCP in Curl_cf_tcp_create(), not to change the logic before ("happy eyeballs", etc.), and because this feature is an extension to TCP, and it should only modify TCP connections. We are happy to change that if there is a better way.
  • In the declaration of struct OperationConfig in src/tool_cfgable.h, the struct OperationConfig *next; item has this comment next to it: /* Always last in the struct */, but it is no longer the last item in the structure. Is it normal?

Copy link
Collaborator

@matttbe matttbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, looks god, just some various things

Category: connection
Multi: boolean
See-also:
- tcp-fastopen
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what else we can give, maybe request?
We can also wait for advices from the maintainers

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add in the PR description, something like:

Attention points:
- This PR replaces #9713.
- Sorry for #13161, I accidentally opened it while the code was not ready yet, my bad.
- Regarding the documentation, we didn't find a good reference (`See-also`). We put `tcp-fastopen` because we had to put something, but we are happy to change.
- It is not clear for us if a test is worth it. According to your comments from #9713, it might not be worth it. We successfully tested it with http://test.multipath-tcp.org:5000 .


## Availability

The `--mptcp` option is available starting from `curl` version 8.6.1.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8.7.0


## Requirements

- Your operating system must support MPTCP, and it must be enabled.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably best to add:

Currently, this feature is only supported on Linux.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feature is currently only supported on Linux starting from kernel 5.6. ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good idea!

This feature is currently only supported on Linux 5.6 or later.

## Requirements

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably best to add:

If not, the connection will fallback to TCP.

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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe best to use the same paragraph here as well

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.

For the paragraph above and below. You can keep the note

lib/cf-socket.c Outdated
}
#ifdef __linux__
if (data->set.mptcp) {
transport = TRNSPRT_MPTCP;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line is not aligned properly: should be indented by 2 spaces, not 3

(I know it looks like details, but consistency is important, maybe they use "beautifier" tools like uncrustify, and you don't want to cause unwanted changes, and you don't want such comments during the review)

lib/cf-socket.h Outdated
@@ -28,6 +28,10 @@
#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
#include "sockaddr.h"

#ifndef IPPROTO_MPTCP
#define IPPROTO_MPTCP 262
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe best to move this to lib/cf-socket.c, at the top (? or just above where you use it?), it is only used in this file, in a single place.

lib/setopt.c Outdated
@@ -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:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: only one space after case

lib/urldata.h Outdated
@@ -1811,6 +1812,7 @@ struct UserDefined {
#ifdef USE_WEBSOCKETS
BIT(ws_raw_mode);
#endif
bool mptcp; /* enable MPTCP support */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

best to use BIT(mptcp); like the other ones above. (you only need 1 bit)

@@ -298,6 +298,7 @@ struct OperationConfig {
struct State state; /* for create_transfer() */
bool rm_partial; /* on error, remove partially written output
files */
bool mptcp;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add /* enable MPTCP support */ (even if it is a bit obvious...)

Copy link
Collaborator

@matttbe matttbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx for the update. Don't forget to update the commit message.

Feel free to also update the PR description with the additional notes we prepare, so you just have to copy-paste when the PR will be opened later

lib/cf-socket.c Outdated
@@ -1601,7 +1605,15 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
if(!ctx) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unwanted change

lib/cf-socket.c Outdated
#endif

#ifdef __linux__
if(data->set.mptcp) transport = TRNSPRT_MPTCP;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you put transport = ... at the next line?

if(data->set.mptcp)
  transport = TRNSPRT_MPTCP;

lib/cf-socket.c Outdated
@@ -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:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you move

#ifndef IPPROTO_MPTCP
#define IPPROTO_MPTCP 262
#endif

here?

(or just after the declaration of the function?)

lib/cf-socket.h Outdated
@@ -28,6 +28,7 @@
#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
#include "sockaddr.h"


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unwanted change

Don't forget the auto-review ;)

@@ -298,6 +298,7 @@ struct OperationConfig {
struct State state; /* for create_transfer() */
bool rm_partial; /* on error, remove partially written output
files */
bool mptcp; /* enable MPTCP support */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get their code style here, maybe best to align the comment with the one above?

  bool rm_partial;                /* on error, remove partially written output
                                     files */
  bool mptcp;                     /* enable MPTCP support */

@@ -244,6 +244,13 @@ void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
dest->socktype = SOCK_STREAM;
dest->protocol = IPPROTO_IP;
break;
#ifndef IPPROTO_MPTCP
#define IPPROTO_MPTCP 262
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, it was not clear: just below case TRNSPRT_MPTCP:

@@ -1602,6 +1609,11 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
result = CURLE_OUT_OF_MEMORY;
goto out;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

detail, just to be consistent with the rest of the code: either also add a new line after #endif or no new line here.

Copy link
Collaborator

@matttbe matttbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one last batch of modifications needed and then we will be good.

@@ -484,6 +484,7 @@ Monnerat
monospace
MorphOS
MPE
MPTCP
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be placed after MPL to respect the alphabetical order.


- This feature is currently only supported on Linux starting from kernel 5.6.
- The server you are connecting to must also support MPTCP.
If not, the connection falls back to TCP..
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is an extra dot . at the end here.

While at it, maybe good to add "seamlessly" and this line could be partially moved to the previous one, as long as you keep the 80 char limit:

- The server you are connecting to must also support MPTCP. If not, the
  connection will seamlessly fall back to TCP.


## Usage

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the : at the end suggests something is missing. Maybe you just want to replace it with a .?

@@ -484,6 +484,7 @@ Monnerat
monospace
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the commit message (not related to this here), I think you can remove:

An HTTP test server indicating whether MPTCP (Multipath TCP) is utilized
is now available at the following address: http://test.multipath-tcp.org:5000/.

But place it in the PR description: the service might not be available after the PR, maybe best not to keep this in the Git history.

Category: connection
Multi: boolean
See-also:
- tcp-fastopen
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add in the PR description, something like:

Attention points:
- This PR replaces #9713.
- Sorry for #13161, I accidentally opened it while the code was not ready yet, my bad.
- Regarding the documentation, we didn't find a good reference (`See-also`). We put `tcp-fastopen` because we had to put something, but we are happy to change.
- It is not clear for us if a test is worth it. According to your comments from #9713, it might not be worth it. We successfully tested it with http://test.multipath-tcp.org:5000 .

infrastructure. Some networks might drop unknown MPTCP, (...), and its
effectiveness varies based on the network configuration and conditions.
If MPTCP is not supported by the network or the end server,
the connection falls back to TCP.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as for the other doc:

the connection will seamlessly fall back to TCP.


#ifdef __linux__
if(data->set.mptcp)
transport = TRNSPRT_MPTCP;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the "Attention points" of the PR (see my previous comment above), maybe good to add:

- The `transport` is changed to `TRNSPRT_MPTCP` in `Curl_cf_tcp_create()`, not to change the logic before ("happy eyeballs", etc.), and because this feature is an extension to TCP, and it should only modify TCP connections. We are happy to change that if there is a better way.

@@ -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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should not be needed, because of the memset(config, 0, sizeof(struct OperationConfig));

Also, see my comment in struct OperationConfig

@@ -298,6 +298,7 @@ struct OperationConfig {
struct State state; /* for create_transfer() */
bool rm_partial; /* on error, remove partially written output
files */
bool mptcp; /* enable MPTCP support */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you move this a bit above, just between file_clobber_mode; and struct GlobalConfig *global;.

Because struct OperationConfig *next; /* Always last in the struct */ just above

@@ -298,6 +298,7 @@ struct OperationConfig {
struct State state; /* for create_transfer() */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the PR's attention point:

- In the declaration of `struct OperationConfig` in `src/tool_cfgable.h`, the `struct OperationConfig *next;` item has this comment next to it: `/* Always last in the struct */`, but it is no longer the last item in the structure. Is it normal?

infrastructure. Some networks might drop unknown MPTCP, and its
effectiveness varies based on the network configuration and conditions.
If MPTCP is not supported by the network or the end server,
the connection will seamlessly fall back to TCP..
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the extra . is back

Copy link
Collaborator

@matttbe matttbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code looks OK to me, good work!

dfandrich and others added 7 commits April 4, 2024 09:23
This version still has ELTS support and contains some old versions of
key components like cmake to help prevent us from breaking that support.

Closes curl#13029
Unity mode is not supported by CMake v3.7.2 used in linux-old, but
enable it anyway for consistency and to kick in automatically once
migrating to a newer old Linux in the future.

Also:
- replace `CMAKE_COMPILE_WARNING_AS_ERROR` with `CURL_WERROR`.
- delete default build option `PICKY_COMPILER=ON`.

Closes curl#13277
Fixing:
```
make[2]: Circular docs/curl-config.1 <- docs/curl-config.1 dependency dropped.
make[2]: Circular docs/mk-ca-bundle.1 <- docs/mk-ca-bundle.1 dependency dropped.
```
Ref: https://github.com/curl/curl/actions/runs/8559617487/job/23456740844?pr=13282#step:6:18

Follow-up to 5023ffa curl#13197
Closes curl#13283
A recent image upgrade added a $HOME/.curlrc by default using --ipv4.

Ref: actions/runner-images#9586
Fixes curl#13284
Closes curl#13285
- cmake: fix `-pedantic-errors` for old CMake with `CURL_WERROR=ON` set.

  `-pedantic-errors` option throws a warning with GCC (all versions) and
  makes `check_symbol_exists()` fail in CMake versions older than
  v3.23.0 (2022-03-29), when CMake introduced a workaround:

  https://gitlab.kitware.com/cmake/cmake/-/issues/13208
  https://gitlab.kitware.com/cmake/cmake/-/commit/eeb45401163d831b8c841ef6eba81466b4067b68
  https://gitlab.kitware.com/cmake/cmake/-/commit/1ab7c3cd28b27ca162c4559e1026e5cad1898ade

  Follow-up to 3829759 curl#12489

- set `CURL_WERROR=ON` for the `linux-old` job in CI.

Closes curl#13282
clang doesn't have the issues of GCC and old CMake versions.

Note: This introduces asymmetry with autotools, which only enables
this for GCC.

Reviewed-by: Daniel Stenberg
Closes curl#13286
vszakats and others added 29 commits April 16, 2024 19:47
- `openssl_check_symbol_exists()` expects a 4th argument now.
  Follow-up to edc2702 curl#13373

- minor comment/script touch-ups.
  Follow-up to a362962 curl#11922

- fix indentation.

Closes curl#13383
For easier reproducibility.

Mention using this script in RELEASE-PROCEDURE

Closes curl#13388
To reduce the risk that the user running the tests has a .curlrc present
that messes things up.

Support 'option="no-q"' for the <command> tag to switch it off on demand.
Use this new feature in test 433 and 436.

Ref: curl#13284
Closes curl#13387
- fix flow handling in ngtcp2 to ACK data on streams
  we abort ourself.
- extend test_02_23* cases to also run for h3
- skip test_02_23* for OpenSSL QUIC as it gets stalled
  on progressing the connection

Closes curl#13374
I implemented the IDN functions for macOS and iOS using Unicode
libraries coming with macOS and iOS.

Builds and runs here on macOS 14.2.1. Also verified to load and
run on older macOS version 10.13.

Build requires macOS SDK 13 or equivalent.

Set `-DUSE_APPLE_IDN=ON` CMake option to enable it.
With autotools and other build tools, set these manual options:
```
CPPFLAGS=-DUSE_APPLE_IDN
LIBS=-licucore
```

Completes TODO 1.6.

TODO: add autotools option and feature-detection.

Refs: curl#5330 curl#5371
Co-authored-by: Viktor Szakats
Closes curl#13246
The check for an option must be predicated on options existing at all.

Follow-up to f7cc9e9
Removes the need for disabling shellcheck warnings.

Follow-up to d28f749
Proposed-by: Viktor Szakats
Closes curl#13391
- add `Curl_hash_offt` as hashmap between a `curl_off_t` and
  an object. Use this in h2+h3 connection filters to associate
  `data->id` with the internal stream state.
- changed implementations of all affected connection filters
- removed `h2_ctx*` and `h3_ctx*` from `struct HTTP` and thus
  the easy handle
- solves the problem of attaching "foreign protocol" easy handles
  during connection shutdown

Test 1616 verifies the new hash functions.

Closes curl#13204
Building curl with -Wcomma, I see warnings about "possible misuse of
comma operator here" and moving fields assignment out of the for() fixes
it.

Closes curl#13392
The parameters are named data, not date.

Closes curl#13393
macro "H3_STREAM_CTX" requires 2 arguments, but only 1 given

Follow-up to c6655f7

Closes curl#13401
- Conversion support for new version info character field rtmp_version.
- New ILE/RPG declarations.

Closes curl#13402
Using the URL API for a redirect URL when the redirected-to string
starts with a hash, ie is only a fragment, the API would produce the
wrong final URL.

Adjusted test 1560 to test for several new redirect cases.

Closes curl#13394
return the result back to the caller.

Closes curl#13398
Inspired by WHATWG URL Spec test inputs

Closes curl#13400
By default the API inhibits empty queries and fragments extracted.
Unless this new flag is set.

This also makes the behavior more consistent: without it set, zero
length queries and fragments are considered not present in the URL. With
the flag set, they are returned as a zero length strings if they were in
fact present in the URL.

This applies when extracting the individual query and fragment
components and for the full URL.

Closes curl#13396
- new caddy servers no longer return 200 on POSTs, but 405
  as they should

Closes curl#13405
... and move the feature request line to the bottom.
The function is only called from a single place (for HTTP/2 server push)
so might as well just assume this fixed option every time.

Closes curl#13409
In the function AcceptServerConnect() the newly created socket would
leak if Curl_conn_tcp_accepted_set() returns error. Which basically
should never happen.

Spotted by CodeSonar.

Closes curl#13417
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet