diff --git a/admin/assets/js/08-server-config.js b/admin/assets/js/08-server-config.js index 3400c97..111cbe3 100644 --- a/admin/assets/js/08-server-config.js +++ b/admin/assets/js/08-server-config.js @@ -29,49 +29,25 @@ function toggleUdpgwFields(on) { } +// Only operator-safe knobs remain. Transport buffers (HTTP/2 flow control, XHTTP +// reorder buffer, mux/UDP buffers) are fixed to xray-core defaults in the backend +// and are no longer exposed here, so they cannot be misconfigured. const XRAY_NATIVE_TUNING_DEFAULTS = { safe: { runtime_gomaxprocs: 0, - mux_max_sessions: 64, mux_global_sessions: 8192, - mux_udp_idle_ms: 120000, - mux_udp_read_buffer: 131072, - mux_udp_write_buffer: 131072, - xhttp_max_sessions: 4096, - xhttp_buffered_posts: 128, - h2_max_concurrent_streams: 256, - h2_upload_buffer_conn: 1048576, - h2_upload_buffer_stream: 262144, trace_packets: false, }, "2k": { runtime_gomaxprocs: 0, - mux_max_sessions: 128, mux_global_sessions: 32768, - mux_udp_idle_ms: 120000, - mux_udp_read_buffer: 262144, - mux_udp_write_buffer: 262144, - xhttp_max_sessions: 16384, - xhttp_buffered_posts: 256, - h2_max_concurrent_streams: 1024, - h2_upload_buffer_conn: 1048576, - h2_upload_buffer_stream: 262144, trace_packets: false, }, }; const XRAY_NATIVE_TUNING_FIELDS = { runtime_gomaxprocs: "cfgXrayRuntimeGomaxprocs", - mux_max_sessions: "cfgXrayMuxMaxSessions", mux_global_sessions: "cfgXrayMuxGlobalSessions", - mux_udp_idle_ms: "cfgXrayMuxUdpIdleMs", - mux_udp_read_buffer: "cfgXrayMuxUdpRbuf", - mux_udp_write_buffer: "cfgXrayMuxUdpWbuf", - xhttp_max_sessions: "cfgXrayXhttpMaxSessions", - xhttp_buffered_posts: "cfgXrayXhttpBufferedPosts", - h2_max_concurrent_streams: "cfgXrayH2MaxStreams", - h2_upload_buffer_conn: "cfgXrayH2UploadConn", - h2_upload_buffer_stream: "cfgXrayH2UploadStream", }; function setXrayNativeTuningDefaults(profile = "2k") { diff --git a/admin/index.html b/admin/index.html index 9d2fd95..eca7eb6 100644 --- a/admin/index.html +++ b/admin/index.html @@ -1192,22 +1192,13 @@ Native Xray scale tuning
-
-
-
-
-
-
-
-
-
-
These values are saved in the panel config and applied live on restart/reload. Go CPU threads = 0 means all detected CPU cores. No systemd Environment lines are needed.
+
Transport buffers (HTTP/2 flow control, XHTTP reorder buffer, mux/UDP buffers) are fixed to xray-core defaults and no longer tunable, so they can't be misconfigured. Go CPU threads = 0 means all detected cores. Saved in the panel config and applied live on restart/reload.
diff --git a/xray_native_tuning.go b/xray_native_tuning.go index 71f2943..98724bc 100644 --- a/xray_native_tuning.go +++ b/xray_native_tuning.go @@ -6,53 +6,45 @@ import ( "time" ) -// XrayNativeTuning contains native-emulator performance limits that are edited -// from the admin panel and saved in config.json under xray.native_tuning. -// Values are process/runtime settings, not generated Xray JSON settings. +// XrayNativeTuning holds the few operator-facing knobs for the in-process native +// Xray. Transport-shaping parameters (HTTP/2 flow control, the XHTTP reorder +// buffer, mux/UDP socket buffers) are intentionally NOT exposed: they are pinned +// to xray-core / Go defaults so they cannot be misconfigured into breakage. Only +// safe operational controls remain here: CPU parallelism, a global mux-session +// DoS cap, and a packet-level trace toggle for debugging. type XrayNativeTuning struct { - // RuntimeGOMAXPROCS controls Go CPU parallelism for the in-process native Xray. - // 0 or negative means use all detected CPU cores. - RuntimeGOMAXPROCS int `json:"runtime_gomaxprocs,omitempty"` - MuxMaxSessions int `json:"mux_max_sessions,omitempty"` - MuxGlobalSessions int `json:"mux_global_sessions,omitempty"` - MuxUDPIdleMS int `json:"mux_udp_idle_ms,omitempty"` - MuxUDPReadBuffer int `json:"mux_udp_read_buffer,omitempty"` - MuxUDPWriteBuffer int `json:"mux_udp_write_buffer,omitempty"` - XHTTPMaxSessions int `json:"xhttp_max_sessions,omitempty"` - XHTTPBufferedPosts int `json:"xhttp_buffered_posts,omitempty"` - H2MaxConcurrentStreams int `json:"h2_max_concurrent_streams,omitempty"` - H2UploadBufferConn int `json:"h2_upload_buffer_conn,omitempty"` - H2UploadBufferStream int `json:"h2_upload_buffer_stream,omitempty"` - TracePackets bool `json:"trace_packets,omitempty"` + // RuntimeGOMAXPROCS controls Go CPU parallelism. 0 or negative = all cores. + RuntimeGOMAXPROCS int `json:"runtime_gomaxprocs,omitempty"` + // MuxGlobalSessions caps total concurrent mux child sessions across every + // client connection (a DoS guard for the multi-tenant panel). 0 = default. + MuxGlobalSessions int `json:"mux_global_sessions,omitempty"` + // TracePackets enables very verbose per-packet XHTTP/mux logging. Debug only. + TracePackets bool `json:"trace_packets,omitempty"` } const ( - defaultNativeRuntimeGOMAXPROCS = 0 - defaultNativeMuxMaxSessions = 128 - defaultNativeMuxGlobalSessions = 32768 - defaultNativeMuxUDPIdleMS = 120000 - defaultNativeMuxUDPReadBuffer = 256 * 1024 - defaultNativeMuxUDPWriteBuffer = 256 * 1024 - defaultNativeXHTTPMaxSessions = 16384 - defaultNativeXHTTPBufferedPosts = 256 - defaultNativeH2MaxConcurrentStreams = 1024 - defaultNativeH2UploadBufferConn = 1 * 1024 * 1024 - defaultNativeH2UploadBufferStream = 256 * 1024 + defaultNativeRuntimeGOMAXPROCS = 0 + defaultNativeMuxGlobalSessions = 32768 + + // Fixed transport defaults, aligned with xray-core / Go's net/http2. These are + // deliberately not operator-tunable: wrong values silently break data flow. + fixedNativeMuxMaxSessions = 128 // per-connection mux child-session guard + fixedNativeMuxUDPIdleMS = 120000 // mux UDP backend idle cleanup (ms) + fixedNativeMuxUDPReadBuffer = 256 * 1024 // mux UDP socket read buffer + fixedNativeMuxUDPWriteBuffer = 256 * 1024 // mux UDP socket write buffer + + // XHTTP: max tracked sessions (DoS guard) and the packet-up reorder buffer. + // defaultNativeXHTTPBufferedPosts matches xray-core's scMaxBufferedPosts + // default; the per-inbound scMaxBufferedPosts from the config still overrides + // it, exactly like upstream. + defaultNativeXHTTPMaxSessions = 16384 + defaultNativeXHTTPBufferedPosts = 30 ) var ( - nativeTuneRuntimeGOMAXPROCS atomic.Int64 - nativeTuneMuxMaxSessions atomic.Int64 - nativeTuneMuxGlobalSessions atomic.Int64 - nativeTuneMuxUDPIdleMS atomic.Int64 - nativeTuneMuxUDPReadBuffer atomic.Int64 - nativeTuneMuxUDPWriteBuffer atomic.Int64 - nativeTuneXHTTPMaxSessions atomic.Int64 - nativeTuneXHTTPBufferedPosts atomic.Int64 - nativeTuneH2MaxConcurrentStreams atomic.Int64 - nativeTuneH2UploadBufferConn atomic.Int64 - nativeTuneH2UploadBufferStream atomic.Int64 - nativeTuneTracePackets atomic.Bool + nativeTuneRuntimeGOMAXPROCS atomic.Int64 + nativeTuneMuxGlobalSessions atomic.Int64 + nativeTuneTracePackets atomic.Bool ) func init() { @@ -67,36 +59,9 @@ func normalizeNativeXrayTuning(t *XrayNativeTuning) XrayNativeTuning { if out.RuntimeGOMAXPROCS < 0 { out.RuntimeGOMAXPROCS = defaultNativeRuntimeGOMAXPROCS } - if out.MuxMaxSessions <= 0 { - out.MuxMaxSessions = defaultNativeMuxMaxSessions - } if out.MuxGlobalSessions <= 0 { out.MuxGlobalSessions = defaultNativeMuxGlobalSessions } - if out.MuxUDPIdleMS <= 0 { - out.MuxUDPIdleMS = defaultNativeMuxUDPIdleMS - } - if out.MuxUDPReadBuffer <= 0 { - out.MuxUDPReadBuffer = defaultNativeMuxUDPReadBuffer - } - if out.MuxUDPWriteBuffer <= 0 { - out.MuxUDPWriteBuffer = defaultNativeMuxUDPWriteBuffer - } - if out.XHTTPMaxSessions <= 0 { - out.XHTTPMaxSessions = defaultNativeXHTTPMaxSessions - } - if out.XHTTPBufferedPosts <= 0 { - out.XHTTPBufferedPosts = defaultNativeXHTTPBufferedPosts - } - if out.H2MaxConcurrentStreams <= 0 { - out.H2MaxConcurrentStreams = defaultNativeH2MaxConcurrentStreams - } - if out.H2UploadBufferConn <= 0 { - out.H2UploadBufferConn = defaultNativeH2UploadBufferConn - } - if out.H2UploadBufferStream <= 0 { - out.H2UploadBufferStream = defaultNativeH2UploadBufferStream - } return out } @@ -111,31 +76,22 @@ func applyNativeXrayTuning(t *XrayNativeTuning) XrayNativeTuning { } runtime.GOMAXPROCS(gomax) nativeTuneRuntimeGOMAXPROCS.Store(int64(gomax)) - nativeTuneMuxMaxSessions.Store(int64(out.MuxMaxSessions)) nativeTuneMuxGlobalSessions.Store(int64(out.MuxGlobalSessions)) - nativeTuneMuxUDPIdleMS.Store(int64(out.MuxUDPIdleMS)) - nativeTuneMuxUDPReadBuffer.Store(int64(out.MuxUDPReadBuffer)) - nativeTuneMuxUDPWriteBuffer.Store(int64(out.MuxUDPWriteBuffer)) - nativeTuneXHTTPMaxSessions.Store(int64(out.XHTTPMaxSessions)) - nativeTuneXHTTPBufferedPosts.Store(int64(out.XHTTPBufferedPosts)) - nativeTuneH2MaxConcurrentStreams.Store(int64(out.H2MaxConcurrentStreams)) - nativeTuneH2UploadBufferConn.Store(int64(out.H2UploadBufferConn)) - nativeTuneH2UploadBufferStream.Store(int64(out.H2UploadBufferStream)) nativeTuneTracePackets.Store(out.TracePackets) return out } +// Operator-tunable values. func nativeRuntimeGOMAXPROCS() int { return int(nativeTuneRuntimeGOMAXPROCS.Load()) } -func nativeMuxMaxSessionLimit() int { return int(nativeTuneMuxMaxSessions.Load()) } func nativeMuxGlobalSessionLimit() int { return int(nativeTuneMuxGlobalSessions.Load()) } +func nativeTracePacketsEnabled() bool { return nativeTuneTracePackets.Load() } + +// Fixed transport limits (see the const block for rationale). +func nativeMuxMaxSessionLimit() int { return fixedNativeMuxMaxSessions } +func nativeMuxUDPReadBufferSize() int { return fixedNativeMuxUDPReadBuffer } +func nativeMuxUDPWriteBufferSize() int { return fixedNativeMuxUDPWriteBuffer } +func nativeXHTTPMaxSessionLimit() int { return defaultNativeXHTTPMaxSessions } +func nativeXHTTPBufferedPostLimit() int { return defaultNativeXHTTPBufferedPosts } func nativeMuxUDPIdleTimeout() time.Duration { - return time.Duration(nativeTuneMuxUDPIdleMS.Load()) * time.Millisecond + return fixedNativeMuxUDPIdleMS * time.Millisecond } -func nativeMuxUDPReadBufferSize() int { return int(nativeTuneMuxUDPReadBuffer.Load()) } -func nativeMuxUDPWriteBufferSize() int { return int(nativeTuneMuxUDPWriteBuffer.Load()) } -func nativeXHTTPMaxSessionLimit() int { return int(nativeTuneXHTTPMaxSessions.Load()) } -func nativeXHTTPBufferedPostLimit() int { return int(nativeTuneXHTTPBufferedPosts.Load()) } -func nativeH2MaxConcurrentStreams() int { return int(nativeTuneH2MaxConcurrentStreams.Load()) } -func nativeH2UploadBufferConn() int { return int(nativeTuneH2UploadBufferConn.Load()) } -func nativeH2UploadBufferStream() int { return int(nativeTuneH2UploadBufferStream.Load()) } -func nativeTracePacketsEnabled() bool { return nativeTuneTracePackets.Load() } diff --git a/xray_xhttp.go b/xray_xhttp.go index 1d4ebb0..9d4bf54 100644 --- a/xray_xhttp.go +++ b/xray_xhttp.go @@ -99,11 +99,9 @@ func mergeNativeXHTTPSettings(primary, fallback nativeXHTTPSettingsJSON) nativeX func (ib *nativeInbound) serveXHTTPListener(ln net.Listener) { defer xrayRecover(fmt.Sprintf("native xray XHTTP listener inbound=%q addr=%s", ib.tag, ln.Addr())) - h2s := &http2.Server{ - MaxConcurrentStreams: uint32(nativeH2MaxConcurrentStreams()), - MaxUploadBufferPerConnection: int32(nativeH2UploadBufferConn()), - MaxUploadBufferPerStream: int32(nativeH2UploadBufferStream()), - } + // Match xray-core: let net/http's HTTP/2 use its own defaults for flow + // control, stream limits and upload buffers instead of overriding them. + h2s := &http2.Server{} handler := http.Handler(ib) // Official Xray accepts plaintext HTTP/1.1 and h2c on non-TLS XHTTP // listeners, and negotiates h2/http1 through ALPN on TLS listeners. Without