Implement remote side buffer control.

This commit is contained in:
notsure2 2023-12-08 08:59:09 +02:00
parent 63e4b35a71
commit c0f7e8ff1f
3 changed files with 42 additions and 6 deletions

View File

@ -119,9 +119,14 @@ This field also has no effect if `AdminUID` isn't a valid UID or is empty.
upstream proxy server. Zero or negative value disables it. Default is 0 (disabled).
`LoopbackTcpSendBuffer` is the number of bytes to use for the tcp loopback send buffer. Use a low value like 4096 for a server-to-server bridge.
`LoopbackTcpReceiveBuffer` is the number of bytes to use for the tcp loopback receive buffer. Use a low value like 4096 for a server-to-server bridge.
These 2 options are not normally needed except when setting up a tcp server-to-server bridge using a shadowsocks or similar tcp server in the `ProxyBook` to reduce tcp performance degradation due to bufferbloat across the bridge.
`RemoteTcpSendBuffer` is the number of bytes to use for the tcp remote send buffer. Use a low value like 4096 for a server-to-server bridge.
`RemoteTcpReceiveBuffer` is the number of bytes to use for the tcp remote receive buffer. Use a low value like 4096 for a server-to-server bridge.
These 4 options are not normally needed except when setting up a tcp server-to-server bridge using a shadowsocks or similar tcp server in the `ProxyBook` to reduce tcp performance degradation due to bufferbloat across the bridge.
### Client

View File

@ -32,6 +32,9 @@ func MakeSession(connConfig RemoteConnConfig, authInfo AuthInfo, dialer common.D
goto makeconn
}
sendBufferSize := connConfig.TcpSendBuffer
receiveBufferSize := connConfig.TcpReceiveBuffer
tcpConn, ok := remoteConn.(*net.TCPConn)
if ok {
syscallConn, err := tcpConn.SyscallConn()
@ -40,6 +43,22 @@ func MakeSession(connConfig RemoteConnConfig, authInfo AuthInfo, dialer common.D
}
err = syscallConn.Control(func(fd uintptr) {
if sendBufferSize > 0 {
log.Debugf("Setting remote connection tcp send buffer: %d", sendBufferSize)
err := syscall.SetsockoptInt(common.Platformfd(fd), syscall.SOL_SOCKET, syscall.SO_SNDBUF, sendBufferSize)
if err != nil {
log.Errorf("setsocketopt SO_SNDBUF: %s\n", err)
}
}
if receiveBufferSize > 0 {
log.Debugf("Setting remote connection tcp receive buffer: %d", receiveBufferSize)
err = syscall.SetsockoptInt(common.Platformfd(fd), syscall.SOL_SOCKET, syscall.SO_RCVBUF, receiveBufferSize)
if err != nil {
log.Errorf("setsocketopt SO_RCVBUF: %s\n", err)
}
}
err = syscall.SetsockoptInt(common.Platformfd(fd), syscall.IPPROTO_TCP, syscall.TCP_NODELAY, 1)
if err != nil {
log.Errorf("setsocketopt TCP_NODELAY: %s\n", err)

View File

@ -42,14 +42,18 @@ type RawConfig struct {
KeepAlive int // nullable
LoopbackTcpSendBuffer int // nullable
LoopbackTcpReceiveBuffer int // nullable
RemoteTcpSendBuffer int // nullable
RemoteTcpReceiveBuffer int // nullable
}
type RemoteConnConfig struct {
Singleplex bool
NumConn int
KeepAlive time.Duration
RemoteAddr string
TransportMaker func() Transport
Singleplex bool
NumConn int
KeepAlive time.Duration
RemoteAddr string
TransportMaker func() Transport
TcpSendBuffer int
TcpReceiveBuffer int
}
type LocalConnConfig struct {
@ -291,5 +295,13 @@ func (raw *RawConfig) ProcessRawConfig(worldState common.WorldState) (local Loca
local.TcpReceiveBuffer = raw.LoopbackTcpReceiveBuffer
}
if raw.RemoteTcpSendBuffer > 0 {
remote.TcpSendBuffer = raw.RemoteTcpSendBuffer
}
if raw.RemoteTcpReceiveBuffer > 0 {
remote.TcpReceiveBuffer = raw.RemoteTcpReceiveBuffer
}
return
}