鲁棒性增强
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user