[client] Disable gVisor TCP RACK loss detection on Windows (#6808)

This commit is contained in:
Viktor Liu
2026-07-17 10:45:30 +02:00
committed by GitHub
parent 099ae4bc6c
commit 6e3f4d8722
3 changed files with 40 additions and 3 deletions
@@ -5,7 +5,9 @@ import (
"fmt"
"net"
"net/netip"
"os"
"runtime"
"strconv"
"sync"
"time"
@@ -31,6 +33,11 @@ const (
defaultMaxInFlight = 1024
iosReceiveWindow = 16384
iosMaxInFlight = 256
// envForceTCPRACK overrides the platform default for gVisor's RACK loss
// detection. Set to a truthy value to force RACK on, or a falsy value to
// force it off, on any platform.
envForceTCPRACK = "NB_FORCE_TCP_RACK"
)
type Forwarder struct {
@@ -152,6 +159,8 @@ func New(iface common.IFaceMapper, logger *nblog.Logger, flowLogger nftypes.Flow
maxInFlight = iosMaxInFlight
}
configureTCPRecovery(s)
tcpForwarder := tcp.NewForwarder(s, receiveWindow, maxInFlight, f.handleTCP)
s.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket)
@@ -466,3 +475,31 @@ func probeRawICMP(network, addr string, logger *nblog.Logger) bool {
logger.Debug1("forwarder: raw %s socket access available", network)
return true
}
// configureTCPRecovery disables gVisor's RACK loss detection on Windows, where
// it interacts poorly with the host and collapses throughput on routed TCP
// connections (gVisor issue #9778). Other platforms keep the default. The
// EnvForceTCPRACK environment variable overrides the platform default.
func configureTCPRecovery(s *stack.Stack) {
disableRACK := runtime.GOOS == "windows"
if val := os.Getenv(envForceTCPRACK); val != "" {
force, err := strconv.ParseBool(val)
if err != nil {
log.Warnf("parse %s: %v", envForceTCPRACK, err)
} else {
disableRACK = !force
}
}
if !disableRACK {
return
}
opt := tcpip.TCPRecovery(0)
if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil {
log.Warnf("disable TCP RACK loss detection: %v", err)
return
}
log.Info("forwarder: TCP RACK loss detection disabled")
}