Skip to content

Add an option to enable Multipath TCP on clients#766

Merged
Lukasa merged 5 commits into
swift-server:mainfrom
Aperence:mptcp-support
Sep 20, 2024
Merged

Add an option to enable Multipath TCP on clients#766
Lukasa merged 5 commits into
swift-server:mainfrom
Aperence:mptcp-support

Conversation

@Aperence

Copy link
Copy Markdown
Contributor

Multipath TCP (MPTCP) is a TCP extension allowing to enhance the reliability of the network by using multiple interfaces. This extension provides a seamless handover between interfaces in case of deterioration of the connection on the original one. In the context of iOS and Mac OS X, it could be really interesting to leverage the capabilities of MPTCP as they could benefit from their multiple interfaces (ethernet + Wi-fi for Mac OS X, Wi-fi + cellular for iOS).

This contribution introduces patches to HTTPClient.Configuration and establishment of the Bootstraps. A supplementary field "enableMultipath" was added to the configuration, allowing to request the use of MPTCP. This flag is then used when creating the channels to configure the client.

Note that in the future, it might also be potentially interesting to offer more precise configuration options for MPTCP on MacOS, as the Network framework allows also to select a type of service, instead of just offering the option to create MPTCP connections. Currently, when enabling MPTCP, only the Handover mode is used.

@Lukasa

Lukasa commented Sep 9, 2024

Copy link
Copy Markdown
Collaborator

Hi @Aperence, sorry for the delay in getting a review here. I'll take a look now.

@Lukasa Lukasa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for this! Generally it looks like a great addition. I've noted that we need to tweak the API surface a bit.

Can I also ask that you add at least one unit test that uses the feature? That'll ensure that we don't break it.

ignoreUncleanSSLShutdown: Bool = false,
decompression: Decompression = .disabled) {
decompression: Decompression = .disabled,
enableMultipath: Bool = false) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Unfortunately, we can't add new parameters to public methods. This will need a new method that has the extra parameter.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Does it require a new method, or do you prefer simply having the field enableMPTCP as public in the configuration, allowing to set it freely ?

ignoreUncleanSSLShutdown: Bool = false,
decompression: Decompression = .disabled
decompression: Decompression = .disabled,
enableMultipath: Bool = false

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Unfortunately, we can't add new parameters here. We need a new method, with the new parameter.

ignoreUncleanSSLShutdown: Bool = false,
decompression: Decompression = .disabled) {
decompression: Decompression = .disabled,
enableMultipath: Bool = false) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same note here.

decompression: Decompression = .disabled,
backgroundActivityLogger: Logger?) {
backgroundActivityLogger: Logger?,
enableMultipath: Bool = false) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same note here.

ignoreUncleanSSLShutdown: Bool = false,
decompression: Decompression = .disabled) {
decompression: Decompression = .disabled,
enableMultipath: Bool = false) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same note here.

@Aperence

Aperence commented Sep 9, 2024

Copy link
Copy Markdown
Contributor Author

Hello @Lukasa,

First, thanks for the review !

I've removed the changes to the methods' signatures. It is still possible to set the enableMultipath field as it is public, but if you prefer, I can also introduce a method for it.

I've added also another test that enables MPTCP, and check that we can still fetch https://httpbin.org/get, as requested.

I remain available if other changes are needed.
Have a nice day !

@Aperence Aperence requested a review from Lukasa September 9, 2024 13:41
@Lukasa Lukasa added the 🆕 semver/minor Adds new public API. label Sep 16, 2024
@Lukasa

Lukasa commented Sep 16, 2024

Copy link
Copy Markdown
Collaborator

@swift-server-bot test this please

Comment thread Tests/AsyncHTTPClientTests/HTTPClientTests.swift Outdated
@Lukasa

Lukasa commented Sep 16, 2024

Copy link
Copy Markdown
Collaborator

Ok, looks like the linux tests fail with EINVAL. This happens with kernels that don't support MPTCP, so you'll need to add a try-catch that checks for this case and skips the test in that context.

@Aperence

Copy link
Copy Markdown
Contributor Author

Just added the do-catch now !

Comment thread Tests/AsyncHTTPClientTests/HTTPClientTests.swift Outdated
Comment thread Tests/AsyncHTTPClientTests/HTTPClientTests.swift Outdated
Multipath TCP (MPTCP) is a TCP extension allowing to enhance
the reliability of the network by using multiple interfaces.
This extension provides a seamless handover between interfaces
in case of deterioration of the connection on the original one.
In the context of iOS and Mac OS X, it could be really interesting
to leverage the capabilities of MPTCP as they could benefit from
their multiple interfaces (ethernet + Wi-fi for Mac OS X, Wi-fi +
cellular for iOS).

This contribution introduces patches to HTTPClient.Configuration and
establishment of the Bootstraps. A supplementary field "enableMultipath"
was added to the configuration, allowing to request the use of MPTCP.
This flag is then used when creating the channels to configure the client.

Note that in the future, it might also be potentially interesting to offer
more precise configuration options for MPTCP on MacOS, as the Network
framework allows also to select a type of service, instead of just offering
the option to create MPTCP connections. Currently, when enabling MPTCP, only
the Handover mode is used.
@Aperence

Copy link
Copy Markdown
Contributor Author

Applied required changes

Comment thread Tests/AsyncHTTPClientTests/HTTPClientTests.swift Outdated
@Lukasa

Lukasa commented Sep 18, 2024

Copy link
Copy Markdown
Collaborator

@swift-server-bot test this please

}
let response = try client.get(url: self.defaultHTTPBinURLPrefix + "get").wait()
XCTAssertEqual(.ok, response.status)
} catch let error as IOError where error.errnoCode == EINVAL {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just tried running this locally, it turns out EPROTONOSUPPORT is also sometimes thrown on Linux, so we need to add that to the list.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added this, I've checked the documentation and it seems that it could also raise an ENOPROTOOPT error, so I've added this one too to the list

@Lukasa

Lukasa commented Sep 20, 2024

Copy link
Copy Markdown
Collaborator

@swift-server-bot test this please

@Lukasa Lukasa enabled auto-merge (squash) September 20, 2024 11:15

@Lukasa Lukasa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice one, thanks!

@Lukasa Lukasa merged commit 15dbe6d into swift-server:main Sep 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🆕 semver/minor Adds new public API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants