Source File
mptcpsock_linux.go
Belonging Package
net
// Copyright 2023 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package netimport ()var (mptcpOnce sync.OncemptcpAvailable boolhasSOLMPTCP bool)// These constants aren't in the syscall package, which is frozenconst (_IPPROTO_MPTCP = 0x106_SOL_MPTCP = 0x11c_MPTCP_INFO = 0x1)func () bool {mptcpOnce.Do(initMPTCPavailable)return mptcpAvailable}// Check that MPTCP is supported by attempting to create an MPTCP socket and by// looking at the returned error if any.func () {, := sysSocket(syscall.AF_INET, syscall.SOCK_STREAM, _IPPROTO_MPTCP)switch {case errors.Is(, syscall.EPROTONOSUPPORT): // Not supported: >= v5.6case errors.Is(, syscall.EINVAL): // Not supported: < v5.6case == nil: // Supported and no errorpoll.CloseFunc()fallthroughdefault:// another error: MPTCP was not available but it might be latermptcpAvailable = true}, := unix.KernelVersion()// SOL_MPTCP only supported from kernel 5.16hasSOLMPTCP = > 5 || ( == 5 && >= 16)}func ( *sysDialer) ( context.Context, , *TCPAddr) (*TCPConn, error) {if supportsMultipathTCP() {if , := .doDialTCPProto(, , , _IPPROTO_MPTCP); == nil {return , nil}}// 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 .dialTCP(, , )}func ( *sysListener) ( context.Context, *TCPAddr) (*TCPListener, error) {if supportsMultipathTCP() {if , := .listenTCPProto(, , _IPPROTO_MPTCP); == nil {return , nil}}// 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 .listenTCP(, )}// hasFallenBack reports whether the MPTCP connection has fallen back to "plain"// TCP.//// A connection can fallback to TCP for different reasons, e.g. the other peer// doesn't support it, a middle box "accidentally" drops the option, etc.//// If the MPTCP protocol has not been requested when creating the socket, this// method will return true: MPTCP is not being used.//// Kernel >= 5.16 returns EOPNOTSUPP/ENOPROTOOPT in case of fallback.// Older kernels will always return them even if MPTCP is used: not usable.func ( *netFD) bool {, := .pfd.GetsockoptInt(_SOL_MPTCP, _MPTCP_INFO)// 2 expected errors in case of fallback depending on the address family// - AF_INET: EOPNOTSUPP// - AF_INET6: ENOPROTOOPTreturn == syscall.EOPNOTSUPP || == syscall.ENOPROTOOPT}// isUsingMPTCPProto reports whether the socket protocol is MPTCP.//// Compared to hasFallenBack method, here only the socket protocol being used is// checked: it can be MPTCP but it doesn't mean MPTCP is used on the wire, maybe// a fallback to TCP has been done.func ( *netFD) bool {, := .pfd.GetsockoptInt(syscall.SOL_SOCKET, syscall.SO_PROTOCOL)return == _IPPROTO_MPTCP}// isUsingMultipathTCP reports whether MPTCP is still being used.//// Please look at the description of hasFallenBack (kernel >=5.16) and// isUsingMPTCPProto methods for more details about what is being checked here.func ( *netFD) bool {if hasSOLMPTCP {return !hasFallenBack()}return isUsingMPTCPProto()}
![]() |
The pages are generated with Golds v0.7.6. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |