From 786607d31ef3c1348887eb8d2415b6da4d760331 Mon Sep 17 00:00:00 2001 From: notsure2 Date: Thu, 5 Jan 2023 06:14:25 +0200 Subject: [PATCH] When dialing a localhost connection, set a small send and receive buffer on the socket to 32 KB to avoid bufferbloat in TCP relays. --- internal/server/platformfd_linux.go | 8 ++++++ internal/server/platformfd_windows.go | 10 ++++++++ internal/server/state.go | 36 +++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 internal/server/platformfd_linux.go create mode 100644 internal/server/platformfd_windows.go diff --git a/internal/server/platformfd_linux.go b/internal/server/platformfd_linux.go new file mode 100644 index 0000000..d0815c4 --- /dev/null +++ b/internal/server/platformfd_linux.go @@ -0,0 +1,8 @@ +//go:build linux +// +build linux + +package server + +func platformfd(fd uintptr) int { + return int(fd) +} diff --git a/internal/server/platformfd_windows.go b/internal/server/platformfd_windows.go new file mode 100644 index 0000000..bb14a46 --- /dev/null +++ b/internal/server/platformfd_windows.go @@ -0,0 +1,10 @@ +//go:build windows +// +build windows + +package server + +import "syscall" + +func platformfd(fd uintptr) syscall.Handle { + return syscall.Handle(fd) +} diff --git a/internal/server/state.go b/internal/server/state.go index 03d9298..aefae67 100644 --- a/internal/server/state.go +++ b/internal/server/state.go @@ -7,10 +7,12 @@ import ( "fmt" "github.com/cbeuw/Cloak/internal/common" "github.com/cbeuw/Cloak/internal/server/usermanager" + log "github.com/sirupsen/logrus" "io/ioutil" "net" "strings" "sync" + "syscall" "time" ) @@ -155,10 +157,40 @@ func InitState(preParse RawConfig, worldState common.WorldState) (sta *State, er sta.Panel = MakeUserPanel(manager) } + dialerControl := func(network, address string, c syscall.RawConn) error { + if !strings.HasPrefix(network, "tcp") { + return nil + } + + ips, err := net.LookupHost(strings.Split(address, ":")[0]) + if err != nil { + return err + } + + for _, ipString := range ips { + ip := net.ParseIP(ipString) + if !ip.IsLoopback() { + return nil + } + } + + return c.Control(func(fd uintptr) { + err := syscall.SetsockoptInt(platformfd(fd), syscall.SOL_SOCKET, syscall.SO_SNDBUF, 32*1024) + if err != nil { + log.Println("setsocketopt SO_SNDBUF: ", err) + } + + err = syscall.SetsockoptInt(platformfd(fd), syscall.SOL_SOCKET, syscall.SO_RCVBUF, 32*1024) + if err != nil { + log.Println("setsocketopt SO_RCVBUF: ", err) + } + }) + } + if preParse.KeepAlive <= 0 { - sta.ProxyDialer = &net.Dialer{KeepAlive: -1} + sta.ProxyDialer = &net.Dialer{KeepAlive: -1, Control: dialerControl} } else { - sta.ProxyDialer = &net.Dialer{KeepAlive: time.Duration(preParse.KeepAlive) * time.Second} + sta.ProxyDialer = &net.Dialer{KeepAlive: time.Duration(preParse.KeepAlive) * time.Second, Control: dialerControl} } sta.RedirHost, sta.RedirPort, err = parseRedirAddr(preParse.RedirAddr)