鲁棒性增强

This commit is contained in:
CN-JS-HuiBai
2026-04-14 23:56:42 +08:00
parent ef1f27c61d
commit bd6f4e946f

View File

@@ -68,16 +68,59 @@ type XNodeConfig struct {
}
type XRealitySettings struct {
Dest string `json:"dest"`
ServerNames []string `json:"serverNames"`
PrivateKey string `json:"privateKey"`
ShortId string `json:"shortId"`
Dest string `json:"dest"`
ServerNames []string `json:"serverNames"`
ServerNames_ []string `json:"server_names"`
PrivateKey string `json:"privateKey"`
PrivateKey_ string `json:"private_key"`
ShortId string `json:"shortId"`
ShortId_ string `json:"short_id"`
ShortIds []string `json:"shortIds"`
ShortIds_ []string `json:"short_ids"`
}
func (r *XRealitySettings) GetPrivateKey() string {
if r.PrivateKey != "" {
return r.PrivateKey
}
return r.PrivateKey_
}
func (r *XRealitySettings) GetShortIds() []string {
if len(r.ShortIds) > 0 {
return r.ShortIds
}
if len(r.ShortIds_) > 0 {
return r.ShortIds_
}
if r.ShortId != "" {
return []string{r.ShortId}
}
if r.ShortId_ != "" {
return []string{r.ShortId_}
}
return nil
}
func (r *XRealitySettings) GetServerNames() []string {
if len(r.ServerNames) > 0 {
return r.ServerNames
}
return r.ServerNames_
}
type XStreamSettings struct {
Network string `json:"network"`
Security string `json:"security"`
RealitySettings XRealitySettings `json:"realitySettings"`
RealitySettings_ XRealitySettings `json:"reality_settings"`
}
func (s *XStreamSettings) GetReality() *XRealitySettings {
if s.RealitySettings.GetPrivateKey() != "" {
return &s.RealitySettings
}
return &s.RealitySettings_
}
func NewService(ctx context.Context, logger log.ContextLogger, tag string, options option.XBoardServiceOptions) (adapter.Service, error) {
@@ -155,20 +198,26 @@ func (s *Service) setupNode() error {
// Handle Reality
var streamSettings XStreamSettings
json.Unmarshal(config.Config.StreamSettings, &streamSettings)
if streamSettings.Security == "reality" {
reality := streamSettings.GetReality()
if streamSettings.Security == "reality" && reality != nil {
serverNames := reality.GetServerNames()
serverName := ""
if len(serverNames) > 0 {
serverName = serverNames[0]
}
vlessOptions.TLS = &option.InboundTLSOptions{
Enabled: true,
ServerName: streamSettings.RealitySettings.ServerNames[0],
ServerName: serverName,
Reality: &option.InboundRealityOptions{
Enabled: true,
Handshake: option.InboundRealityHandshakeOptions{
ServerOptions: option.ServerOptions{
Server: streamSettings.RealitySettings.Dest,
Server: reality.Dest,
ServerPort: 443,
},
},
PrivateKey: streamSettings.RealitySettings.PrivateKey,
ShortID: badoption.Listable[string]{streamSettings.RealitySettings.ShortId},
PrivateKey: reality.GetPrivateKey(),
ShortID: badoption.Listable[string](reality.GetShortIds()),
},
}
}
@@ -252,11 +301,14 @@ func (s *Service) fetchConfig() (*XNodeConfig, error) {
return nil, E.New("failed to fetch config, status: ", resp.Status, ", body: ", string(respBody))
}
body, _ := io.ReadAll(resp.Body)
var result struct {
Data XNodeConfig `json:"data"`
}
err = json.NewDecoder(resp.Body).Decode(&result)
err = json.Unmarshal(body, &result)
if err != nil {
s.logger.Debug("Xboard raw config response: ", string(body))
return nil, err
}
return &result.Data, nil
@@ -289,7 +341,7 @@ type userData struct {
func (s *Service) syncUsers() {
s.logger.Info("Xboard sync users...")
xUsers, err := s.fetchUsers()
users, err := s.fetchUsers()
if err != nil {
s.logger.Error("Xboard sync error: ", err)
return
@@ -299,11 +351,8 @@ func (s *Service) syncUsers() {
defer s.access.Unlock()
newUsers := make(map[string]userData)
for _, u := range xUsers {
key := u.UUID
if key == "" {
key = u.Passwd
}
for _, u := range users {
key := u.ResolveKey()
if key == "" {
continue
}
@@ -468,11 +517,26 @@ func (s *Service) Close() error {
// Xboard User Model
type XUser struct {
ID int `json:"id"`
Email string `json:"email"`
UUID string `json:"uuid"`
Passwd string `json:"passwd"`
Flow string `json:"flow"`
ID int `json:"id"`
Email string `json:"email"`
UUID string `json:"uuid"` // V2ray/Vless
Passwd string `json:"passwd"` // SS
Password string `json:"password"` // Trojan/SS alternate
Token string `json:"token"` // Alternate
Flow string `json:"flow"`
}
func (u *XUser) ResolveKey() string {
if u.UUID != "" {
return u.UUID
}
if u.Passwd != "" {
return u.Passwd
}
if u.Password != "" {
return u.Password
}
return u.Token
}
func (s *Service) fetchUsers() ([]XUser, error) {
@@ -499,11 +563,14 @@ func (s *Service) fetchUsers() ([]XUser, error) {
return nil, E.New("failed to fetch users, status: ", resp.Status, ", body: ", string(respBody))
}
body, _ := io.ReadAll(resp.Body)
var result struct {
Data []XUser `json:"data"`
}
err = json.NewDecoder(resp.Body).Decode(&result)
err = json.Unmarshal(body, &result)
if err != nil {
s.logger.Debug("Xboard raw user response: ", string(body))
return nil, err
}
return result.Data, nil