Multipath TCP for Linux (2022)
mptcp.dev
mptcp.dev
It made so much sense back then, when mobile apps were not that robust to networks changing, I assumed it's going to get adopted in no time due to how much of a ux improvement it would have been back in the day.
It's incredibly depressing that this gained barely any traction in the last 10 years, and kernel options are appearing just recently, after everyone has wrapped they http calls in multiple retry handlers, and mobile operating systems have abstracted network connectivity to the point where it feels more like you are using zeromq rather than tcp.
> I assumed it's going to get adopted in no time due to how much of a ux improvement it would have been back in the day.
You might also be interested in SCTP[1] from the year 2000, which also hasn't gotten any traction so far.
[1]: https://en.wikipedia.org/wiki/Stream_Control_Transmission_Pr...
(SCTP over DTLS, that is...)
Probably partly because middleware boxes (e.g., firewalls) either didn't/don't support it and/or rules were written to only support "TCP" (as opposed to 'stream') or "UDP" (as opposed to 'dgram'; see also "DCCP").
Now we have HTTP3 which runs over UDP - where there is a will, there is a way.
Perhaps SCTP was ahead of its time.
SCTP over UDP came out in 2013:
* https://datatracker.ietf.org/doc/html/rfc6951
SCTP came out in 2000:
* https://datatracker.ietf.org/doc/html/rfc2960
Over a decade is quite a while in Internet-time.
Most firewalls are default deny out of the box and you have to allow things through. How many folks bother opening up SCTP/DCCP/etc?
Given that TCP also has at least one unfixable flaw, the only recommendation I can make is to use something UDP-based - which, to make sure you don't stomp on everybody else's traffic, means use the only popular one: QUIC (the layer beneath HTTP/3).
When I was deployed on FreeBSD with no load balancers, there weren't recent patches. And even if there were, I'd need to do some serious work to avoid advertising the private network ips as alternates...
When I was on Linux behind a load balancer, it's too complex to get the streams to the right place. And the load balancer doesn't want to do it anyway.
Processing two streams together involves a lot of complexity in a high throughput code path. It's a lot of risk, and you've got to reboot for changes.
And then you do all that work and it only benefits iOS users, who tend to be on better networks anyway.
The only question I have is if it opens up a different can of worms even if you've got a magic box terminating layer 7 for you or not. Never dug deep enough into mptcp myself to know.
If you balance your load balancers with ECMP, I don't know if you can get two client streams to the same mptcp terminating place.
If you've optimized the heck out of your tcp flows, this throws a wrench in there, because the second stream is likely to get hashed into a different nic queue, and then you have communication between cpus to move forward on the logical stream.
It would have been really handy though, and solve real issues with real users.
Edit to add: it could also solve some issues on private networking / interserver networking I saw... although the contention would be a much bigger problem on higher bandwidth streams. On networks with link aggregation, while there are many paths from one host to another, usually path selection is by hashing the connection 5-tuple {src ip, dst ip, protocol, src port, dst port} so a long running tcp connection remains on the same path for the duration, if a path segment has high loss/corruption or is congested, MPTCP could help if you had an extra connection that hit a different path. Otherwise, you need to find the segment and get network operations to fix it; it's not easy to figure that out (i had to write a tool to sample and find port combinations with trouble and then a patch for mtr to run a trace with fixed ports) and then you still need to reconnect your affected tcp sockets unless you can get a quick response from net ops (sometimes they can check error stats once the right devices are pointed out to them, and then replacing a cable/fiber often helps, or disconnecting it during investigation can help the traffic flow across the redundant links)
At Google, we do something similar with QUIC and connection migration. Our mechanism for ensuring these hit the same backend is Maglev [0], where we use the QUIC connection ID for hashing purposes in software. (Our routers still mostly use ECMP based on the 5-tuple, so being able to consistently hash to the same backend across multiple LB instances is crucial.)
> if a path segment has high loss/corruption or is congested, MPTCP could help if you had an extra connection that hit a different path.
Incidentally, we also have a family of internal mechanisms that do this, although we don't rely on MPTCP. (We instead twiddle some other bits in the packet that we make sure our routers use for hashing, at least for RPCs between prod machines.) This inspired some of the connection migration work in our QUIC implementation [1], wherein we can migrate to a different ephemeral port if we detect issues with the current path. This works shockingly often for routing around network problems.
[0] https://research.google/pubs/maglev-a-fast-and-reliable-soft...
[1] https://github.com/google/quiche/blob/main/quiche/quic/core/...
I don't think there is any basis to claim that.
iPhone isn't always 'premium', since they have their version of cheap phones as well. Point is cell network service quality is independent from phone quality.
https://www.comscore.com/lat/Prensa-y-Eventos/Infographics/i...
Multipath: There are several areas where TCP still has an advantage over QUIC. One of those is multipath support. Multipath TCP connections can send data on different network paths simultaneously — for example, sending via both WiFi and cellular data — to provide better throughput than either path permits individually.
Server connection migration is explicitly forbidden by QUIC:
It's on the standards track, rather than experimental, so likely to be supported once finished. There seem to be some implementations, including Apple:
https://github.com/quicwg/multipath/wiki/QUIC-Implementation...
Complain to your ISP if they mingle with a layer they are not supposed to mingle with.
>(And firewall in free access points / guest networks
I consider those as "corporate".
We ended up going with PepLink's SpeedFusion to save engineering time. But the license was costly. I really hope for a free solution in the future for 2 cellular networks and <50ms failover.
Multipath UDP + OpenVPN would also probably be a viable solution.
It will connect your devices in a P2P Mesh VPN and allow them to send and receive data using multiple links (e.g. multiple 5G or 5G + Satellite).
It is significantly cheaper than Peplink's license, less latency and no bandwidth / data limits.
You need to bring your own hardware though. Like a Raspberry Pi with 3 USB 4G/5G dongles.
https://mikrotik.com/product/rbm33g#fndtn-specifications
maybe someone could make one that uses an RPi compute module instead.
I found this board on AliExpress (https://www.aliexpress.com/item/1005003540616473.html?spm=a2...) based on the CM4 and with 3 cellular modems. That could also be a good candidate.
Also found this one (https://www.gateworks.com/products/industrial-single-board-c...) US-made and has 3 minipcie slots (other options available with 2 and 4)
Do you mean how we have to use 4 fields to track a connection - IP address and port for both ends?
(Another fun future would have been one where SCTP got widespread adoption.)
* Where to send a frame to get to the other side of the connection
* Whose connection this is.
TCP combined the two, because we didn't have mobile clients or a lot of multihomed systems that would benefit from distinguishing them. Also, every octet in the header counted.
In practice, this means we have to keep building a lot of infrastructure on top of TCP (or parallel to it, in datagram protocols) to handle retries and splitting flows well. In turn, these things are completely opaque to the network and it's difficult to write rules about them.
Whereas if we had different packet fields for "where am I sending this packet right now" and "whose flow does this belong to"? we could write better firewall rules, have less infrastructure built on top of TCP, and have better typical application performance.
It's just the origin that needs to know what address(es) it should be using as the destination at layer 3.
The big problems with this is that it depends upon things that weren't really feasible in the early 80's -- bigger packet headers, a bit more state on each side of the connection, potential need for cryptographic authentication.
There is still a source/destination address. Routing still works. But those addresses are allowed to change without disrupting the connection because the connection isn't based on the values of these addresses.
> When the device changes networks, how does the origin and all routers along the way know
The routers don't need to "know" these things.
MPQUIC does this. To the network it's just UDP packets moving around. Connection state is dealt with at higher levels and doesn't rely on IP addresses.
Otherwise you're just switching port (16-bit) value to arbitrary 32-bit identifier.
* Clients roaming between L3 addresses
* Clients/servers with multiple L3 addresses
RFC793:
To allow for many processes within a single Host to use TCP
communication facilities simultaneously, the TCP provides a set of
addresses or ports within each host. **Concatenated with the network
and host addresses from the internet communication layer,** this forms
a socket. A pair of sockets uniquely identifies each connection.
That is, a socket may be simultaneously used in multiple
connections.
TCP uses the combination of L3 source address, L3 destination address, L4 destination port, L4 source port to identify what connection a frame is on. We're discussing how using that L3 information isn't necessarily ideal for today's world.> TCP with changing IPs can work e.g. on top of an ip-ip tunnel with applications not being aware at all.
That's just because the IPs have not changed from its point of view: it receives the same frame with the same destination/source IP addresses the entire time.
Part of the reason why we need things like IP-IP tunnels is because L4 connections can't "move" with TCP. In scenarios where we're using tunneling for this, we're accepting worse performance than if we could just directly send TCP to its true destination and have it processed.
This doesn't make much sense to me. The hardest problem here is not assigning uuids to pipes, it's the routing/mapping of the "true destination".
- If you manage to solve it on L3, ip-ip tunnels or not — you have it, TCP works unmodified and so does UDP and everything else including quic and http/3.
- If you didn't solve it, then support for persistent connections in TCP is useless.
In another words I don't see what a "transmission control protocol" has to do with it. It's very reasonable to assume that addreses are already figured out when designing transmission control and that's exactly what TCP did.
SCTP and multipath TCP (which is what we're talking about) already do pretty much this. Assuming that endpoints to a stream connection have single, unchanging network addresses isn't a reasonable assumption anymore. But we're stuck with the assumption that hosts won't move in one of our most common protocols.
https://en.wikipedia.org/wiki/Multipath_TCP#/media/File:Diff...
https://en.wikipedia.org/wiki/Stream_Control_Transmission_Pr...
In the OSI model, you got similar functionality up at layer 5, but TCP only handles the connection/disconnection aspect of the session layer. In the internet world, we have a bunch of haphazard sets of retries, session balancing, multihoming and reconnecting behavior that are protocol specific (and completely missing from many well-used protocols) kludged on top. (Actually arguably MP-TCP is a session layer on top of TCP).
The only way you solve this on layer 3 is to build some kind of messy overlay network, because addresses have no real relation to where things are anymore. And we know that overlay networks are suboptimal and inefficient. Solving it at layer 4 doesn't have to be (but it's too late for that now).
(I did say I was oversimplifying...
In the OSI model what you talk about is level 5, that is session, but in TCP/IP there is no such level, thus it must be handled by the application (e.g. trough a session cookie, in HTTP).
This is mostly how Mosh [1] works and allows for IP roaming, changing IP's, etc... without losing ones SSH session. The connection can even be interrupted for a prolonged period of time and restore on its own on a new IP seamlessly.
[1] - https://mosh.org/
PS: I mentored a student for 2 years at GSOC to patch Openwrt with mptcp:
https://blog.freifunk.net/2017/05/29/gsoc-2017-add-mptcp-sup...
I'd think support on web servers and mobile devices would be most important...
I recently bought a property where I cannot get a full fibre connection, but I can get 150-400 Mbps using 5G. I've been thinking about using dual 5G connections and tunneling my traffic via mptcp to a VPS to aggregate the connections.
If you look at the older multipath TCP implementation, prior to the upstreaming, it was intended to be fully transparent to the application, which I think makes more sense for the intent of the protocol. Sure, in many cases MPTCP may be better with application-guided logic, but having a standard system approach (e.g. establish sub-flows on an LTE connection for automatic failover, but don't send any data along those sub-flows) would have worked for 95% of cases.
[1] https://lore.kernel.org/all/alpine.OSX.2.21.1707181728570.11...
But apps can use it by default. For the server case, it really makes sense: https://www.mptcp.dev/faq.html#why--when-should-mptcp-be-ena...
GNU/Linux distributions could even switch MPTCP on by default (via eBPF).
Imagine you have an application which checks the clients IP (eg. against a whitelist) at the time of connection and then assumes it doesn't change...
Like everything which came along and tried to supplant regular TCP, such as SCTP, it seems MPTCP has also been confined to a niche of application developers who will use it forever while the rest of the world forgets about it.
> QUIC multiplexes application streams on a single UDP flow, whereas MPTCP splits a single stream on multiple TCP subflows. MPQUIC combines both features by multiplex- ing application streams on multiple UDP subflows.
[1]: "Multipath QUIC: A Deployable Multipath Transport Protocol" https://www.researchgate.net/publication/327122884_Multipath...
Now I'm curious about how these protocols compare in production operation. Anybody have experience with both?
But both tries to achieve the same goal. Technically, you can have a very similar behaviour. MPTCP is implemented in the Linux kernel, while QUIC is on the userspace side.
That sounds .. quite restrictive. Is the only requirement on a middlebox to just forward the MPTCP options as-is?
If you're interested, we wrote a couple of papers on this:
[1] https://www.usenix.org/conference/nsdi12/technical-sessions/...
[2] https://www.researchgate.net/publication/229002024_Is_it_sti...
for example Great Chinese firewall: if you can split your traffic across multiple uplink channels, the firewall will have a hard time to put them together for enforcement?
With multiple ISPs, or on a complex enough LAN, we can use multiple routing tables + weights too.
Also, if the ISP at home can do 10Gbps, 1Gbps, 300 Mbps whatever... I want to be able to use them with a single path, so there is no gain using multiple paths. Eventually, when I have cable+wifi connected at the same time, I use to force one of both, cannot see a reason to prefer using both at the same time.
Maybe the latency thing? Never had that issue at home, but could understand that usage case "just use the network segment with less latency to reach $thing".
MPTCP can also be very interesting for mobility use-cases, even when one network is used at a time, e.g. switching from WiFi to cellular, or different cellular networks in the train, etc.
https://community.fortinet.com/t5/FortiGate/Technical-Tip-Ho...
I don't understand why you would want to be able to use them with a single path. the gain would be being able to aggregate them and have individual tcp streams faster than any one IP connection could handle.
Though personally I think the resilience is more appealing. Not having to have a hard cutover when wifi degrades as I walk away would be nice
So, If I already have a 10 Gbps path to the router, I don't want to add a 300 Mbps failing air path added to my way to the router.
In the context of the parent (at home networks), I think most people has two paths... WiFi or RJ45-UTP. And with that multipath setup (WiFi + RJ45, I don't get why other comments are talking about cellular networks "at home") is not usual to walk away; right, you could walk, as far as long is the rj45 cable, but...
To keep HA on WiFi when walking around, there are other technologies more battle tested than MPTCP.