mirror of
https://github.com/wyx2685/V2bX.git
synced 2025-01-22 09:58:14 -05:00
support custom core name
This commit is contained in:
parent
db5059106c
commit
3a7d10c142
@ -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:"-"`
|
||||||
}
|
}
|
||||||
|
@ -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"`
|
||||||
|
17
core/core.go
17
core/core.go
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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可不填
|
||||||
|
// 建议视情况填写Core和CoreName其中一个,如果均没有填写将随机选择支持的内核
|
||||||
"Core": "sing",
|
"Core": "sing",
|
||||||
|
|
||||||
|
// 要使用的Core的标识名,如果没有定义多个同类型内核可不填
|
||||||
|
"CoreName": "sing1",
|
||||||
|
|
||||||
// API接口地址
|
// API接口地址
|
||||||
"ApiHost": "http://127.0.0.1",
|
"ApiHost": "http://127.0.0.1",
|
||||||
|
|
||||||
// API密钥,即Token
|
// API密钥,即Token
|
||||||
"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"
|
|
||||||
}
|
}
|
||||||
/*,
|
/*,
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user