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+)
This commit is contained in:
sagitchu
2026-04-21 11:33:41 +08:00
parent 37341af2d1
commit 29407c90b6
3 changed files with 42 additions and 4 deletions
+30 -4
View File
@@ -3457,9 +3457,15 @@ func buildTunnelChainConfig(tunnelID int64, fromNodeID int64, targets []tunnelRu
connectorMetadata["nodelay"] = true connectorMetadata["nodelay"] = true
connectorMetadata["mux.keepaliveInterval"] = "15s" connectorMetadata["mux.keepaliveInterval"] = "15s"
connectorMetadata["mux.keepaliveTimeout"] = "45s" connectorMetadata["mux.keepaliveTimeout"] = "45s"
connectorMetadata["mux.maxFrameSize"] = 32768
connectorMetadata["mux.maxStreamBuffer"] = 2097152
} }
if isKCPTunnelProtocol(protocol) { if isKCPTunnelProtocol(protocol) {
connectorMetadata["connectTimeout"] = "30s" connectorMetadata["connectTimeout"] = "30s"
connectorMetadata["mux.keepaliveInterval"] = "15s"
connectorMetadata["mux.keepaliveTimeout"] = "45s"
connectorMetadata["mux.maxFrameSize"] = 32768
connectorMetadata["mux.maxStreamBuffer"] = 2097152
} }
if len(connectorMetadata) > 0 { if len(connectorMetadata) > 0 {
connector["metadata"] = connectorMetadata connector["metadata"] = connectorMetadata
@@ -3505,9 +3511,15 @@ func buildTunnelChainServiceConfig(tunnelID int64, chainNode tunnelRuntimeNode,
handlerMetadata["nodelay"] = true handlerMetadata["nodelay"] = true
handlerMetadata["mux.keepaliveInterval"] = "15s" handlerMetadata["mux.keepaliveInterval"] = "15s"
handlerMetadata["mux.keepaliveTimeout"] = "45s" handlerMetadata["mux.keepaliveTimeout"] = "45s"
handlerMetadata["mux.maxFrameSize"] = 32768
handlerMetadata["mux.maxStreamBuffer"] = 2097152
} }
if isKCPTunnelProtocol(protocol) { if isKCPTunnelProtocol(protocol) {
handlerMetadata["connectTimeout"] = "30s" handlerMetadata["connectTimeout"] = "30s"
handlerMetadata["mux.keepaliveInterval"] = "15s"
handlerMetadata["mux.keepaliveTimeout"] = "45s"
handlerMetadata["mux.maxFrameSize"] = 32768
handlerMetadata["mux.maxStreamBuffer"] = 2097152
} }
if len(handlerMetadata) > 0 { if len(handlerMetadata) > 0 {
handlerCfg["metadata"] = handlerMetadata handlerCfg["metadata"] = handlerMetadata
@@ -3621,8 +3633,15 @@ func buildTunnelDialerConfig(protocol string) map[string]interface{} {
} }
if isKCPTunnelProtocol(protocol) { if isKCPTunnelProtocol(protocol) {
dialer["metadata"] = map[string]interface{}{ dialer["metadata"] = map[string]interface{}{
"kcp.keepalive": 10, "kcp.keepalive": 10,
"kcp.tcp": false, "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 return dialer
@@ -3634,8 +3653,15 @@ func buildTunnelListenerConfig(protocol string) map[string]interface{} {
} }
if isKCPTunnelProtocol(protocol) { if isKCPTunnelProtocol(protocol) {
listener["metadata"] = map[string]interface{}{ listener["metadata"] = map[string]interface{}{
"kcp.keepalive": 10, "kcp.keepalive": 10,
"kcp.tcp": false, "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 return listener
+6
View File
@@ -85,6 +85,12 @@ func (d *kcpDialer) parseMetadata(md mdata.Metadata) (err error) {
if md.IsExists("kcp.nocomp") { if md.IsExists("kcp.nocomp") {
d.md.config.NoComp = mdutil.GetBool(md, "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) d.md.handshakeTimeout = mdutil.GetDuration(md, handshakeTimeout)
+6
View File
@@ -88,6 +88,12 @@ func (l *kcpListener) parseMetadata(md mdata.Metadata) (err error) {
if md.IsExists("kcp.nocomp") { if md.IsExists("kcp.nocomp") {
l.md.config.NoComp = mdutil.GetBool(md, "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) l.md.backlog = mdutil.GetInt(md, backlog)