Skip to content

Commit

Permalink
net: add initial MPTCP support
Browse files Browse the repository at this point in the history
This currently defines an internal function supportsMultipathTCP which
reports whether MPTCP[1] is supported on the current platform.

Only Linux is supported here.

The check on Linux is performed once by attemting to create an MPTCP
socket and look at the returned error:

- If the protocol is not supported, EINVAL (kernel < 5.6) or
  EPROTONOSUPPORT (kernel >= 5.6) is returned and there is no point to
  try again.

- Other errors can be returned:
  - ENOPROTOOPT: the sysctl knob net.mptcp.enabled is set to 0
  - Unpredictable ones: if MPTCP is blocked using SELinux, eBPF, etc.

These other errors are due to modifications that can be reverted during
the session: MPTCP can be available again later. In this case, it is
fine to always try to create an MPTCP socket and fallback to TCP in case
of error.

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

[1] https://www.rfc-editor.org/rfc/rfc8684.html

Updates #56539

Change-Id: Ic84fe85aad887a2be4556a898e649bf6b6f12f03
Reviewed-on: https://go-review.googlesource.com/c/go/+/471135
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
  • Loading branch information
matttbe authored and gopherbot committed Mar 24, 2023
1 parent 16544b8 commit 59d7c69
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/net/mptcpsock_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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 net

import (
"errors"
"internal/poll"
"sync"
"syscall"
)

var (
mptcpOnce sync.Once
mptcpAvailable bool
)

// These constants aren't in the syscall package, which is frozen
const (
_IPPROTO_MPTCP = 0x106
)

func supportsMultipathTCP() bool {
mptcpOnce.Do(initMPTCPavailable)
return mptcpAvailable
}

// Check that MPTCP is supported by attemting to create an MPTCP socket and by
// looking at the returned error if any.
func initMPTCPavailable() {
s, err := sysSocket(syscall.AF_INET, syscall.SOCK_STREAM, _IPPROTO_MPTCP)
switch {
case errors.Is(err, syscall.EPROTONOSUPPORT): // Not supported: >= v5.6
case errors.Is(err, syscall.EINVAL): // Not supported: < v5.6
case err == nil: // Supported and no error
poll.CloseFunc(s)
fallthrough
default:
// another error: MPTCP was not available but it might be later
mptcpAvailable = true
}
}
7 changes: 7 additions & 0 deletions src/net/mptcpsock_stub.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// 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.

//go:build !linux

package net

0 comments on commit 59d7c69

Please sign in to comment.