github.com/sagernet/sing-mux@v0.2.1-0.20240124034317-9bfb33698bb6/brutal_linux.go (about)

     1  package mux
     2  
     3  import (
     4  	"net"
     5  	"os"
     6  	"reflect"
     7  	"syscall"
     8  	"unsafe"
     9  	_ "unsafe"
    10  
    11  	"github.com/sagernet/sing/common"
    12  	"github.com/sagernet/sing/common/control"
    13  	E "github.com/sagernet/sing/common/exceptions"
    14  
    15  	"golang.org/x/sys/unix"
    16  )
    17  
    18  const (
    19  	BrutalAvailable   = true
    20  	TCP_BRUTAL_PARAMS = 23301
    21  )
    22  
    23  type TCPBrutalParams struct {
    24  	Rate     uint64
    25  	CwndGain uint32
    26  }
    27  
    28  //go:linkname setsockopt syscall.setsockopt
    29  func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
    30  
    31  func SetBrutalOptions(conn net.Conn, sendBPS uint64) error {
    32  	syscallConn, loaded := common.Cast[syscall.Conn](conn)
    33  	if !loaded {
    34  		return E.New(
    35  			"brutal: nested multiplexing is not supported: ",
    36  			"cannot convert ", reflect.TypeOf(conn), " to syscall.Conn, final type: ", reflect.TypeOf(common.Top(conn)),
    37  		)
    38  	}
    39  	return control.Conn(syscallConn, func(fd uintptr) error {
    40  		err := unix.SetsockoptString(int(fd), unix.IPPROTO_TCP, unix.TCP_CONGESTION, "brutal")
    41  		if err != nil {
    42  			return E.Extend(
    43  				os.NewSyscallError("setsockopt IPPROTO_TCP TCP_CONGESTION brutal", err),
    44  				"please make sure you have installed the tcp-brutal kernel module",
    45  			)
    46  		}
    47  		params := TCPBrutalParams{
    48  			Rate:     sendBPS,
    49  			CwndGain: 20, // hysteria2 default
    50  		}
    51  		err = setsockopt(int(fd), unix.IPPROTO_TCP, TCP_BRUTAL_PARAMS, unsafe.Pointer(&params), unsafe.Sizeof(params))
    52  		if err != nil {
    53  			return os.NewSyscallError("setsockopt IPPROTO_TCP TCP_BRUTAL_PARAMS", err)
    54  		}
    55  		return nil
    56  	})
    57  }