// 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 (
	"context"
	"errors"
	"internal/poll"
	"internal/syscall/unix"
	"sync"
	"syscall"
)

var (
	mptcpOnce      sync.Once
	mptcpAvailable bool
	hasSOLMPTCP    bool
)

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

func supportsMultipathTCP() 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 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
	}

	major, minor := unix.KernelVersion()
	// SOL_MPTCP only supported from kernel 5.16
	hasSOLMPTCP = major > 5 || (major == 5 && minor >= 16)
}

func (sd *sysDialer) dialMPTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
	if supportsMultipathTCP() {
		if conn, err := sd.doDialTCPProto(ctx, laddr, raddr, _IPPROTO_MPTCP); err == nil {
			return conn, 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 sd.dialTCP(ctx, laddr, raddr)
}

func (sl *sysListener) listenMPTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
	if supportsMultipathTCP() {
		if dial, err := sl.listenTCPProto(ctx, laddr, _IPPROTO_MPTCP); err == nil {
			return dial, 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 sl.listenTCP(ctx, laddr)
}

// 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 hasFallenBack(fd *netFD) bool {
	_, err := fd.pfd.GetsockoptInt(_SOL_MPTCP, _MPTCP_INFO)

	// 2 expected errors in case of fallback depending on the address family
	//   - AF_INET:  EOPNOTSUPP
	//   - AF_INET6: ENOPROTOOPT
	return err == syscall.EOPNOTSUPP || err == 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 isUsingMPTCPProto(fd *netFD) bool {
	proto, _ := fd.pfd.GetsockoptInt(syscall.SOL_SOCKET, syscall.SO_PROTOCOL)

	return proto == _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 isUsingMultipathTCP(fd *netFD) bool {
	if hasSOLMPTCP {
		return !hasFallenBack(fd)
	}

	return isUsingMPTCPProto(fd)
}
