diff --git a/node/inbound.go b/common/builder/inbound.go similarity index 88% rename from node/inbound.go rename to common/builder/inbound.go index d8ae9fc..ada5f6d 100644 --- a/node/inbound.go +++ b/common/builder/inbound.go @@ -1,4 +1,4 @@ -package node +package builder import ( "crypto/rand" @@ -17,18 +17,18 @@ import ( // BuildInbound build Inbound config for different protocol func BuildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag string) (*core.InboundHandlerConfig, error) { - inbound := &coreConf.InboundDetourConfig{} + in := &coreConf.InboundDetourConfig{} // Set network protocol t := coreConf.TransportProtocol(nodeInfo.Network) - inbound.StreamSetting = &coreConf.StreamConfig{Network: &t} + in.StreamSetting = &coreConf.StreamConfig{Network: &t} var err error switch nodeInfo.NodeType { case "v2ray": - err = buildV2ray(config, nodeInfo, inbound) + err = buildV2ray(config, nodeInfo, in) case "trojan": - err = buildTrojan(config, nodeInfo, inbound) + err = buildTrojan(config, nodeInfo, in) case "shadowsocks": - err = buildShadowsocks(config, nodeInfo, inbound) + err = buildShadowsocks(config, nodeInfo, in) default: return nil, fmt.Errorf("unsupported node type: %s, Only support: V2ray, Trojan, Shadowsocks", nodeInfo.NodeType) } @@ -36,12 +36,12 @@ func BuildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag s return nil, err } // Set server port - inbound.PortList = &coreConf.PortList{ + in.PortList = &coreConf.PortList{ Range: []coreConf.PortRange{{From: uint32(nodeInfo.ServerPort), To: uint32(nodeInfo.ServerPort)}}, } // Set Listen IP address ipAddress := net.ParseAddress(config.ListenIP) - inbound.ListenOn = &coreConf.Address{Address: ipAddress} + in.ListenOn = &coreConf.Address{Address: ipAddress} // Set SniffingConfig sniffingConfig := &coreConf.SniffingConfig{ Enabled: true, @@ -50,30 +50,30 @@ func BuildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag s if config.DisableSniffing { sniffingConfig.Enabled = false } - inbound.SniffingConfig = sniffingConfig - if *inbound.StreamSetting.Network == "tcp" { - if inbound.StreamSetting.TCPSettings != nil { - inbound.StreamSetting.TCPSettings.AcceptProxyProtocol = config.EnableProxyProtocol + in.SniffingConfig = sniffingConfig + if *in.StreamSetting.Network == "tcp" { + if in.StreamSetting.TCPSettings != nil { + in.StreamSetting.TCPSettings.AcceptProxyProtocol = config.EnableProxyProtocol } else { tcpSetting := &coreConf.TCPConfig{ AcceptProxyProtocol: config.EnableProxyProtocol, } //Enable proxy protocol - inbound.StreamSetting.TCPSettings = tcpSetting + in.StreamSetting.TCPSettings = tcpSetting } - } else if *inbound.StreamSetting.Network == "ws" { - inbound.StreamSetting.WSSettings = &coreConf.WebSocketConfig{ + } else if *in.StreamSetting.Network == "ws" { + in.StreamSetting.WSSettings = &coreConf.WebSocketConfig{ AcceptProxyProtocol: config.EnableProxyProtocol} //Enable proxy protocol } // Set TLS and XTLS settings if nodeInfo.Tls != 0 { if config.CertConfig.CertMode != "none" { // Normal tls - inbound.StreamSetting.Security = "tls" + in.StreamSetting.Security = "tls" certFile, keyFile, err := getCertFile(config.CertConfig) if err != nil { return nil, err } - inbound.StreamSetting.TLSSettings = &coreConf.TLSConfig{ + in.StreamSetting.TLSSettings = &coreConf.TLSConfig{ Certs: []*coreConf.TLSCertConfig{ { CertFile: certFile, @@ -85,12 +85,12 @@ func BuildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag s } } else if config.EnableReality { // Reality - inbound.StreamSetting.Security = "reality" + in.StreamSetting.Security = "reality" d, err := json.Marshal(config.RealityConfig.Dest) if err != nil { return nil, fmt.Errorf("marshal reality dest error: %s", err) } - inbound.StreamSetting.REALITYSettings = &coreConf.REALITYConfig{ + in.StreamSetting.REALITYSettings = &coreConf.REALITYConfig{ Dest: d, Xver: config.RealityConfig.Xver, ServerNames: config.RealityConfig.ServerNames, @@ -103,16 +103,16 @@ func BuildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag s } } // Support ProxyProtocol for any transport protocol - if *inbound.StreamSetting.Network != "tcp" && - *inbound.StreamSetting.Network != "ws" && + if *in.StreamSetting.Network != "tcp" && + *in.StreamSetting.Network != "ws" && config.EnableProxyProtocol { sockoptConfig := &coreConf.SocketConfig{ AcceptProxyProtocol: config.EnableProxyProtocol, } //Enable proxy protocol - inbound.StreamSetting.SocketSettings = sockoptConfig + in.StreamSetting.SocketSettings = sockoptConfig } - inbound.Tag = tag - return inbound.Build() + in.Tag = tag + return in.Build() } func buildV2ray(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, inbound *coreConf.InboundDetourConfig) error { diff --git a/node/outbound.go b/common/builder/outbound.go similarity index 88% rename from node/outbound.go rename to common/builder/outbound.go index 17cc33f..66bac83 100644 --- a/node/outbound.go +++ b/common/builder/outbound.go @@ -1,18 +1,17 @@ -package node +package builder import ( "fmt" "github.com/Yuzuki616/V2bX/api/panel" conf2 "github.com/Yuzuki616/V2bX/conf" "github.com/goccy/go-json" - "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/infra/conf" ) -// buildOutbound build freedom outbund config for addoutbound -func buildOutbound(config *conf2.ControllerConfig, nodeInfo *panel.NodeInfo, tag string) (*core.OutboundHandlerConfig, error) { +// BuildOutbound build freedom outbund config for addoutbound +func BuildOutbound(config *conf2.ControllerConfig, nodeInfo *panel.NodeInfo, tag string) (*core.OutboundHandlerConfig, error) { outboundDetourConfig := &conf.OutboundDetourConfig{} outboundDetourConfig.Protocol = "freedom" outboundDetourConfig.Tag = tag diff --git a/node/user.go b/common/builder/user.go similarity index 50% rename from node/user.go rename to common/builder/user.go index f4e729e..b532348 100644 --- a/node/user.go +++ b/common/builder/user.go @@ -1,4 +1,4 @@ -package node +package builder import ( "encoding/base64" @@ -11,94 +11,69 @@ import ( "github.com/xtls/xray-core/proxy/shadowsocks_2022" "github.com/xtls/xray-core/proxy/trojan" "github.com/xtls/xray-core/proxy/vless" - "log" "strings" ) const xtlsFLow = "xtls-rprx-vision" -func (c *Controller) addNewUser(userInfo []panel.UserInfo, nodeInfo *panel.NodeInfo) (err error) { - users := make([]*protocol.User, 0, len(userInfo)) - switch nodeInfo.NodeType { - case "v2ray": - if c.EnableVless { - users = c.buildVlessUsers(userInfo) - } else { - users = c.buildVmessUsers(userInfo) - } - case "trojan": - users = c.buildTrojanUsers(userInfo) - case "shadowsocks": - users = c.buildSSUsers(userInfo, getCipherFromString(nodeInfo.Cipher)) - default: - return fmt.Errorf("unsupported node type: %s", nodeInfo.NodeType) - } - err = c.server.AddUsers(users, c.Tag) - if err != nil { - return fmt.Errorf("add users error: %s", err) - } - log.Printf("[%s: %d] Added %d new users", c.nodeInfo.NodeType, c.nodeInfo.NodeId, len(userInfo)) - return nil -} - -func (c *Controller) buildVmessUsers(userInfo []panel.UserInfo) (users []*protocol.User) { +func BuildVmessUsers(tag string, userInfo []panel.UserInfo) (users []*protocol.User) { users = make([]*protocol.User, len(userInfo)) for i, user := range userInfo { - users[i] = c.buildVmessUser(&user, 0) + users[i] = BuildVmessUser(tag, &user) } return users } -func (c *Controller) buildVmessUser(userInfo *panel.UserInfo, serverAlterID uint16) (user *protocol.User) { +func BuildVmessUser(tag string, userInfo *panel.UserInfo) (user *protocol.User) { vmessAccount := &conf.VMessAccount{ ID: userInfo.Uuid, - AlterIds: serverAlterID, + AlterIds: 0, Security: "auto", } return &protocol.User{ Level: 0, - Email: c.buildUserTag(userInfo), // Uid: InboundTag|email|uid + Email: BuildUserTag(tag, userInfo), // Uid: InboundTag|email|uid Account: serial.ToTypedMessage(vmessAccount.Build()), } } -func (c *Controller) buildVlessUsers(userInfo []panel.UserInfo) (users []*protocol.User) { +func BuildVlessUsers(tag string, userInfo []panel.UserInfo, xtls bool) (users []*protocol.User) { users = make([]*protocol.User, len(userInfo)) for i := range userInfo { - users[i] = c.buildVlessUser(&(userInfo)[i]) + users[i] = BuildVlessUser(tag, &(userInfo)[i], xtls) } return users } -func (c *Controller) buildVlessUser(userInfo *panel.UserInfo) (user *protocol.User) { +func BuildVlessUser(tag string, userInfo *panel.UserInfo, xtls bool) (user *protocol.User) { vlessAccount := &vless.Account{ Id: userInfo.Uuid, } - if c.EnableXtls { + if xtls { vlessAccount.Flow = xtlsFLow } return &protocol.User{ Level: 0, - Email: c.buildUserTag(userInfo), + Email: BuildUserTag(tag, userInfo), Account: serial.ToTypedMessage(vlessAccount), } } -func (c *Controller) buildTrojanUsers(userInfo []panel.UserInfo) (users []*protocol.User) { +func BuildTrojanUsers(tag string, userInfo []panel.UserInfo) (users []*protocol.User) { users = make([]*protocol.User, len(userInfo)) for i := range userInfo { - users[i] = c.buildTrojanUser(&(userInfo)[i]) + users[i] = BuildTrojanUser(tag, &(userInfo)[i]) } return users } -func (c *Controller) buildTrojanUser(userInfo *panel.UserInfo) (user *protocol.User) { +func BuildTrojanUser(tag string, userInfo *panel.UserInfo) (user *protocol.User) { trojanAccount := &trojan.Account{ Password: userInfo.Uuid, } return &protocol.User{ Level: 0, - Email: c.buildUserTag(userInfo), + Email: BuildUserTag(tag, userInfo), Account: serial.ToTypedMessage(trojanAccount), } } @@ -118,23 +93,23 @@ func getCipherFromString(c string) shadowsocks.CipherType { } } -func (c *Controller) buildSSUsers(userInfo []panel.UserInfo, cypher shadowsocks.CipherType) (users []*protocol.User) { +func BuildSSUsers(tag string, userInfo []panel.UserInfo, cypher shadowsocks.CipherType, serverKey string) (users []*protocol.User) { users = make([]*protocol.User, len(userInfo)) for i := range userInfo { - users[i] = c.buildSSUser(&(userInfo)[i], cypher) + users[i] = BuildSSUser(tag, &userInfo[i], cypher, serverKey) } return users } -func (c *Controller) buildSSUser(userInfo *panel.UserInfo, cypher shadowsocks.CipherType) (user *protocol.User) { - if c.nodeInfo.ServerKey == "" { +func BuildSSUser(tag string, userInfo *panel.UserInfo, cypher shadowsocks.CipherType, serverKey string) (user *protocol.User) { + if serverKey == "" { ssAccount := &shadowsocks.Account{ Password: userInfo.Uuid, CipherType: cypher, } return &protocol.User{ Level: 0, - Email: c.buildUserTag(userInfo), + Email: tag, Account: serial.ToTypedMessage(ssAccount), } } else { @@ -143,12 +118,12 @@ func (c *Controller) buildSSUser(userInfo *panel.UserInfo, cypher shadowsocks.Ci } return &protocol.User{ Level: 0, - Email: c.buildUserTag(userInfo), + Email: tag, Account: serial.ToTypedMessage(ssAccount), } } } -func (c *Controller) buildUserTag(user *panel.UserInfo) string { - return fmt.Sprintf("%s|%s|%d", c.Tag, user.Uuid, user.Id) +func BuildUserTag(tag string, user *panel.UserInfo) string { + return fmt.Sprintf("%s|%s|%d", tag, user.Uuid, user.Id) } diff --git a/core/core.go b/core/core.go index 57fcb1b..b537ff7 100644 --- a/core/core.go +++ b/core/core.go @@ -150,38 +150,38 @@ func getCore(v2bXConfig *conf.Conf) *core.Instance { } // Start the Core -func (p *Core) Start() error { - p.access.Lock() - defer p.access.Unlock() - if err := p.Server.Start(); err != nil { +func (c *Core) Start() error { + c.access.Lock() + defer c.access.Unlock() + if err := c.Server.Start(); err != nil { return err } - p.shm = p.Server.GetFeature(statsFeature.ManagerType()).(statsFeature.Manager) - p.ihm = p.Server.GetFeature(inbound.ManagerType()).(inbound.Manager) - p.ohm = p.Server.GetFeature(outbound.ManagerType()).(outbound.Manager) - p.dispatcher = p.Server.GetFeature(routing.DispatcherType()).(*dispatcher.DefaultDispatcher) + c.shm = c.Server.GetFeature(statsFeature.ManagerType()).(statsFeature.Manager) + c.ihm = c.Server.GetFeature(inbound.ManagerType()).(inbound.Manager) + c.ohm = c.Server.GetFeature(outbound.ManagerType()).(outbound.Manager) + c.dispatcher = c.Server.GetFeature(routing.DispatcherType()).(*dispatcher.DefaultDispatcher) return nil } // Close the core -func (p *Core) Close() { - p.access.Lock() - defer p.access.Unlock() - p.ihm = nil - p.ohm = nil - p.shm = nil - p.dispatcher = nil - err := p.Server.Close() +func (c *Core) Close() { + c.access.Lock() + defer c.access.Unlock() + c.ihm = nil + c.ohm = nil + c.shm = nil + c.dispatcher = nil + err := c.Server.Close() if err != nil { log.Panicf("failed to close xray core: %s", err) } return } -func (p *Core) Restart(v2bXConfig *conf.Conf) error { - p.Close() - p.Server = getCore(v2bXConfig) - err := p.Start() +func (c *Core) Restart(v2bXConfig *conf.Conf) error { + c.Close() + c.Server = getCore(v2bXConfig) + err := c.Start() if err != nil { return err } diff --git a/core/inbound.go b/core/inbound.go deleted file mode 100644 index 69af4ab..0000000 --- a/core/inbound.go +++ /dev/null @@ -1,27 +0,0 @@ -package core - -import ( - "context" - "fmt" - "github.com/xtls/xray-core/core" - "github.com/xtls/xray-core/features/inbound" -) - -func (p *Core) RemoveInbound(tag string) error { - return p.ihm.RemoveHandler(context.Background(), tag) -} - -func (p *Core) AddInbound(config *core.InboundHandlerConfig) error { - rawHandler, err := core.CreateObject(p.Server, config) - if err != nil { - return err - } - handler, ok := rawHandler.(inbound.Handler) - if !ok { - return fmt.Errorf("not an InboundHandler: %s", err) - } - if err := p.ihm.AddHandler(context.Background(), handler); err != nil { - return err - } - return nil -} diff --git a/core/node.go b/core/node.go new file mode 100644 index 0000000..3a64104 --- /dev/null +++ b/core/node.go @@ -0,0 +1,62 @@ +package core + +import ( + "context" + "fmt" + "github.com/Yuzuki616/V2bX/api/panel" + "github.com/Yuzuki616/V2bX/common/builder" + "github.com/Yuzuki616/V2bX/conf" + "github.com/xtls/xray-core/core" + "github.com/xtls/xray-core/features/inbound" +) + +func (c *Core) AddNode(tag string, info *panel.NodeInfo, config *conf.ControllerConfig) error { + inboundConfig, err := builder.BuildInbound(config, info, tag) + if err != nil { + return fmt.Errorf("build inbound error: %s", err) + } + err = c.addInbound(inboundConfig) + if err != nil { + return fmt.Errorf("add inbound error: %s", err) + } + outBoundConfig, err := builder.BuildOutbound(config, info, tag) + if err != nil { + return fmt.Errorf("build outbound error: %s", err) + } + err = c.AddOutbound(outBoundConfig) + if err != nil { + return fmt.Errorf("add outbound error: %s", err) + } + return nil +} + +func (c *Core) addInbound(config *core.InboundHandlerConfig) error { + rawHandler, err := core.CreateObject(c.Server, config) + if err != nil { + return err + } + handler, ok := rawHandler.(inbound.Handler) + if !ok { + return fmt.Errorf("not an InboundHandler: %s", err) + } + if err := c.ihm.AddHandler(context.Background(), handler); err != nil { + return err + } + return nil +} + +func (c *Core) DelNode(tag string) error { + err := c.removeInbound(tag) + if err != nil { + return fmt.Errorf("remove in error: %s", err) + } + err = c.RemoveOutbound(tag) + if err != nil { + return fmt.Errorf("remove out error: %s", err) + } + return nil +} + +func (c *Core) removeInbound(tag string) error { + return c.ihm.RemoveHandler(context.Background(), tag) +} diff --git a/core/outbound.go b/core/outbound.go index 8ec8137..8453810 100644 --- a/core/outbound.go +++ b/core/outbound.go @@ -7,13 +7,13 @@ import ( "github.com/xtls/xray-core/features/outbound" ) -func (p *Core) RemoveOutbound(tag string) error { - err := p.ohm.RemoveHandler(context.Background(), tag) +func (c *Core) RemoveOutbound(tag string) error { + err := c.ohm.RemoveHandler(context.Background(), tag) return err } -func (p *Core) AddOutbound(config *core.OutboundHandlerConfig) error { - rawHandler, err := core.CreateObject(p.Server, config) +func (c *Core) AddOutbound(config *core.OutboundHandlerConfig) error { + rawHandler, err := core.CreateObject(c.Server, config) if err != nil { return err } @@ -21,7 +21,7 @@ func (p *Core) AddOutbound(config *core.OutboundHandlerConfig) error { if !ok { return fmt.Errorf("not an InboundHandler: %s", err) } - if err := p.ohm.AddHandler(context.Background(), handler); err != nil { + if err := c.ohm.AddHandler(context.Background(), handler); err != nil { return err } return nil diff --git a/core/user.go b/core/user.go index ae9fbfc..8e1956a 100644 --- a/core/user.go +++ b/core/user.go @@ -3,12 +3,17 @@ package core import ( "context" "fmt" + "github.com/Yuzuki616/V2bX/api/panel" + "github.com/Yuzuki616/V2bX/common/builder" + "github.com/Yuzuki616/V2bX/conf" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/proxy" + "github.com/xtls/xray-core/proxy/shadowsocks" + "strings" ) -func (p *Core) GetUserManager(tag string) (proxy.UserManager, error) { - handler, err := p.ihm.GetHandler(context.Background(), tag) +func (c *Core) GetUserManager(tag string) (proxy.UserManager, error) { + handler, err := c.ihm.GetHandler(context.Background(), tag) if err != nil { return nil, fmt.Errorf("no such inbound tag: %s", err) } @@ -23,26 +28,8 @@ func (p *Core) GetUserManager(tag string) (proxy.UserManager, error) { return userManager, nil } -func (p *Core) AddUsers(users []*protocol.User, tag string) error { - userManager, err := p.GetUserManager(tag) - if err != nil { - return fmt.Errorf("get user manager error: %s", err) - } - for _, item := range users { - mUser, err := item.ToMemoryUser() - if err != nil { - return err - } - err = userManager.AddUser(context.Background(), mUser) - if err != nil { - return err - } - } - return nil -} - -func (p *Core) RemoveUsers(users []string, tag string) error { - userManager, err := p.GetUserManager(tag) +func (c *Core) RemoveUsers(users []string, tag string) error { + userManager, err := c.GetUserManager(tag) if err != nil { return fmt.Errorf("get user manager error: %s", err) } @@ -55,11 +42,11 @@ func (p *Core) RemoveUsers(users []string, tag string) error { return nil } -func (p *Core) GetUserTraffic(email string, reset bool) (up int64, down int64) { +func (c *Core) GetUserTraffic(email string, reset bool) (up int64, down int64) { upName := "user>>>" + email + ">>>traffic>>>uplink" downName := "user>>>" + email + ">>>traffic>>>downlink" - upCounter := p.shm.GetCounter(upName) - downCounter := p.shm.GetCounter(downName) + upCounter := c.shm.GetCounter(upName) + downCounter := c.shm.GetCounter(downName) if reset { if upCounter != nil { up = upCounter.Set(0) @@ -77,3 +64,61 @@ func (p *Core) GetUserTraffic(email string, reset bool) (up int64, down int64) { } return up, down } + +type AddUsersParams struct { + Tag string + Config *conf.ControllerConfig + UserInfo []panel.UserInfo + NodeInfo *panel.NodeInfo +} + +func (c *Core) AddUsers(p *AddUsersParams) (added int, err error) { + users := make([]*protocol.User, 0, len(p.UserInfo)) + switch p.NodeInfo.NodeType { + case "v2ray": + if p.Config.EnableVless { + users = builder.BuildVlessUsers(p.Tag, p.UserInfo, p.Config.EnableXtls) + } else { + users = builder.BuildVmessUsers(p.Tag, p.UserInfo) + } + case "trojan": + users = builder.BuildTrojanUsers(p.Tag, p.UserInfo) + case "shadowsocks": + users = builder.BuildSSUsers(p.Tag, + p.UserInfo, + getCipherFromString(p.NodeInfo.Cipher), + p.NodeInfo.ServerKey) + default: + return 0, fmt.Errorf("unsupported node type: %s", p.NodeInfo.NodeType) + } + man, err := c.GetUserManager(p.Tag) + if err != nil { + return 0, fmt.Errorf("get user manager error: %s", err) + } + for _, u := range users { + mUser, err := u.ToMemoryUser() + if err != nil { + return 0, err + } + err = man.AddUser(context.Background(), mUser) + if err != nil { + return 0, err + } + } + return len(users), nil +} + +func getCipherFromString(c string) shadowsocks.CipherType { + switch strings.ToLower(c) { + case "aes-128-gcm", "aead_aes_128_gcm": + return shadowsocks.CipherType_AES_128_GCM + case "aes-256-gcm", "aead_aes_256_gcm": + return shadowsocks.CipherType_AES_256_GCM + case "chacha20-poly1305", "aead_chacha20_poly1305", "chacha20-ietf-poly1305": + return shadowsocks.CipherType_CHACHA20_POLY1305 + case "none", "plain": + return shadowsocks.CipherType_NONE + default: + return shadowsocks.CipherType_UNKNOWN + } +} diff --git a/limiter/limiter.go b/limiter/limiter.go index 905aa74..d9b21fd 100644 --- a/limiter/limiter.go +++ b/limiter/limiter.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "github.com/Yuzuki616/V2bX/api/panel" + "github.com/Yuzuki616/V2bX/common/builder" "github.com/Yuzuki616/V2bX/conf" "github.com/juju/ratelimit" "github.com/xtls/xray-core/common/task" @@ -25,7 +26,7 @@ func Init() { go func() { log.Println("Limiter: ClearOnlineIP started") time.Sleep(time.Minute * 2) - c.Start() + _ = c.Start() }() } @@ -59,7 +60,7 @@ func AddLimiter(tag string, l *conf.LimitConfig, users []panel.UserInfo) *Limite SpeedLimit: users[i].SpeedLimit, ExpireTime: 0, } - info.UserLimitInfo.Store(fmt.Sprintf("%s|%s|%d", tag, users[i].Uuid, users[i].Id), userLimit) + info.UserLimitInfo.Store(builder.BuildUserTag(tag, &users[i]), userLimit) } } limitLock.Lock() diff --git a/node/controller.go b/node/controller.go index 40fd06c..2ef0034 100644 --- a/node/controller.go +++ b/node/controller.go @@ -64,11 +64,12 @@ func (c *Controller) Start() error { } } // Add new tag - err = c.addNewNode(c.nodeInfo) + err = c.server.AddNode(c.Tag, c.nodeInfo, c.ControllerConfig) if err != nil { return fmt.Errorf("add new tag failed: %s", err) } - err = c.addNewUser(c.userList, c.nodeInfo) + added, err := c.server.AddUsers(&core.AddUsersParams{}) + log.Printf("[%s: %d] Added %d new users", c.nodeInfo.NodeType, c.nodeInfo.NodeId, added) if err != nil { return err } diff --git a/node/inbound_test.go b/node/inbound_test.go deleted file mode 100644 index abc567d..0000000 --- a/node/inbound_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package node_test - -import ( - "github.com/Yuzuki616/V2bX/api/panel" - "github.com/Yuzuki616/V2bX/conf" - . "github.com/Yuzuki616/V2bX/node" - "testing" -) - -func TestBuildV2ray(t *testing.T) { - nodeInfo := &panel.NodeInfo{ - NodeType: "v2ray", - NodeId: 1, - ServerPort: 1145, - Network: "ws", - NetworkSettings: nil, - Host: "test.test.tk", - ServerName: "test.test.tk", - } - certConfig := &conf.CertConfig{ - CertMode: "none", - CertDomain: "test.test.tk", - Provider: "alidns", - Email: "test@gmail.com", - } - config := &conf.ControllerConfig{ - ListenIP: "0.0.0.0", - CertConfig: certConfig, - } - _, err := BuildInbound(config, nodeInfo, "11") - if err != nil { - t.Error(err) - } -} diff --git a/node/task.go b/node/task.go index c39fd5a..0a6835b 100644 --- a/node/task.go +++ b/node/task.go @@ -3,6 +3,8 @@ package node import ( "fmt" "github.com/Yuzuki616/V2bX/api/panel" + "github.com/Yuzuki616/V2bX/common/builder" + "github.com/Yuzuki616/V2bX/core" "github.com/Yuzuki616/V2bX/limiter" "github.com/Yuzuki616/V2bX/node/lego" "github.com/xtls/xray-core/common/task" @@ -61,7 +63,7 @@ func (c *Controller) nodeInfoMonitor() (err error) { if newNodeInfo != nil { // Remove old tag oldTag := c.Tag - err := c.removeOldNode(oldTag) + err := c.server.DelNode(oldTag) if err != nil { log.Print(err) return nil @@ -71,7 +73,7 @@ func (c *Controller) nodeInfoMonitor() (err error) { // Add new tag c.nodeInfo = newNodeInfo c.Tag = c.buildNodeTag() - err = c.addNewNode(newNodeInfo) + err = c.server.AddNode(c.Tag, newNodeInfo, c.ControllerConfig) if err != nil { log.Print(err) return nil @@ -88,7 +90,10 @@ func (c *Controller) nodeInfoMonitor() (err error) { c.userList = newUserInfo // Add new Limiter l := limiter.AddLimiter(c.Tag, &c.LimitConfig, newUserInfo) - err = c.addNewUser(newUserInfo, newNodeInfo) + _, err = c.server.AddUsers(&core.AddUsersParams{ + Tag: c.Tag, + Config: c.ControllerConfig, + }) if err != nil { log.Print(err) return nil @@ -132,7 +137,12 @@ func (c *Controller) nodeInfoMonitor() (err error) { } } if len(added) > 0 { - err = c.addNewUser(added, c.nodeInfo) + _, err := c.server.AddUsers(&core.AddUsersParams{ + Tag: c.Tag, + Config: c.ControllerConfig, + UserInfo: added, + NodeInfo: c.nodeInfo, + }) if err != nil { log.Print(err) } @@ -151,38 +161,6 @@ func (c *Controller) nodeInfoMonitor() (err error) { return nil } -func (c *Controller) removeOldNode(oldTag string) (err error) { - err = c.server.RemoveInbound(oldTag) - if err != nil { - return err - } - err = c.server.RemoveOutbound(oldTag) - if err != nil { - return err - } - return nil -} - -func (c *Controller) addNewNode(newNodeInfo *panel.NodeInfo) (err error) { - inboundConfig, err := BuildInbound(c.ControllerConfig, newNodeInfo, c.Tag) - if err != nil { - return fmt.Errorf("build inbound error: %s", err) - } - err = c.server.AddInbound(inboundConfig) - if err != nil { - return fmt.Errorf("add inbound error: %s", err) - } - outBoundConfig, err := buildOutbound(c.ControllerConfig, newNodeInfo, c.Tag) - if err != nil { - return fmt.Errorf("build outbound error: %s", err) - } - err = c.server.AddOutbound(outBoundConfig) - if err != nil { - return fmt.Errorf("add outbound error: %s", err) - } - return nil -} - func compareUserList(old, new []panel.UserInfo) (deleted, added []panel.UserInfo) { tmp := map[string]struct{}{} tmp2 := map[string]struct{}{} @@ -215,7 +193,7 @@ func (c *Controller) reportUserTraffic() (err error) { // Get User traffic userTraffic := make([]panel.UserTraffic, 0) for i := range c.userList { - up, down := c.server.GetUserTraffic(c.buildUserTag(&(c.userList)[i]), true) + up, down := c.server.GetUserTraffic(builder.BuildUserTag(c.Tag, &c.userList[i]), true) if up > 0 || down > 0 { if c.LimitConfig.EnableDynamicSpeedLimit { c.userList[i].Traffic += up + down