3x-ui/subproject/Xray-core-main/infra/conf/policy.go
test999 367152556a **Fixes & Changes:**
1. **Fixed XPadding Placement Dropdown**:
   - Added the missing `cookie` and `query` options to `xPaddingPlacement` (`stream_xhttp.html`).
   - *Why:* Previously, users wanting `cookie` obfuscation were forced to use the `header` placement string. This caused Xray-core to blindly intercept the entire monolithic HTTP Cookie header, failing internal padding-length validations and causing the inbound to silently drop the connection.
2. **Fixed Uplink Data Placement Validation**:
   - Replaced the unsupported `query` option with `cookie` in `uplinkDataPlacement`.
   - *Why:* Xray-core's `transport_internet.go` explicitly forbids `query` as an uplink placement option. Selecting it from the UI previously sent a payload that would cause Xray-core to instantly throw an `unsupported uplink data placement: query` panic. Adding `cookie` perfectly aligns the UI with Xray-core restrictions.
### Related Issues
- Resolves #3992
2026-04-06 15:00:43 +03:00

102 lines
2.4 KiB
Go

package conf
import (
"github.com/xtls/xray-core/app/policy"
)
type Policy struct {
Handshake *uint32 `json:"handshake"`
ConnectionIdle *uint32 `json:"connIdle"`
UplinkOnly *uint32 `json:"uplinkOnly"`
DownlinkOnly *uint32 `json:"downlinkOnly"`
StatsUserUplink bool `json:"statsUserUplink"`
StatsUserDownlink bool `json:"statsUserDownlink"`
StatsUserOnline bool `json:"statsUserOnline"`
BufferSize *int32 `json:"bufferSize"`
}
func (t *Policy) Build() (*policy.Policy, error) {
config := new(policy.Policy_Timeout)
if t.Handshake != nil {
config.Handshake = &policy.Second{Value: *t.Handshake}
}
if t.ConnectionIdle != nil {
config.ConnectionIdle = &policy.Second{Value: *t.ConnectionIdle}
}
if t.UplinkOnly != nil {
config.UplinkOnly = &policy.Second{Value: *t.UplinkOnly}
}
if t.DownlinkOnly != nil {
config.DownlinkOnly = &policy.Second{Value: *t.DownlinkOnly}
}
p := &policy.Policy{
Timeout: config,
Stats: &policy.Policy_Stats{
UserUplink: t.StatsUserUplink,
UserDownlink: t.StatsUserDownlink,
UserOnline: t.StatsUserOnline,
},
}
if t.BufferSize != nil {
bs := int32(-1)
if *t.BufferSize >= 0 {
bs = (*t.BufferSize) * 1024
}
p.Buffer = &policy.Policy_Buffer{
Connection: bs,
}
}
return p, nil
}
type SystemPolicy struct {
StatsInboundUplink bool `json:"statsInboundUplink"`
StatsInboundDownlink bool `json:"statsInboundDownlink"`
StatsOutboundUplink bool `json:"statsOutboundUplink"`
StatsOutboundDownlink bool `json:"statsOutboundDownlink"`
}
func (p *SystemPolicy) Build() (*policy.SystemPolicy, error) {
return &policy.SystemPolicy{
Stats: &policy.SystemPolicy_Stats{
InboundUplink: p.StatsInboundUplink,
InboundDownlink: p.StatsInboundDownlink,
OutboundUplink: p.StatsOutboundUplink,
OutboundDownlink: p.StatsOutboundDownlink,
},
}, nil
}
type PolicyConfig struct {
Levels map[uint32]*Policy `json:"levels"`
System *SystemPolicy `json:"system"`
}
func (c *PolicyConfig) Build() (*policy.Config, error) {
levels := make(map[uint32]*policy.Policy)
for l, p := range c.Levels {
if p != nil {
pp, err := p.Build()
if err != nil {
return nil, err
}
levels[l] = pp
}
}
config := &policy.Config{
Level: levels,
}
if c.System != nil {
sc, err := c.System.Build()
if err != nil {
return nil, err
}
config.System = sc
}
return config, nil
}