Config: Parallel for for inbounds' clients (#6055)

https://github.com/XTLS/Xray-core/pull/6055#issuecomment-4360958652
This commit is contained in:
Yury Kastov
2026-05-02 16:32:59 +03:00
committed by GitHub
parent bdff2fa72e
commit 1ead940a71
7 changed files with 173 additions and 39 deletions

View File

@@ -4,6 +4,7 @@ import (
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/common/task"
"github.com/xtls/xray-core/proxy/hysteria"
"github.com/xtls/xray-core/proxy/hysteria/account"
"google.golang.org/protobuf/proto"
@@ -44,16 +45,22 @@ type HysteriaServerConfig struct {
func (c *HysteriaServerConfig) Build() (proto.Message, error) {
config := new(hysteria.ServerConfig)
if c.Users != nil {
for _, user := range c.Users {
account := &account.Account{
if len(c.Users) > 0 {
config.Users = make([]*protocol.User, len(c.Users))
processUser := func(idx int) error {
user := c.Users[idx]
acc := &account.Account{
Auth: user.Auth,
}
config.Users = append(config.Users, &protocol.User{
config.Users[idx] = &protocol.User{
Email: user.Email,
Level: user.Level,
Account: serial.ToTypedMessage(account),
})
Account: serial.ToTypedMessage(acc),
}
return nil
}
if err := task.ParallelForN(len(c.Users), processUser); err != nil {
return nil, err
}
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/common/task"
"github.com/xtls/xray-core/proxy/shadowsocks"
"github.com/xtls/xray-core/proxy/shadowsocks_2022"
"google.golang.org/protobuf/proto"
@@ -59,23 +60,31 @@ func (v *ShadowsocksServerConfig) Build() (proto.Message, error) {
config.Network = v.NetworkList.Build()
if v.Users != nil {
for _, user := range v.Users {
account := &shadowsocks.Account{
Password: user.Password,
CipherType: cipherFromString(user.Cipher),
if len(v.Users) > 0 {
config.Users = make([]*protocol.User, len(v.Users))
processUser := func(idx int) error {
user := v.Users[idx]
account := &shadowsocks.Account{
Password: user.Password,
CipherType: cipherFromString(user.Cipher),
}
if account.Password == "" {
return errors.New("Shadowsocks password is not specified.")
}
if account.CipherType < shadowsocks.CipherType_AES_128_GCM ||
account.CipherType > shadowsocks.CipherType_XCHACHA20_POLY1305 {
return errors.New("unsupported cipher method: ", user.Cipher)
}
config.Users[idx] = &protocol.User{
Email: user.Email,
Level: uint32(user.Level),
Account: serial.ToTypedMessage(account),
}
return nil
}
if account.Password == "" {
return nil, errors.New("Shadowsocks password is not specified.")
if err := task.ParallelForN(len(v.Users), processUser); err != nil {
return nil, err
}
if account.CipherType < shadowsocks.CipherType_AES_128_GCM ||
account.CipherType > shadowsocks.CipherType_XCHACHA20_POLY1305 {
return nil, errors.New("unsupported cipher method: ", user.Cipher)
}
config.Users = append(config.Users, &protocol.User{
Email: user.Email,
Level: uint32(user.Level),
Account: serial.ToTypedMessage(account),
})
}
} else {
account := &shadowsocks.Account{
@@ -121,18 +130,24 @@ func buildShadowsocks2022(v *ShadowsocksServerConfig) (proto.Message, error) {
config.Key = v.Password
config.Network = v.NetworkList.Build()
for _, user := range v.Users {
config.Users = make([]*protocol.User, len(v.Users))
processUser := func(idx int) error {
user := v.Users[idx]
if user.Cipher != "" {
return nil, errors.New("shadowsocks 2022 (multi-user): users must have empty method")
return errors.New("shadowsocks 2022 (multi-user): users must have empty method")
}
account := &shadowsocks_2022.Account{
Key: user.Password,
}
config.Users = append(config.Users, &protocol.User{
config.Users[idx] = &protocol.User{
Email: user.Email,
Level: uint32(user.Level),
Account: serial.ToTypedMessage(account),
})
}
return nil
}
if err := task.ParallelForN(len(v.Users), processUser); err != nil {
return nil, err
}
return config, nil
}

View File

@@ -12,6 +12,7 @@ import (
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/common/task"
"github.com/xtls/xray-core/proxy/trojan"
"google.golang.org/protobuf/proto"
)
@@ -123,9 +124,10 @@ func (c *TrojanServerConfig) Build() (proto.Message, error) {
Users: make([]*protocol.User, len(c.Clients)),
}
for idx, rawUser := range c.Clients {
processClient := func(idx int) error {
rawUser := c.Clients[idx]
if rawUser.Flow != "" {
return nil, errors.PrintRemovedFeatureError(`Flow for Trojan`, ``)
return errors.PrintRemovedFeatureError(`Flow for Trojan`, ``)
}
config.Users[idx] = &protocol.User{
@@ -135,6 +137,10 @@ func (c *TrojanServerConfig) Build() (proto.Message, error) {
Password: rawUser.Password,
}),
}
return nil
}
if err := task.ParallelForN(len(c.Clients), processClient); err != nil {
return nil, err
}
for _, fb := range c.Fallbacks {

View File

@@ -13,6 +13,7 @@ import (
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/common/task"
"github.com/xtls/xray-core/common/uuid"
"github.com/xtls/xray-core/proxy/vless"
"github.com/xtls/xray-core/proxy/vless/inbound"
@@ -46,19 +47,20 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) {
default:
return nil, errors.New(`VLESS "settings.flow" doesn't support "` + c.Flow + `" in this version`)
}
for idx, rawUser := range c.Clients {
processClient := func(idx int) error {
rawUser := c.Clients[idx]
user := new(protocol.User)
if err := json.Unmarshal(rawUser, user); err != nil {
return nil, errors.New(`VLESS clients: invalid user`).Base(err)
return errors.New(`VLESS clients: invalid user`).Base(err)
}
account := new(vless.Account)
if err := json.Unmarshal(rawUser, account); err != nil {
return nil, errors.New(`VLESS clients: invalid user`).Base(err)
return errors.New(`VLESS clients: invalid user`).Base(err)
}
u, err := uuid.ParseString(account.Id)
if err != nil {
return nil, err
return err
}
account.Id = u.String()
@@ -67,7 +69,7 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) {
account.Flow = c.Flow
case vless.XRV:
default:
return nil, errors.New(`VLESS clients: "flow" doesn't support "` + account.Flow + `" in this version`)
return errors.New(`VLESS clients: "flow" doesn't support "` + account.Flow + `" in this version`)
}
if len(account.Testseed) < 4 {
@@ -75,20 +77,25 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) {
}
if account.Encryption != "" {
return nil, errors.New(`VLESS clients: "encryption" should not be in inbound settings`)
return errors.New(`VLESS clients: "encryption" should not be in inbound settings`)
}
if account.Reverse != nil {
if account.Reverse.Tag == "" {
return nil, errors.New(`VLESS clients: "tag" can't be empty for "reverse"`)
return errors.New(`VLESS clients: "tag" can't be empty for "reverse"`)
}
if account.Reverse.Sniffing != nil { // may not be reached: error json unmarshal
return nil, errors.New(`VLESS clients: inbound's "reverse" can't have "sniffing"`)
return errors.New(`VLESS clients: inbound's "reverse" can't have "sniffing"`)
}
}
user.Account = serial.ToTypedMessage(account)
config.Clients[idx] = user
return nil
}
if err := task.ParallelForN(len(c.Clients), processClient); err != nil {
return nil, err
}
config.Decryption = c.Decryption

View File

@@ -7,6 +7,7 @@ import (
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/common/task"
"github.com/xtls/xray-core/common/uuid"
"github.com/xtls/xray-core/proxy/vmess"
"github.com/xtls/xray-core/proxy/vmess/inbound"
@@ -73,24 +74,29 @@ func (c *VMessInboundConfig) Build() (proto.Message, error) {
}
config.User = make([]*protocol.User, len(c.Users))
for idx, rawData := range c.Users {
processUser := func(idx int) error {
rawData := c.Users[idx]
user := new(protocol.User)
if err := json.Unmarshal(rawData, user); err != nil {
return nil, errors.New("invalid VMess user").Base(err)
return errors.New("invalid VMess user").Base(err)
}
account := new(VMessAccount)
if err := json.Unmarshal(rawData, account); err != nil {
return nil, errors.New("invalid VMess user").Base(err)
return errors.New("invalid VMess user").Base(err)
}
u, err := uuid.ParseString(account.ID)
if err != nil {
return nil, err
return err
}
account.ID = u.String()
user.Account = serial.ToTypedMessage(account.Build())
config.User[idx] = user
return nil
}
if err := task.ParallelForN(len(c.Users), processUser); err != nil {
return nil, err
}
return config, nil