support custom core name

This commit is contained in:
Yuzuki616 2023-09-16 20:03:02 +08:00
parent db5059106c
commit 3a7d10c142
5 changed files with 107 additions and 46 deletions

View File

@ -6,6 +6,7 @@ import (
type CoreConfig struct { type CoreConfig struct {
Type string `json:"Type"` Type string `json:"Type"`
Name string `json:"Name"`
XrayConfig *XrayConfig `json:"-"` XrayConfig *XrayConfig `json:"-"`
SingConfig *SingConfig `json:"-"` SingConfig *SingConfig `json:"-"`
} }

View File

@ -2,10 +2,11 @@ package conf
import ( import (
"fmt" "fmt"
"github.com/InazumaV/V2bX/common/json5"
"github.com/goccy/go-json"
"io" "io"
"os" "os"
"github.com/InazumaV/V2bX/common/json5"
"github.com/goccy/go-json"
) )
type NodeConfig struct { type NodeConfig struct {
@ -85,6 +86,7 @@ func (n *NodeConfig) UnmarshalJSON(data []byte) (err error) {
type Options struct { type Options struct {
Name string `json:"Name"` Name string `json:"Name"`
Core string `json:"Core"` Core string `json:"Core"`
CoreName string `json:"CoreName"`
ListenIP string `json:"ListenIP"` ListenIP string `json:"ListenIP"`
SendIP string `json:"SendIP"` SendIP string `json:"SendIP"`
LimitConfig LimitConfig `json:"LimitConfig"` LimitConfig LimitConfig `json:"LimitConfig"`

View File

@ -2,7 +2,6 @@ package core
import ( import (
"errors" "errors"
"strings"
"github.com/InazumaV/V2bX/conf" "github.com/InazumaV/V2bX/conf"
) )
@ -17,21 +16,7 @@ func NewCore(c []conf.CoreConfig) (Core, error) {
} }
// multi core // multi core
if len(c) > 1 { if len(c) > 1 {
var cs []Core return NewSelector(c)
for _, t := range c {
f, ok := cores[strings.ToLower(t.Type)]
if !ok {
return nil, errors.New("unknown core type: " + t.Type)
}
core1, err := f(&t)
if err != nil {
return nil, err
}
cs = append(cs, core1)
}
return &Selector{
cores: cs,
}, nil
} }
// one core // one core
if f, ok := cores[c[0].Type]; ok { if f, ok := cores[c[0].Type]; ok {

View File

@ -3,6 +3,7 @@ package core
import ( import (
"errors" "errors"
"fmt" "fmt"
"strings"
"sync" "sync"
"github.com/InazumaV/V2bX/api/panel" "github.com/InazumaV/V2bX/api/panel"
@ -11,10 +12,32 @@ import (
) )
type Selector struct { type Selector struct {
cores []Core cores map[string]Core
nodes sync.Map nodes sync.Map
} }
func NewSelector(c []conf.CoreConfig) (Core, error) {
cs := make(map[string]Core, len(c))
for _, t := range c {
f, ok := cores[strings.ToLower(t.Type)]
if !ok {
return nil, errors.New("unknown core type: " + t.Type)
}
core1, err := f(&t)
if err != nil {
return nil, err
}
if t.Name == "" {
cs[t.Type] = core1
} else {
cs[t.Name] = core1
}
}
return &Selector{
cores: cs,
}, nil
}
func (s *Selector) 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()
@ -43,32 +66,47 @@ func isSupported(protocol string, protocols []string) bool {
} }
func (s *Selector) AddNode(tag string, info *panel.NodeInfo, option *conf.Options) error { func (s *Selector) AddNode(tag string, info *panel.NodeInfo, option *conf.Options) error {
for i, c := range s.cores { var core Core
if len(option.Core) == 0 { if len(option.CoreName) > 0 {
if !isSupported(info.Type, c.Protocols()) { // use name to select core
if c, ok := s.cores[option.CoreName]; ok {
core = c
}
} else {
// use type to select core
for _, c := range s.cores {
if len(option.Core) == 0 {
if !isSupported(info.Type, c.Protocols()) {
continue
}
} else if option.Core != c.Type() {
continue continue
} }
option.Core = c.Type() core = c
err := option.UnmarshalJSON(option.RawOptions)
if err != nil {
return fmt.Errorf("unmarshal option error: %s", err)
}
} else if option.Core != c.Type() {
continue
} }
err := c.AddNode(tag, info, option)
if err != nil {
return err
}
s.nodes.Store(tag, i)
return nil
} }
return errors.New("the node type is not support") if core == nil {
return errors.New("the node type is not support")
}
if len(option.Core) == 0 {
option.Core = core.Type()
err := option.UnmarshalJSON(option.RawOptions)
if err != nil {
return fmt.Errorf("unmarshal option error: %s", err)
}
option.RawOptions = nil
}
err := core.AddNode(tag, info, option)
if err != nil {
return err
}
s.nodes.Store(tag, core)
return nil
} }
func (s *Selector) 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.(string)].DelNode(tag)
if err != nil { if err != nil {
return err return err
} }
@ -83,7 +121,7 @@ func (s *Selector) AddUsers(p *AddUsersParams) (added int, err error) {
if !e { if !e {
return 0, errors.New("the node is not have") return 0, errors.New("the node is not have")
} }
return s.cores[t.(int)].AddUsers(p) return t.(Core).AddUsers(p)
} }
func (s *Selector) GetUserTraffic(tag, uuid string, reset bool) (up int64, down int64) { func (s *Selector) GetUserTraffic(tag, uuid string, reset bool) (up int64, down int64) {
@ -91,7 +129,7 @@ func (s *Selector) GetUserTraffic(tag, uuid string, reset bool) (up int64, down
if !e { if !e {
return 0, 0 return 0, 0
} }
return s.cores[t.(int)].GetUserTraffic(tag, uuid, reset) return t.(Core).GetUserTraffic(tag, uuid, reset)
} }
func (s *Selector) DelUsers(users []panel.UserInfo, tag string) error { func (s *Selector) DelUsers(users []panel.UserInfo, tag string) error {
@ -99,7 +137,7 @@ func (s *Selector) DelUsers(users []panel.UserInfo, tag string) error {
if !e { if !e {
return errors.New("the node is not have") return errors.New("the node is not have")
} }
return s.cores[t.(int)].DelUsers(users, tag) return t.(Core).DelUsers(users, tag)
} }
func (s *Selector) Protocols() []string { func (s *Selector) Protocols() []string {
@ -112,11 +150,18 @@ func (s *Selector) Protocols() []string {
func (s *Selector) Type() string { func (s *Selector) Type() string {
t := "Selector(" t := "Selector("
for i := range s.cores { var flag bool
if i != 0 { for n, c := range s.cores {
if flag {
t += " " t += " "
} else {
flag = true
}
if len(n) == 0 {
t += c.Type()
} else {
t += n
} }
t += s.cores[i].Type()
} }
t += ")" t += ")"
return t return t

View File

@ -4,6 +4,7 @@
// info, warn, error, none // info, warn, error, none
"Level": "error", "Level": "error",
// //
"Output": "" "Output": ""
}, },
@ -11,6 +12,10 @@
{ {
// Core // Core
"Type": "sing", "Type": "sing",
// Core
"Name": "sing1",
"Log": { "Log": {
// SingBox log // SingBox log
@ -26,6 +31,14 @@
} }
// More // More
}, },
{
"Type": "sing",
"Name": "sing2",
"Log": {
"Level": "info",
"Timestamp": false
},
},
{ {
"Type": "xray", "Type": "xray",
"Log": { "Log": {
@ -45,26 +58,42 @@
// Node便 // Node便
// //
"Name": "sing_node1", "Name": "sing_node1",
// Core
// 使Core
// CoreName
// CoreCoreName
"Core": "sing", "Core": "sing",
// 使Core
"CoreName": "sing1",
// API // API
"ApiHost": "http://127.0.0.1", "ApiHost": "http://127.0.0.1",
// APIToken // APIToken
"ApiKey": "test", "ApiKey": "test",
// ID // ID
"NodeID": 33, "NodeID": 33,
// //
"NodeType": "shadowsocks", "NodeType": "shadowsocks",
// //
"Timeout": 30, "Timeout": 30,
// IP // IP
"ListenIP": "0.0.0.0", "ListenIP": "0.0.0.0",
// IP // IP
"SendIP": "0.0.0.0", "SendIP": "0.0.0.0",
// Proxy Protocol https://github.com/haproxy/haproxy/blob/master/doc/proxy-protocol.txt // Proxy Protocol https://github.com/haproxy/haproxy/blob/master/doc/proxy-protocol.txt
"EnableProxyProtocol": false, "EnableProxyProtocol": false,
// TCP Fast Open // TCP Fast Open
"EnableTFO": true, "EnableTFO": true,
// Domain Strategy // Domain Strategy
// prefer_ipv4 / prefer_ipv6 / ipv4_only / ipv6_only // prefer_ipv4 / prefer_ipv6 / ipv4_only / ipv6_only
"DomainStrategy": "ipv4_only" "DomainStrategy": "ipv4_only"
@ -73,8 +102,7 @@
}, },
{ {
// //
"Include": "../example/config_node1.json",
"Include": "../example/config_node1.json"
} }
/*, /*,
{ {