]> Cypherpunks.ru repositories - gostls13.git/commitdiff
net: mptcp: implement listenMPTCP
authorMatthieu Baerts <matthieu.baerts@tessares.net>
Fri, 24 Feb 2023 16:51:58 +0000 (17:51 +0100)
committerGopher Robot <gobot@golang.org>
Wed, 29 Mar 2023 22:12:20 +0000 (22:12 +0000)
Similar to dialMPTCP, this listenMPTCP function is called when the user
has requested MPTCP via SetMultipathTCP in the ListenConfig.

This function falls back to listenTCP on operating systems that do not
support MPTCP or if MPTCP is not supported.

On ListenConfig side, MultipathTCP function can be used to know if the
package will try to use MPTCP or not when Listen is called.

Note that this new listenMPTCP function returns a TCPListener object and
not a new MPTCP dedicated one. The reasons are similar as the ones
explained in the parent commit introducing dialTCP: if MPTCP is used by
default later, Listen will return a different object that could break
existing applications expecting TCPListener.

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

Updates #56539

Change-Id: I010f1d87f921bbac9e157cef2212c51917852353
Reviewed-on: https://go-review.googlesource.com/c/go/+/471137
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
api/next/56539.txt
src/net/dial.go
src/net/mptcpsock_linux.go
src/net/mptcpsock_stub.go
src/net/tcpsock_posix.go

index ad1dfb72510464c0388a09a6434c659d42348586..65d0418aff1a7279d44db79e8d981ee6a029fe55 100644 (file)
@@ -1,2 +1,4 @@
 pkg net, method (*Dialer) MultipathTCP() bool #56539
 pkg net, method (*Dialer) SetMultipathTCP(bool) #56539
+pkg net, method (*ListenConfig) MultipathTCP() bool #56539
+pkg net, method (*ListenConfig) SetMultipathTCP(bool) #56539
index 3cc8f840c5fcf71e040b8e4142d5b46602388d0e..58e3b392d959adc6e8947253fc7a3b7fe4b00a33 100644 (file)
@@ -673,6 +673,29 @@ type ListenConfig struct {
        // that do not support keep-alives ignore this field.
        // If negative, keep-alives are disabled.
        KeepAlive time.Duration
+
+       // If mptcpStatus is set to a value allowing Multipath TCP (MPTCP) to be
+       // used, any call to Listen with "tcp(4|6)" as network will use MPTCP if
+       // supported by the operating system.
+       mptcpStatus mptcpStatus
+}
+
+// MultipathTCP reports whether MPTCP will be used.
+//
+// This method doesn't check if MPTCP is supported by the operating
+// system or not.
+func (lc *ListenConfig) MultipathTCP() bool {
+       return lc.mptcpStatus.get()
+}
+
+// SetMultipathTCP directs the Listen method to use, or not use, MPTCP,
+// if supported by the operating system. This method overrides the
+// system default.
+//
+// If MPTCP is not available on the host or not supported by the client,
+// the Listen method will fall back to TCP.
+func (lc *ListenConfig) SetMultipathTCP(use bool) {
+       lc.mptcpStatus.set(use)
 }
 
 // Listen announces on the local network address.
@@ -693,7 +716,11 @@ func (lc *ListenConfig) Listen(ctx context.Context, network, address string) (Li
        la := addrs.first(isIPv4)
        switch la := la.(type) {
        case *TCPAddr:
-               l, err = sl.listenTCP(ctx, la)
+               if sl.MultipathTCP() {
+                       l, err = sl.listenMPTCP(ctx, la)
+               } else {
+                       l, err = sl.listenTCP(ctx, la)
+               }
        case *UnixAddr:
                l, err = sl.listenUnix(ctx, la)
        default:
index a1c3805795459b78814d75f142f0443a4a82ee97..4663d28b4b419785fcaa7b1291b606022d3ca923 100644 (file)
@@ -51,3 +51,12 @@ func (sd *sysDialer) dialMPTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCP
 
        return sd.doDialTCPProto(ctx, laddr, raddr, _IPPROTO_MPTCP)
 }
+
+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)
+       }
+
+       return sl.listenTCPProto(ctx, laddr, _IPPROTO_MPTCP)
+}
index 62f5d4973137174389c67e2d5e9d57d2024d93cf..ae06772896a338a9ce51cf46050fb60c304aa352 100644 (file)
@@ -13,3 +13,7 @@ import (
 func (sd *sysDialer) dialMPTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
        return sd.dialTCP(ctx, laddr, raddr)
 }
+
+func (sl *sysListener) listenMPTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
+       return sl.listenTCP(ctx, laddr)
+}
index f8d4b3e4d0e434f0215d2b9efa321eeacded599b..ed144a6ddc2b85b1f70e5271ab88192103ea10da 100644 (file)
@@ -169,13 +169,17 @@ func (ln *TCPListener) file() (*os.File, error) {
 }
 
 func (sl *sysListener) listenTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
+       return sl.listenTCPProto(ctx, laddr, 0)
+}
+
+func (sl *sysListener) listenTCPProto(ctx context.Context, laddr *TCPAddr, proto int) (*TCPListener, error) {
        var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
        if sl.ListenConfig.Control != nil {
                ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
                        return sl.ListenConfig.Control(network, address, c)
                }
        }
-       fd, err := internetSocket(ctx, sl.network, laddr, nil, syscall.SOCK_STREAM, 0, "listen", ctrlCtxFn)
+       fd, err := internetSocket(ctx, sl.network, laddr, nil, syscall.SOCK_STREAM, proto, "listen", ctrlCtxFn)
        if err != nil {
                return nil, err
        }