From 29407c90b66605360df8698979eb90640671bf23 Mon Sep 17 00:00:00 2001 From: sagitchu Date: Tue, 21 Apr 2026 11:33:41 +0800 Subject: [PATCH] perf(kcp): optimize tunnel transport defaults for high throughput - Set KCP mode to fast3 (NoDelay:1, Interval:10ms) for lower latency - Double SndWnd/RcvWnd from 1024 to 2048 for higher BDP - Disable FEC (datashard:0, parityshard:0) to eliminate 30% overhead - Disable compression for tunnel transport - Increase relay mux MaxStreamBuffer to 2MB for better UDP throughput - Add kcp.datashard/kcp.parityshard metadata keys support Before: 210Mbps TCP / 35Mbps UDP (93% loss) After: should approach direct-connection speed (~400Mbps+) --- go-backend/internal/http/handler/mutations.go | 34 ++++++++++++++++--- go-gost/x/dialer/kcp/metadata.go | 6 ++++ go-gost/x/listener/kcp/metadata.go | 6 ++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/go-backend/internal/http/handler/mutations.go b/go-backend/internal/http/handler/mutations.go index 42fb10c..fc98f98 100644 --- a/go-backend/internal/http/handler/mutations.go +++ b/go-backend/internal/http/handler/mutations.go @@ -3457,9 +3457,15 @@ func buildTunnelChainConfig(tunnelID int64, fromNodeID int64, targets []tunnelRu connectorMetadata["nodelay"] = true connectorMetadata["mux.keepaliveInterval"] = "15s" connectorMetadata["mux.keepaliveTimeout"] = "45s" + connectorMetadata["mux.maxFrameSize"] = 32768 + connectorMetadata["mux.maxStreamBuffer"] = 2097152 } if isKCPTunnelProtocol(protocol) { connectorMetadata["connectTimeout"] = "30s" + connectorMetadata["mux.keepaliveInterval"] = "15s" + connectorMetadata["mux.keepaliveTimeout"] = "45s" + connectorMetadata["mux.maxFrameSize"] = 32768 + connectorMetadata["mux.maxStreamBuffer"] = 2097152 } if len(connectorMetadata) > 0 { connector["metadata"] = connectorMetadata @@ -3505,9 +3511,15 @@ func buildTunnelChainServiceConfig(tunnelID int64, chainNode tunnelRuntimeNode, handlerMetadata["nodelay"] = true handlerMetadata["mux.keepaliveInterval"] = "15s" handlerMetadata["mux.keepaliveTimeout"] = "45s" + handlerMetadata["mux.maxFrameSize"] = 32768 + handlerMetadata["mux.maxStreamBuffer"] = 2097152 } if isKCPTunnelProtocol(protocol) { handlerMetadata["connectTimeout"] = "30s" + handlerMetadata["mux.keepaliveInterval"] = "15s" + handlerMetadata["mux.keepaliveTimeout"] = "45s" + handlerMetadata["mux.maxFrameSize"] = 32768 + handlerMetadata["mux.maxStreamBuffer"] = 2097152 } if len(handlerMetadata) > 0 { handlerCfg["metadata"] = handlerMetadata @@ -3621,8 +3633,15 @@ func buildTunnelDialerConfig(protocol string) map[string]interface{} { } if isKCPTunnelProtocol(protocol) { dialer["metadata"] = map[string]interface{}{ - "kcp.keepalive": 10, - "kcp.tcp": false, + "kcp.keepalive": 10, + "kcp.tcp": false, + "kcp.mode": "fast3", + "kcp.sndwnd": 2048, + "kcp.rcvwnd": 2048, + "kcp.mtu": 1400, + "kcp.datashard": 0, + "kcp.parityshard": 0, + "kcp.nocomp": true, } } return dialer @@ -3634,8 +3653,15 @@ func buildTunnelListenerConfig(protocol string) map[string]interface{} { } if isKCPTunnelProtocol(protocol) { listener["metadata"] = map[string]interface{}{ - "kcp.keepalive": 10, - "kcp.tcp": false, + "kcp.keepalive": 10, + "kcp.tcp": false, + "kcp.mode": "fast3", + "kcp.sndwnd": 2048, + "kcp.rcvwnd": 2048, + "kcp.mtu": 1400, + "kcp.datashard": 0, + "kcp.parityshard": 0, + "kcp.nocomp": true, } } return listener diff --git a/go-gost/x/dialer/kcp/metadata.go b/go-gost/x/dialer/kcp/metadata.go index c544eda..b587727 100644 --- a/go-gost/x/dialer/kcp/metadata.go +++ b/go-gost/x/dialer/kcp/metadata.go @@ -85,6 +85,12 @@ func (d *kcpDialer) parseMetadata(md mdata.Metadata) (err error) { if md.IsExists("kcp.nocomp") { d.md.config.NoComp = mdutil.GetBool(md, "kcp.nocomp") } + if md.IsExists("kcp.datashard") { + d.md.config.DataShard = mdutil.GetInt(md, "kcp.datashard") + } + if md.IsExists("kcp.parityshard") { + d.md.config.ParityShard = mdutil.GetInt(md, "kcp.parityshard") + } } d.md.handshakeTimeout = mdutil.GetDuration(md, handshakeTimeout) diff --git a/go-gost/x/listener/kcp/metadata.go b/go-gost/x/listener/kcp/metadata.go index 5b7ce9b..7c091e5 100644 --- a/go-gost/x/listener/kcp/metadata.go +++ b/go-gost/x/listener/kcp/metadata.go @@ -88,6 +88,12 @@ func (l *kcpListener) parseMetadata(md mdata.Metadata) (err error) { if md.IsExists("kcp.nocomp") { l.md.config.NoComp = mdutil.GetBool(md, "kcp.nocomp") } + if md.IsExists("kcp.datashard") { + l.md.config.DataShard = mdutil.GetInt(md, "kcp.datashard") + } + if md.IsExists("kcp.parityshard") { + l.md.config.ParityShard = mdutil.GetInt(md, "kcp.parityshard") + } } l.md.backlog = mdutil.GetInt(md, backlog)