mirror of
https://github.com/wyx2685/V2bX.git
synced 2026-02-06 05:30:08 +00:00
16
conf/node.go
16
conf/node.go
@@ -15,15 +15,13 @@ type ApiConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ControllerConfig struct {
|
type ControllerConfig struct {
|
||||||
DisableUploadTraffic bool `yaml:"DisableUploadTraffic"`
|
ListenIP string `yaml:"ListenIP"`
|
||||||
DisableGetRule bool `yaml:"DisableGetRule"`
|
SendIP string `yaml:"SendIP"`
|
||||||
ListenIP string `yaml:"ListenIP"`
|
EnableProxyProtocol bool `yaml:"EnableProxyProtocol"`
|
||||||
SendIP string `yaml:"SendIP"`
|
XrayOptions XrayOptions `yaml:"XrayOptions"`
|
||||||
EnableProxyProtocol bool `yaml:"EnableProxyProtocol"`
|
HyOptions HyOptions `yaml:"HyOptions"`
|
||||||
XrayOptions XrayOptions `yaml:"XrayOptions"`
|
LimitConfig LimitConfig `yaml:"LimitConfig"`
|
||||||
HyOptions HyOptions `yaml:"HyOptions"`
|
CertConfig *CertConfig `yaml:"CertConfig"`
|
||||||
LimitConfig LimitConfig `yaml:"LimitConfig"`
|
|
||||||
CertConfig *CertConfig `yaml:"CertConfig"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type XrayOptions struct {
|
type XrayOptions struct {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func NewCore(c *conf.CoreConfig) (Core, error) {
|
|||||||
}
|
}
|
||||||
cs = append(cs, core1)
|
cs = append(cs, core1)
|
||||||
}
|
}
|
||||||
return &Selecter{
|
return &Selector{
|
||||||
cores: cs,
|
cores: cs,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"github.com/Yuzuki616/V2bX/api/panel"
|
"github.com/Yuzuki616/V2bX/api/panel"
|
||||||
"github.com/Yuzuki616/V2bX/conf"
|
"github.com/Yuzuki616/V2bX/conf"
|
||||||
"github.com/Yuzuki616/V2bX/limiter"
|
"github.com/Yuzuki616/V2bX/limiter"
|
||||||
"github.com/apernet/hysteria/core/cs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Hy) AddNode(tag string, info *panel.NodeInfo, c *conf.ControllerConfig) error {
|
func (h *Hy) AddNode(tag string, info *panel.NodeInfo, c *conf.ControllerConfig) error {
|
||||||
@@ -32,7 +31,7 @@ func (h *Hy) AddNode(tag string, info *panel.NodeInfo, c *conf.ControllerConfig)
|
|||||||
|
|
||||||
func (h *Hy) DelNode(tag string) error {
|
func (h *Hy) DelNode(tag string) error {
|
||||||
if s, e := h.servers.Load(tag); e {
|
if s, e := h.servers.Load(tag); e {
|
||||||
err := s.(*cs.Server).Close()
|
err := s.(*Server).Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ func (h *Hy) GetUserTraffic(tag, uuid string, reset bool) (up int64, down int64)
|
|||||||
s := v.(*Server)
|
s := v.(*Server)
|
||||||
auth := base64.StdEncoding.EncodeToString([]byte(uuid))
|
auth := base64.StdEncoding.EncodeToString([]byte(uuid))
|
||||||
up = s.counter.getCounters(auth).UpCounter.Load()
|
up = s.counter.getCounters(auth).UpCounter.Load()
|
||||||
down = s.counter.getCounters(uuid).DownCounter.Load()
|
down = s.counter.getCounters(auth).DownCounter.Load()
|
||||||
if reset {
|
if reset {
|
||||||
s.counter.Reset(uuid)
|
s.counter.Reset(auth)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ import (
|
|||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Selecter struct {
|
type Selector struct {
|
||||||
cores []Core
|
cores []Core
|
||||||
nodes sync.Map
|
nodes sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Selecter) Start() error {
|
func (s *Selector) Start() error {
|
||||||
for i := range s.cores {
|
for i := range s.cores {
|
||||||
err := s.cores[i].Start()
|
err := s.cores[i].Start()
|
||||||
return err
|
return err
|
||||||
@@ -22,7 +22,7 @@ func (s *Selecter) Start() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Selecter) Close() error {
|
func (s *Selector) Close() error {
|
||||||
var errs error
|
var errs error
|
||||||
for i := range s.cores {
|
for i := range s.cores {
|
||||||
errs = multierror.Append(errs, s.cores[i].Close())
|
errs = multierror.Append(errs, s.cores[i].Close())
|
||||||
@@ -39,7 +39,7 @@ func isSupported(protocol string, protocols []string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Selecter) AddNode(tag string, info *panel.NodeInfo, config *conf.ControllerConfig) error {
|
func (s *Selector) AddNode(tag string, info *panel.NodeInfo, config *conf.ControllerConfig) error {
|
||||||
for i := range s.cores {
|
for i := range s.cores {
|
||||||
if !isSupported(info.Type, s.cores[i].Protocols()) {
|
if !isSupported(info.Type, s.cores[i].Protocols()) {
|
||||||
continue
|
continue
|
||||||
@@ -53,7 +53,7 @@ func (s *Selecter) AddNode(tag string, info *panel.NodeInfo, config *conf.Contro
|
|||||||
return errors.New("the node type is not support")
|
return errors.New("the node type is not support")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Selecter) DelNode(tag string) error {
|
func (s *Selector) DelNode(tag string) error {
|
||||||
if t, e := s.nodes.Load(tag); e {
|
if t, e := s.nodes.Load(tag); e {
|
||||||
err := s.cores[t.(int)].DelNode(tag)
|
err := s.cores[t.(int)].DelNode(tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -65,7 +65,7 @@ func (s *Selecter) DelNode(tag string) error {
|
|||||||
return errors.New("the node is not have")
|
return errors.New("the node is not have")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Selecter) AddUsers(p *AddUsersParams) (added int, err error) {
|
func (s *Selector) AddUsers(p *AddUsersParams) (added int, err error) {
|
||||||
t, e := s.nodes.Load(p.Tag)
|
t, e := s.nodes.Load(p.Tag)
|
||||||
if !e {
|
if !e {
|
||||||
return 0, errors.New("the node is not have")
|
return 0, errors.New("the node is not have")
|
||||||
@@ -73,7 +73,7 @@ func (s *Selecter) AddUsers(p *AddUsersParams) (added int, err error) {
|
|||||||
return s.cores[t.(int)].AddUsers(p)
|
return s.cores[t.(int)].AddUsers(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Selecter) GetUserTraffic(tag, uuid string, reset bool) (up int64, down int64) {
|
func (s *Selector) GetUserTraffic(tag, uuid string, reset bool) (up int64, down int64) {
|
||||||
t, e := s.nodes.Load(tag)
|
t, e := s.nodes.Load(tag)
|
||||||
if !e {
|
if !e {
|
||||||
return 0, 0
|
return 0, 0
|
||||||
@@ -81,7 +81,7 @@ func (s *Selecter) GetUserTraffic(tag, uuid string, reset bool) (up int64, down
|
|||||||
return s.cores[t.(int)].GetUserTraffic(tag, uuid, reset)
|
return s.cores[t.(int)].GetUserTraffic(tag, uuid, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Selecter) DelUsers(users []string, tag string) error {
|
func (s *Selector) DelUsers(users []string, tag string) error {
|
||||||
t, e := s.nodes.Load(tag)
|
t, e := s.nodes.Load(tag)
|
||||||
if !e {
|
if !e {
|
||||||
return errors.New("the node is not have")
|
return errors.New("the node is not have")
|
||||||
@@ -89,7 +89,7 @@ func (s *Selecter) DelUsers(users []string, tag string) error {
|
|||||||
return s.cores[t.(int)].DelUsers(users, tag)
|
return s.cores[t.(int)].DelUsers(users, tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Selecter) Protocols() []string {
|
func (s *Selector) Protocols() []string {
|
||||||
protocols := make([]string, 0)
|
protocols := make([]string, 0)
|
||||||
for i := range s.cores {
|
for i := range s.cores {
|
||||||
protocols = append(protocols, s.cores[i].Protocols()...)
|
protocols = append(protocols, s.cores[i].Protocols()...)
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
CoreConfig:
|
CoreConfig:
|
||||||
Type: "xray" # Core type. if you need many cores, use " " to split
|
Type: "xray" # Core type, default support "xray" and "hy". If you need many cores, use " " to split
|
||||||
XrayConfig:
|
XrayConfig:
|
||||||
Log:
|
Log:
|
||||||
Level: warning # Log level: none, error, warning, info, debug
|
Level: warning # Log level: none, error, warning, info, debug
|
||||||
@@ -39,7 +39,7 @@ Nodes:
|
|||||||
Alpn: # Alpn, Empty for any
|
Alpn: # Alpn, Empty for any
|
||||||
Path: # HTTP PATH, Empty for any
|
Path: # HTTP PATH, Empty for any
|
||||||
Dest: 80 # Required, Destination of fallback, check https://xtls.github.io/config/features/fallback.html for details.
|
Dest: 80 # Required, Destination of fallback, check https://xtls.github.io/config/features/fallback.html for details.
|
||||||
ProxyProtocolVer: 0 # Send PROXY protocol version, 0 for dsable
|
ProxyProtocolVer: 0 # Send PROXY protocol version, 0 for disable
|
||||||
HyOptions:
|
HyOptions:
|
||||||
Resolver: "udp://1.1.1.1:53" # DNS resolver address
|
Resolver: "udp://1.1.1.1:53" # DNS resolver address
|
||||||
ResolvePreference: 64 # DNS IPv4/IPv6 preference. Available options: "64" (IPv6 first, fallback to IPv4), "46" (IPv4 first, fallback to IPv6), "6" (IPv6 only), "4" (IPv4 only)
|
ResolvePreference: 64 # DNS IPv4/IPv6 preference. Available options: "64" (IPv6 first, fallback to IPv4), "46" (IPv4 first, fallback to IPv6), "6" (IPv6 only), "4" (IPv4 only)
|
||||||
|
|||||||
@@ -58,10 +58,8 @@ func (c *Controller) Start() error {
|
|||||||
// add limiter
|
// add limiter
|
||||||
l := limiter.AddLimiter(c.Tag, &c.LimitConfig, c.userList)
|
l := limiter.AddLimiter(c.Tag, &c.LimitConfig, c.userList)
|
||||||
// add rule limiter
|
// add rule limiter
|
||||||
if !c.DisableGetRule {
|
if err = l.UpdateRule(c.nodeInfo.Rules); err != nil {
|
||||||
if err = l.UpdateRule(c.nodeInfo.Rules); err != nil {
|
return fmt.Errorf("update rule error: %s", err)
|
||||||
return fmt.Errorf("update rule error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if c.nodeInfo.Tls || c.nodeInfo.Type == "hysteria" {
|
if c.nodeInfo.Tls || c.nodeInfo.Type == "hysteria" {
|
||||||
err = c.requestCert()
|
err = c.requestCert()
|
||||||
@@ -83,7 +81,7 @@ func (c *Controller) Start() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("add users error: %s", err)
|
return fmt.Errorf("add users error: %s", err)
|
||||||
}
|
}
|
||||||
log.Printf("[%s: %d] Added %d new users", c.nodeInfo.Type, c.nodeInfo.Id, added)
|
log.Printf("[%s] Added %d new users", c.Tag, added)
|
||||||
c.initTask()
|
c.initTask()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
133
node/task.go
133
node/task.go
@@ -41,50 +41,44 @@ func (c *Controller) initTask() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) nodeInfoMonitor() (err error) {
|
func (c *Controller) nodeInfoMonitor() (err error) {
|
||||||
// First fetch Node Info
|
// get node info
|
||||||
newNodeInfo, err := c.apiClient.GetNodeInfo()
|
newNodeInfo, err := c.apiClient.GetNodeInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Printf("[%s] Get node info error: %s", c.Tag, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// get user info
|
||||||
|
newUserInfo, err := c.apiClient.GetUserList()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[%s] Get user list error: %s", c.Tag, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var nodeInfoChanged = false
|
|
||||||
// If nodeInfo changed
|
|
||||||
if newNodeInfo != nil {
|
if newNodeInfo != nil {
|
||||||
|
// nodeInfo changed
|
||||||
// Remove old tag
|
// Remove old tag
|
||||||
oldTag := c.Tag
|
err = c.server.DelNode(c.Tag)
|
||||||
err := c.server.DelNode(oldTag)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Printf("[%s] Del node error: %s", c.Tag, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Remove Old limiter
|
// Remove Old limiter
|
||||||
limiter.DeleteLimiter(oldTag)
|
limiter.DeleteLimiter(c.Tag)
|
||||||
// Add new tag
|
// Add new Limiter
|
||||||
c.nodeInfo = newNodeInfo
|
|
||||||
c.Tag = c.buildNodeTag()
|
c.Tag = c.buildNodeTag()
|
||||||
err = c.server.AddNode(c.Tag, newNodeInfo, c.ControllerConfig)
|
l := limiter.AddLimiter(c.Tag, &c.LimitConfig, newUserInfo)
|
||||||
if err != nil {
|
// check cert
|
||||||
log.Print(err)
|
if newNodeInfo.Tls || newNodeInfo.Type == "hysteria" {
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if c.nodeInfo.Tls || c.nodeInfo.Type == "hysteria" {
|
|
||||||
err = c.requestCert()
|
err = c.requestCert()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("request cert error: %s", err)
|
log.Printf("[%s] Request cert error: %s", c.Tag, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nodeInfoChanged = true
|
// add new node
|
||||||
}
|
err = c.server.AddNode(c.Tag, newNodeInfo, c.ControllerConfig)
|
||||||
// Update User
|
if err != nil {
|
||||||
newUserInfo, err := c.apiClient.GetUserList()
|
log.Printf("[%s] Add node error: %s", c.Tag, err)
|
||||||
if err != nil {
|
return nil
|
||||||
log.Print(err)
|
}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if nodeInfoChanged {
|
|
||||||
c.userList = newUserInfo
|
|
||||||
// Add new Limiter
|
|
||||||
l := limiter.AddLimiter(c.Tag, &c.LimitConfig, newUserInfo)
|
|
||||||
_, err = c.server.AddUsers(&vCore.AddUsersParams{
|
_, err = c.server.AddUsers(&vCore.AddUsersParams{
|
||||||
Tag: c.Tag,
|
Tag: c.Tag,
|
||||||
Config: c.ControllerConfig,
|
Config: c.ControllerConfig,
|
||||||
@@ -92,12 +86,12 @@ func (c *Controller) nodeInfoMonitor() (err error) {
|
|||||||
NodeInfo: newNodeInfo,
|
NodeInfo: newNodeInfo,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Printf("[%s] Add users error: %s", c.Tag, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err = l.UpdateRule(newNodeInfo.Rules)
|
err = l.UpdateRule(newNodeInfo.Rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Update Rule error: %s", err)
|
log.Printf("[%s] Update Rule error: %s", c.Tag, err)
|
||||||
}
|
}
|
||||||
// Check interval
|
// Check interval
|
||||||
if c.nodeInfoMonitorPeriodic.Interval != newNodeInfo.PullInterval &&
|
if c.nodeInfoMonitorPeriodic.Interval != newNodeInfo.PullInterval &&
|
||||||
@@ -112,42 +106,49 @@ func (c *Controller) nodeInfoMonitor() (err error) {
|
|||||||
c.userReportPeriodic.Close()
|
c.userReportPeriodic.Close()
|
||||||
_ = c.userReportPeriodic.Start(false)
|
_ = c.userReportPeriodic.Start(false)
|
||||||
}
|
}
|
||||||
} else {
|
c.nodeInfo = newNodeInfo
|
||||||
deleted, added := compareUserList(c.userList, newUserInfo)
|
|
||||||
if len(deleted) > 0 {
|
|
||||||
deletedEmail := make([]string, len(deleted))
|
|
||||||
for i := range deleted {
|
|
||||||
deletedEmail[i] = fmt.Sprintf("%s|%s|%d",
|
|
||||||
c.Tag,
|
|
||||||
(deleted)[i].Uuid,
|
|
||||||
(deleted)[i].Id)
|
|
||||||
}
|
|
||||||
err := c.server.DelUsers(deletedEmail, c.Tag)
|
|
||||||
if err != nil {
|
|
||||||
log.Print(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(added) > 0 {
|
|
||||||
_, err := c.server.AddUsers(&vCore.AddUsersParams{
|
|
||||||
Tag: c.Tag,
|
|
||||||
Config: c.ControllerConfig,
|
|
||||||
UserInfo: added,
|
|
||||||
NodeInfo: c.nodeInfo,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Print(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(added) > 0 || len(deleted) > 0 {
|
|
||||||
// Update Limiter
|
|
||||||
err = limiter.UpdateLimiter(c.Tag, added, deleted)
|
|
||||||
if err != nil {
|
|
||||||
log.Print("update limiter:", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Printf("[%s: %d] %d user deleted, %d user added", c.nodeInfo.Type, c.nodeInfo.Id,
|
|
||||||
len(deleted), len(added))
|
|
||||||
c.userList = newUserInfo
|
c.userList = newUserInfo
|
||||||
|
// exit
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// node no changed, check users
|
||||||
|
deleted, added := compareUserList(c.userList, newUserInfo)
|
||||||
|
if len(deleted) > 0 {
|
||||||
|
// have deleted users
|
||||||
|
deletedEmail := make([]string, len(deleted))
|
||||||
|
for i := range deleted {
|
||||||
|
deletedEmail[i] = fmt.Sprintf("%s|%s|%d",
|
||||||
|
c.Tag,
|
||||||
|
(deleted)[i].Uuid,
|
||||||
|
(deleted)[i].Id)
|
||||||
|
}
|
||||||
|
err = c.server.DelUsers(deletedEmail, c.Tag)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[%s] Del users error: %s", c.Tag, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(added) > 0 {
|
||||||
|
// have added users
|
||||||
|
_, err = c.server.AddUsers(&vCore.AddUsersParams{
|
||||||
|
Tag: c.Tag,
|
||||||
|
Config: c.ControllerConfig,
|
||||||
|
UserInfo: added,
|
||||||
|
NodeInfo: c.nodeInfo,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[%s] Add users error: %s", c.Tag, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(added) > 0 || len(deleted) > 0 {
|
||||||
|
// update Limiter
|
||||||
|
err = limiter.UpdateLimiter(c.Tag, added, deleted)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[%s] Update limiter error: %s", c.Tag, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.userList = newUserInfo
|
||||||
|
log.Printf("[%s] %d user deleted, %d user added", c.Tag,
|
||||||
|
len(deleted), len(added))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func (c *Controller) reportUserTrafficTask() (err error) {
|
|||||||
Download: down})
|
Download: down})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(userTraffic) > 0 && !c.DisableUploadTraffic {
|
if len(userTraffic) > 0 {
|
||||||
err = c.apiClient.ReportUserTraffic(userTraffic)
|
err = c.apiClient.ReportUserTraffic(userTraffic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Report user traffic faild: %s", err)
|
log.Printf("Report user traffic faild: %s", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user