fix(xhttp): stop injecting scMaxEachPostBytes/scMinPostsIntervalMs defaults (#5141)

The panel seeded xhttp configs with scMaxEachPostBytes=1000000 and
scMinPostsIntervalMs=30 — xray-core''s own defaults — and emitted them
into every generated config and share link. The literal
scMinPostsIntervalMs=30 is a stable DPI fingerprint that Russia''s TSPU
keys on to block connections on mobile networks.

New configs no longer seed these values (empty schema/template defaults,
so xray-core applies its internal defaults). For configs already stored
with the old defaults, the link/subscription builders now drop values
equal to xray-core''s defaults instead of advertising them — covering
panel share links, the raw subscription, and the JSON subscription
without requiring every inbound to be re-saved. Non-default values the
user set deliberately are still emitted.
This commit is contained in:
MHSanaei
2026-06-12 01:50:37 +02:00
parent 7e87b7dc60
commit 60da6bed15
10 changed files with 44 additions and 13 deletions
+9
View File
@@ -217,6 +217,15 @@ func (s *SubJsonService) streamData(stream string) map[string]any {
delete(xhttp, "scMaxBufferedPosts")
delete(xhttp, "scStreamUpServerSecs")
delete(xhttp, "serverMaxHeaderBytes")
// Values matching xray-core's own defaults stay off the wire:
// old panels seeded them into every stored config and the
// literal scMinPostsIntervalMs=30 is a DPI fingerprint (#5141).
if v, _ := xhttp["scMaxEachPostBytes"].(string); v == "" || v == "1000000" {
delete(xhttp, "scMaxEachPostBytes")
}
if v, _ := xhttp["scMinPostsIntervalMs"].(string); v == "" || v == "30" {
delete(xhttp, "scMinPostsIntervalMs")
}
}
}
return streamSettings
+9 -1
View File
@@ -1661,8 +1661,16 @@ func buildXhttpExtra(xhttp map[string]any) map[string]any {
"uplinkDataPlacement", "uplinkDataKey",
"scMaxEachPostBytes", "scMinPostsIntervalMs",
}
// Values matching xray-core's own defaults are redundant on the wire and
// the literal scMinPostsIntervalMs=30 is a known DPI fingerprint (#5141).
// Old panels seeded these defaults into every xhttp inbound, so filter
// them here instead of requiring every stored config to be re-saved.
coreDefaults := map[string]string{
"scMaxEachPostBytes": "1000000",
"scMinPostsIntervalMs": "30",
}
for _, field := range stringFields {
if v, ok := xhttp[field].(string); ok && len(v) > 0 {
if v, ok := xhttp[field].(string); ok && len(v) > 0 && v != coreDefaults[field] {
extra[field] = v
}
}
+3 -1
View File
@@ -545,9 +545,11 @@ func buildStream(network, security string) map[string]any {
case "httpupgrade":
stream["httpupgradeSettings"] = map[string]any{"path": "/", "host": "", "headers": map[string]any{}}
case "xhttp":
// No scMaxEachPostBytes/scMinPostsIntervalMs seed: xray-core's own
// defaults apply, and the literal values fingerprint traffic (#5141).
stream["xhttpSettings"] = map[string]any{
"path": "/", "host": "", "mode": "auto", "headers": map[string]any{},
"xPaddingBytes": "100-1000", "scMaxEachPostBytes": "1000000",
"xPaddingBytes": "100-1000",
}
default:
stream["tcpSettings"] = map[string]any{"header": map[string]any{"type": "none"}}