Xboard config fetched...
This commit is contained in:
@@ -104,6 +104,7 @@ type XNodeConfig struct {
|
||||
ServerName string `json:"server_name,omitempty"`
|
||||
ServerPortText string `json:"server_port_text,omitempty"`
|
||||
Network string `json:"network"`
|
||||
Multiplex *XMultiplexConfig `json:"multiplex,omitempty"`
|
||||
NetworkSettings json.RawMessage `json:"network_settings"`
|
||||
NetworkSettings_ json.RawMessage `json:"networkSettings"`
|
||||
|
||||
@@ -159,6 +160,7 @@ type XInnerConfig struct {
|
||||
Dest string `json:"dest,omitempty"`
|
||||
ServerName string `json:"server_name,omitempty"`
|
||||
Network string `json:"network"`
|
||||
Multiplex *XMultiplexConfig `json:"multiplex,omitempty"`
|
||||
NetworkSettings json.RawMessage `json:"network_settings"`
|
||||
NetworkSettings_ json.RawMessage `json:"networkSettings"`
|
||||
StreamSettings json.RawMessage `json:"streamSettings"`
|
||||
@@ -166,6 +168,22 @@ type XInnerConfig struct {
|
||||
DownMbps int `json:"down_mbps"`
|
||||
}
|
||||
|
||||
type XMultiplexConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Protocol string `json:"protocol,omitempty"`
|
||||
MaxConnections int `json:"max_connections,omitempty"`
|
||||
MinStreams int `json:"min_streams,omitempty"`
|
||||
MaxStreams int `json:"max_streams,omitempty"`
|
||||
Padding bool `json:"padding,omitempty"`
|
||||
Brutal *XBrutalConfig `json:"brutal,omitempty"`
|
||||
}
|
||||
|
||||
type XBrutalConfig struct {
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
UpMbps int `json:"up_mbps,omitempty"`
|
||||
DownMbps int `json:"down_mbps,omitempty"`
|
||||
}
|
||||
|
||||
type HttpNetworkConfig struct {
|
||||
Header struct {
|
||||
Type string `json:"type"`
|
||||
@@ -403,6 +421,25 @@ func mergedTLSSettings(inner XInnerConfig, config *XNodeConfig) *XTLSSettings {
|
||||
return tlsSettings
|
||||
}
|
||||
|
||||
func buildInboundMultiplex(config *XMultiplexConfig) *option.InboundMultiplexOptions {
|
||||
if config == nil || !config.Enabled {
|
||||
return nil
|
||||
}
|
||||
var brutal *option.BrutalOptions
|
||||
if config.Brutal != nil {
|
||||
brutal = &option.BrutalOptions{
|
||||
Enabled: config.Brutal.Enabled,
|
||||
UpMbps: config.Brutal.UpMbps,
|
||||
DownMbps: config.Brutal.DownMbps,
|
||||
}
|
||||
}
|
||||
return &option.InboundMultiplexOptions{
|
||||
Enabled: config.Enabled,
|
||||
Padding: config.Padding,
|
||||
Brutal: brutal,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
@@ -556,15 +593,23 @@ func (s *Service) setupNode() error {
|
||||
if inner.Protocol == "" {
|
||||
inner.Protocol = config.NodeType
|
||||
}
|
||||
portSource := ""
|
||||
if inner.Port == 0 {
|
||||
if inner.ServerPort != 0 {
|
||||
inner.Port = inner.ServerPort
|
||||
portSource = "inner.server_port"
|
||||
} else if config.Port != 0 {
|
||||
inner.Port = config.Port
|
||||
portSource = "config.port"
|
||||
} else {
|
||||
inner.Port = config.ServerPort
|
||||
if config.ServerPort != 0 {
|
||||
portSource = "config.server_port"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
portSource = "inner.port"
|
||||
}
|
||||
if inner.Cipher == "" {
|
||||
inner.Cipher = config.Cipher
|
||||
}
|
||||
@@ -574,6 +619,9 @@ func (s *Service) setupNode() error {
|
||||
if inner.Network == "" {
|
||||
inner.Network = config.Network
|
||||
}
|
||||
if inner.Multiplex == nil {
|
||||
inner.Multiplex = config.Multiplex
|
||||
}
|
||||
if len(inner.NetworkSettings) == 0 {
|
||||
inner.NetworkSettings = config.NetworkSettings
|
||||
}
|
||||
@@ -714,6 +762,20 @@ func (s *Service) setupNode() error {
|
||||
}
|
||||
|
||||
// ── Build inbound per protocol (matching V2bX core/sing/node.go) ──
|
||||
multiplex := buildInboundMultiplex(inner.Multiplex)
|
||||
s.logger.Info(
|
||||
"Xboard node config resolved. protocol=", protocol,
|
||||
", listen_ip=", inner.ListenIP,
|
||||
", listen_port=", inner.Port,
|
||||
" (source=", portSource, ")",
|
||||
", inner_server_port=", inner.ServerPort,
|
||||
", config_port=", config.Port,
|
||||
", config_server_port=", config.ServerPort,
|
||||
", network=", networkType,
|
||||
", tls=", securityType,
|
||||
", multiplex=", multiplex != nil,
|
||||
)
|
||||
|
||||
var inboundOptions any
|
||||
switch protocol {
|
||||
case "vmess", "vless":
|
||||
@@ -729,6 +791,7 @@ func (s *Service) setupNode() error {
|
||||
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
|
||||
TLS: &tlsOptions,
|
||||
},
|
||||
Multiplex: multiplex,
|
||||
}
|
||||
if transport != nil {
|
||||
opts.Transport = transport
|
||||
@@ -740,6 +803,7 @@ func (s *Service) setupNode() error {
|
||||
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
|
||||
TLS: &tlsOptions,
|
||||
},
|
||||
Multiplex: multiplex,
|
||||
}
|
||||
if transport != nil {
|
||||
opts.Transport = transport
|
||||
@@ -765,6 +829,7 @@ func (s *Service) setupNode() error {
|
||||
ssOptions := &option.ShadowsocksInboundOptions{
|
||||
ListenOptions: listen,
|
||||
Method: method,
|
||||
Multiplex: multiplex,
|
||||
}
|
||||
|
||||
isSS2022 := strings.Contains(method, "2022")
|
||||
@@ -805,6 +870,7 @@ func (s *Service) setupNode() error {
|
||||
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
|
||||
TLS: &tlsOptions,
|
||||
},
|
||||
Multiplex: multiplex,
|
||||
}
|
||||
if transport != nil {
|
||||
opts.Transport = transport
|
||||
@@ -902,6 +968,7 @@ func (s *Service) setupNode() error {
|
||||
|
||||
// Remove old if exists
|
||||
s.inboundManager.Remove(inboundTag)
|
||||
s.logger.Info("Xboard creating inbound [", inboundTag, "] on ", inner.ListenIP, ":", inner.Port, " (protocol: ", protocol, ")")
|
||||
|
||||
// Create new inbound
|
||||
err = s.inboundManager.Create(s.ctx, s.router, s.logger, inboundTag, protocol, inboundOptions)
|
||||
@@ -983,6 +1050,12 @@ func (s *Service) fetchConfig() (*XNodeConfig, error) {
|
||||
// Try unmarshaling WITHOUT "data" wrapper
|
||||
var flatResult XNodeConfig
|
||||
if err2 := json.Unmarshal(body, &flatResult); err2 == nil {
|
||||
s.logger.Info(
|
||||
"Xboard config fetched (flat). protocol=", flatResult.Protocol,
|
||||
", node_type=", flatResult.NodeType,
|
||||
", port=", flatResult.Port,
|
||||
", server_port=", flatResult.ServerPort,
|
||||
)
|
||||
return &flatResult, nil
|
||||
}
|
||||
|
||||
@@ -995,6 +1068,12 @@ func (s *Service) fetchConfig() (*XNodeConfig, error) {
|
||||
if result.Data.Protocol == "" && len(result.Data.ServerConfig) == 0 && len(result.Data.Config) == 0 && result.Data.NodeType == "" && result.Data.ServerPort == 0 {
|
||||
s.logger.Error("Xboard config mapping failed (fields missing). Data: ", string(body))
|
||||
}
|
||||
s.logger.Info(
|
||||
"Xboard config fetched. protocol=", result.Data.Protocol,
|
||||
", node_type=", result.Data.NodeType,
|
||||
", port=", result.Data.Port,
|
||||
", server_port=", result.Data.ServerPort,
|
||||
)
|
||||
|
||||
return &result.Data, nil
|
||||
}
|
||||
|
||||
@@ -93,3 +93,26 @@ func TestExpandNodeOptions(t *testing.T) {
|
||||
t.Fatalf("second node = %+v", nodes[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildInboundMultiplex(t *testing.T) {
|
||||
config := &XMultiplexConfig{
|
||||
Enabled: true,
|
||||
Padding: true,
|
||||
Brutal: &XBrutalConfig{
|
||||
Enabled: true,
|
||||
UpMbps: 100,
|
||||
DownMbps: 200,
|
||||
},
|
||||
}
|
||||
|
||||
got := buildInboundMultiplex(config)
|
||||
if got == nil {
|
||||
t.Fatal("buildInboundMultiplex() returned nil")
|
||||
}
|
||||
if !got.Enabled || !got.Padding {
|
||||
t.Fatalf("buildInboundMultiplex() = %+v", got)
|
||||
}
|
||||
if got.Brutal == nil || !got.Brutal.Enabled || got.Brutal.UpMbps != 100 || got.Brutal.DownMbps != 200 {
|
||||
t.Fatalf("buildInboundMultiplex() brutal = %+v", got.Brutal)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user