1
0
mirror of https://github.com/golang/go synced 2024-09-29 04:14:27 -06:00

net: mptcp: fallback to TCP in case of any error

Specific MPTCP errors could happen but only one is detectable: if
ENOPROTOOPT errno is returned, it likely means MPTCP has been disable
via this sysctl knob: net.mptcp.enabled.

But because MPTCP could be blocked by the administrator using different
techniques (SELinux, etc.) making the socket creation returning other
errors, it looks better to always retry to create a "plain" TCP socket
when any errors are returned.

This work has been co-developed by Gregory Detal
<gregory.detal@tessares.net>.

Updates #56539

Change-Id: I94fb8448dae351e1d3135b4f182570979c6b36d3
Reviewed-on: https://go-review.googlesource.com/c/go/+/471138
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Matthieu Baerts 2023-02-24 17:51:59 +01:00 committed by Emmanuel Odeke
parent f80e270bab
commit dead7887b1

View File

@ -44,19 +44,33 @@ func initMPTCPavailable() {
}
func (sd *sysDialer) dialMPTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
// Fallback to dialTCP if Multipath TCP isn't supported on this operating system.
if !supportsMultipathTCP() {
return sd.dialTCP(ctx, laddr, raddr)
if supportsMultipathTCP() {
if conn, err := sd.doDialTCPProto(ctx, laddr, raddr, _IPPROTO_MPTCP); err == nil {
return conn, nil
}
}
return sd.doDialTCPProto(ctx, laddr, raddr, _IPPROTO_MPTCP)
// Fallback to dialTCP if Multipath TCP isn't supported on this operating
// system. But also fallback in case of any error with MPTCP.
//
// Possible MPTCP specific error: ENOPROTOOPT (sysctl net.mptcp.enabled=0)
// But just in case MPTCP is blocked differently (SELinux, etc.), just
// retry with "plain" TCP.
return sd.dialTCP(ctx, laddr, raddr)
}
func (sl *sysListener) listenMPTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
// Fallback to listenTCP if Multipath TCP isn't supported on this operating system.
if !supportsMultipathTCP() {
return sl.listenTCP(ctx, laddr)
if supportsMultipathTCP() {
if dial, err := sl.listenTCPProto(ctx, laddr, _IPPROTO_MPTCP); err == nil {
return dial, nil
}
}
return sl.listenTCPProto(ctx, laddr, _IPPROTO_MPTCP)
// Fallback to listenTCP if Multipath TCP isn't supported on this operating
// system. But also fallback in case of any error with MPTCP.
//
// Possible MPTCP specific error: ENOPROTOOPT (sysctl net.mptcp.enabled=0)
// But just in case MPTCP is blocked differently (SELinux, etc.), just
// retry with "plain" TCP.
return sl.listenTCP(ctx, laddr)
}