From dead7887b1a1a06aad8c80592045375401e4aeda Mon Sep 17 00:00:00 2001 From: Matthieu Baerts Date: Fri, 24 Feb 2023 17:51:59 +0100 Subject: [PATCH] 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 . Updates #56539 Change-Id: I94fb8448dae351e1d3135b4f182570979c6b36d3 Reviewed-on: https://go-review.googlesource.com/c/go/+/471138 Reviewed-by: Ian Lance Taylor Reviewed-by: Emmanuel Odeke Run-TryBot: Emmanuel Odeke TryBot-Result: Gopher Robot Reviewed-by: Matthew Dempsky --- src/net/mptcpsock_linux.go | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/net/mptcpsock_linux.go b/src/net/mptcpsock_linux.go index 4663d28b4b..15a7882498 100644 --- a/src/net/mptcpsock_linux.go +++ b/src/net/mptcpsock_linux.go @@ -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) } -- 2.48.1