mirror of
https://github.com/wyx2685/V2bX.git
synced 2025-02-08 17:18:13 -05:00
fix bug,optimize performance
This commit is contained in:
parent
3eadd58da4
commit
5434e86d93
@ -50,6 +50,7 @@ type Client struct {
|
|||||||
RemoteRuleCache *Rule
|
RemoteRuleCache *Rule
|
||||||
access sync.Mutex
|
access sync.Mutex
|
||||||
NodeInfoRspMd5 [16]byte
|
NodeInfoRspMd5 [16]byte
|
||||||
|
NodeRuleRspMd5 [16]byte
|
||||||
UserListCheckNum int
|
UserListCheckNum int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
api/node.go
44
api/node.go
@ -2,6 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
md52 "crypto/md5"
|
md52 "crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/go-resty/resty/v2"
|
"github.com/go-resty/resty/v2"
|
||||||
@ -76,7 +77,7 @@ type SSConfig struct {
|
|||||||
type V2rayConfig struct {
|
type V2rayConfig struct {
|
||||||
Inbounds []conf.InboundDetourConfig `json:"inbounds"`
|
Inbounds []conf.InboundDetourConfig `json:"inbounds"`
|
||||||
Routing *struct {
|
Routing *struct {
|
||||||
Rules []Rule `json:"rules"`
|
Rules *json.RawMessage `json:"rules"`
|
||||||
} `json:"routing"`
|
} `json:"routing"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,10 +105,6 @@ func (c *Client) GetNodeInfo() (nodeInfo *NodeInfo, err error) {
|
|||||||
switch c.NodeType {
|
switch c.NodeType {
|
||||||
case "V2ray":
|
case "V2ray":
|
||||||
path = "/api/v1/server/Deepbwork/config"
|
path = "/api/v1/server/Deepbwork/config"
|
||||||
res, err = c.client.R().
|
|
||||||
SetQueryParam("local_port", "1").
|
|
||||||
ForceContentType("application/json").
|
|
||||||
Get(path)
|
|
||||||
case "Trojan":
|
case "Trojan":
|
||||||
path = "/api/v1/server/TrojanTidalab/config"
|
path = "/api/v1/server/TrojanTidalab/config"
|
||||||
case "Shadowsocks":
|
case "Shadowsocks":
|
||||||
@ -119,13 +116,6 @@ func (c *Client) GetNodeInfo() (nodeInfo *NodeInfo, err error) {
|
|||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unsupported Node type: %s", c.NodeType)
|
return nil, fmt.Errorf("unsupported Node type: %s", c.NodeType)
|
||||||
}
|
}
|
||||||
md := md52.Sum(res.Body())
|
|
||||||
if c.NodeInfoRspMd5 != [16]byte{} {
|
|
||||||
if c.NodeInfoRspMd5 == md {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.NodeInfoRspMd5 = md
|
|
||||||
res, err = c.client.R().
|
res, err = c.client.R().
|
||||||
SetQueryParam("local_port", "1").
|
SetQueryParam("local_port", "1").
|
||||||
ForceContentType("application/json").
|
ForceContentType("application/json").
|
||||||
@ -134,12 +124,25 @@ func (c *Client) GetNodeInfo() (nodeInfo *NodeInfo, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
i := bytes.Index(res.Body(), []byte("outbo"))
|
||||||
|
md := md52.Sum(res.Body()[:i])
|
||||||
|
nodeIsNotChange := false
|
||||||
|
if c.NodeInfoRspMd5 != [16]byte{} {
|
||||||
|
if c.NodeInfoRspMd5 == md {
|
||||||
|
nodeIsNotChange = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.NodeInfoRspMd5 = md
|
||||||
c.access.Lock()
|
c.access.Lock()
|
||||||
defer c.access.Unlock()
|
defer c.access.Unlock()
|
||||||
switch c.NodeType {
|
switch c.NodeType {
|
||||||
case "V2ray":
|
case "V2ray":
|
||||||
nodeInfo, err = c.ParseV2rayNodeResponse(res.Body())
|
md2 := md52.Sum(res.Body()[i:])
|
||||||
|
nodeInfo, err = c.ParseV2rayNodeResponse(res.Body(), nodeIsNotChange, c.NodeRuleRspMd5 != md2)
|
||||||
case "Trojan":
|
case "Trojan":
|
||||||
|
if nodeIsNotChange {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
nodeInfo, err = c.ParseTrojanNodeResponse(res.Body())
|
nodeInfo, err = c.ParseTrojanNodeResponse(res.Body())
|
||||||
}
|
}
|
||||||
return nodeInfo, nil
|
return nodeInfo, nil
|
||||||
@ -147,7 +150,7 @@ func (c *Client) GetNodeInfo() (nodeInfo *NodeInfo, err error) {
|
|||||||
|
|
||||||
func (c *Client) GetNodeRule() (*[]DetectRule, error) {
|
func (c *Client) GetNodeRule() (*[]DetectRule, error) {
|
||||||
ruleList := c.LocalRuleList
|
ruleList := c.LocalRuleList
|
||||||
if c.NodeType != "V2ray" {
|
if c.NodeType != "V2ray" || c.RemoteRuleCache == nil {
|
||||||
return &ruleList, nil
|
return &ruleList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +165,7 @@ func (c *Client) GetNodeRule() (*[]DetectRule, error) {
|
|||||||
}
|
}
|
||||||
ruleList = append(ruleList, ruleListItem)
|
ruleList = append(ruleList, ruleListItem)
|
||||||
}
|
}
|
||||||
|
c.RemoteRuleCache = nil
|
||||||
return &ruleList, nil
|
return &ruleList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,18 +215,24 @@ func (c *Client) ParseSSNodeResponse() (*NodeInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParseV2rayNodeResponse parse the response for the given nodeinfor format
|
// ParseV2rayNodeResponse parse the response for the given nodeinfor format
|
||||||
func (c *Client) ParseV2rayNodeResponse(body []byte) (*NodeInfo, error) {
|
func (c *Client) ParseV2rayNodeResponse(body []byte, notParseNode, parseRule bool) (*NodeInfo, error) {
|
||||||
node := &NodeInfo{V2ray: &V2rayConfig{}}
|
node := &NodeInfo{V2ray: &V2rayConfig{}}
|
||||||
err := json.Unmarshal(body, node.V2ray)
|
err := json.Unmarshal(body, node.V2ray)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unmarshal nodeinfo error: %s", err)
|
return nil, fmt.Errorf("unmarshal nodeinfo error: %s", err)
|
||||||
}
|
}
|
||||||
|
if parseRule {
|
||||||
|
json.Unmarshal(*node.V2ray.Routing.Rules, c.RemoteRuleCache)
|
||||||
|
}
|
||||||
|
node.V2ray.Routing = nil
|
||||||
|
if notParseNode {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
node.SpeedLimit = uint64(c.SpeedLimit * 1000000 / 8)
|
node.SpeedLimit = uint64(c.SpeedLimit * 1000000 / 8)
|
||||||
node.DeviceLimit = c.DeviceLimit
|
node.DeviceLimit = c.DeviceLimit
|
||||||
node.NodeType = c.NodeType
|
node.NodeType = c.NodeType
|
||||||
node.NodeId = c.NodeID
|
node.NodeId = c.NodeID
|
||||||
c.RemoteRuleCache = &node.V2ray.Routing.Rules[0]
|
|
||||||
node.V2ray.Routing = nil
|
|
||||||
if c.EnableXTLS {
|
if c.EnableXTLS {
|
||||||
node.TLSType = "xtls"
|
node.TLSType = "xtls"
|
||||||
} else {
|
} else {
|
||||||
|
@ -69,15 +69,18 @@ func (c *Client) GetUserList() (UserList *[]UserInfo, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unmarshal userlist error: %s", err)
|
return nil, fmt.Errorf("unmarshal userlist error: %s", err)
|
||||||
}
|
}
|
||||||
checkNum := userList.Data[len(userList.Data)-1].UID +
|
l := len(userList.Data)
|
||||||
userList.Data[len(userList.Data)/2-1].UID +
|
checkNum := userList.Data[l-1].UID +
|
||||||
|
userList.Data[l/2-1].UID +
|
||||||
userList.Data[0].UID
|
userList.Data[0].UID
|
||||||
if c.UserListCheckNum != 0 {
|
if c.UserListCheckNum != 0 {
|
||||||
if c.UserListCheckNum == checkNum {
|
if c.UserListCheckNum == checkNum {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.UserListCheckNum = userList.Data[len(userList.Data)-1].UID
|
c.UserListCheckNum = userList.Data[l-1].UID +
|
||||||
|
userList.Data[l/2-1].UID +
|
||||||
|
userList.Data[0].UID
|
||||||
return &userList.Data, nil
|
return &userList.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -99,6 +100,7 @@ func (c *Controller) Start() error {
|
|||||||
time.Sleep(time.Duration(c.config.UpdatePeriodic) * time.Second)
|
time.Sleep(time.Duration(c.config.UpdatePeriodic) * time.Second)
|
||||||
_ = c.userReportPeriodic.Start()
|
_ = c.userReportPeriodic.Start()
|
||||||
}()
|
}()
|
||||||
|
runtime.GC()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +133,7 @@ func (c *Controller) nodeInfoMonitor() (err error) {
|
|||||||
var nodeInfoChanged = false
|
var nodeInfoChanged = false
|
||||||
// If nodeInfo changed
|
// If nodeInfo changed
|
||||||
if newNodeInfo != nil {
|
if newNodeInfo != nil {
|
||||||
|
if !reflect.DeepEqual(c.nodeInfo, newNodeInfo) {
|
||||||
// Remove old tag
|
// Remove old tag
|
||||||
oldtag := c.Tag
|
oldtag := c.Tag
|
||||||
err := c.removeOldTag(oldtag)
|
err := c.removeOldTag(oldtag)
|
||||||
@ -153,12 +156,13 @@ func (c *Controller) nodeInfoMonitor() (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check Rule
|
// Check Rule
|
||||||
if !c.config.DisableGetRule {
|
if !c.config.DisableGetRule {
|
||||||
if ruleList, err := c.apiClient.GetNodeRule(); err != nil {
|
if ruleList, err := c.apiClient.GetNodeRule(); err != nil {
|
||||||
log.Printf("Get rule list filed: %s", err)
|
log.Printf("Get rule list filed: %s", err)
|
||||||
} else if len(*ruleList) > 0 {
|
} else if ruleList != nil {
|
||||||
if err := c.UpdateRule(c.Tag, *ruleList); err != nil {
|
if err := c.UpdateRule(c.Tag, *ruleList); err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
@ -185,9 +189,6 @@ func (c *Controller) nodeInfoMonitor() (err error) {
|
|||||||
log.Print(err)
|
log.Print(err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if newUserInfo == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if nodeInfoChanged {
|
if nodeInfoChanged {
|
||||||
if newUserInfo != nil {
|
if newUserInfo != nil {
|
||||||
c.userList = newUserInfo
|
c.userList = newUserInfo
|
||||||
@ -197,12 +198,15 @@ func (c *Controller) nodeInfoMonitor() (err error) {
|
|||||||
log.Print(err)
|
log.Print(err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
newNodeInfo = nil
|
||||||
// Add Limiter
|
// Add Limiter
|
||||||
if err := c.AddInboundLimiter(c.Tag, newUserInfo); err != nil {
|
if err := c.AddInboundLimiter(c.Tag, newUserInfo); err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
} else {
|
newUserInfo = nil
|
||||||
|
runtime.GC()
|
||||||
|
} else if newUserInfo != nil {
|
||||||
deleted, added := compareUserList(c.userList, newUserInfo)
|
deleted, added := compareUserList(c.userList, newUserInfo)
|
||||||
if len(deleted) > 0 {
|
if len(deleted) > 0 {
|
||||||
deletedEmail := make([]string, len(deleted))
|
deletedEmail := make([]string, len(deleted))
|
||||||
@ -229,8 +233,9 @@ func (c *Controller) nodeInfoMonitor() (err error) {
|
|||||||
log.Printf("[%s: %d] %d user deleted, %d user added", c.nodeInfo.NodeType, c.nodeInfo.NodeId,
|
log.Printf("[%s: %d] %d user deleted, %d user added", c.nodeInfo.NodeType, c.nodeInfo.NodeId,
|
||||||
len(deleted), len(added))
|
len(deleted), len(added))
|
||||||
c.userList = newUserInfo
|
c.userList = newUserInfo
|
||||||
}
|
newUserInfo = nil
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,11 +366,11 @@ func compareUserList(old, new *[]api.UserInfo) (deleted, added []int) {
|
|||||||
func (c *Controller) userInfoMonitor() (err error) {
|
func (c *Controller) userInfoMonitor() (err error) {
|
||||||
// Get User traffic
|
// Get User traffic
|
||||||
userTraffic := make([]api.UserTraffic, 0)
|
userTraffic := make([]api.UserTraffic, 0)
|
||||||
for _, user := range *c.userList {
|
for i := range *c.userList {
|
||||||
up, down := c.getTraffic(c.buildUserTag(&user))
|
up, down := c.getTraffic(c.buildUserTag(&(*c.userList)[i]))
|
||||||
if up > 0 || down > 0 {
|
if up > 0 || down > 0 {
|
||||||
userTraffic = append(userTraffic, api.UserTraffic{
|
userTraffic = append(userTraffic, api.UserTraffic{
|
||||||
UID: user.UID,
|
UID: (*c.userList)[i].UID,
|
||||||
Upload: up,
|
Upload: up,
|
||||||
Download: down})
|
Download: down})
|
||||||
}
|
}
|
||||||
@ -389,6 +394,8 @@ func (c *Controller) userInfoMonitor() (err error) {
|
|||||||
} else {
|
} else {
|
||||||
log.Printf("[%s: %d] Report %d illegal behaviors", c.nodeInfo.NodeType, c.nodeInfo.NodeId, len(*detectResult))
|
log.Printf("[%s: %d] Report %d illegal behaviors", c.nodeInfo.NodeType, c.nodeInfo.NodeId, len(*detectResult))
|
||||||
}
|
}
|
||||||
|
userTraffic = nil
|
||||||
|
runtime.GC()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@ import (
|
|||||||
func InboundBuilder(config *Config, nodeInfo *api.NodeInfo, tag string) (*core.InboundHandlerConfig, error) {
|
func InboundBuilder(config *Config, nodeInfo *api.NodeInfo, tag string) (*core.InboundHandlerConfig, error) {
|
||||||
var proxySetting interface{}
|
var proxySetting interface{}
|
||||||
if nodeInfo.NodeType == "V2ray" {
|
if nodeInfo.NodeType == "V2ray" {
|
||||||
defer func() { nodeInfo.V2ray = nil }()
|
defer func() {
|
||||||
|
nodeInfo.V2ray = nil
|
||||||
|
}()
|
||||||
if nodeInfo.EnableVless {
|
if nodeInfo.EnableVless {
|
||||||
nodeInfo.V2ray.Inbounds[0].Protocol = "vless"
|
nodeInfo.V2ray.Inbounds[0].Protocol = "vless"
|
||||||
// Enable fallback
|
// Enable fallback
|
||||||
@ -40,7 +42,10 @@ func InboundBuilder(config *Config, nodeInfo *api.NodeInfo, tag string) (*core.I
|
|||||||
proxySetting = &conf.VMessInboundConfig{}
|
proxySetting = &conf.VMessInboundConfig{}
|
||||||
}
|
}
|
||||||
} else if nodeInfo.NodeType == "Trojan" {
|
} else if nodeInfo.NodeType == "Trojan" {
|
||||||
defer func() { nodeInfo.V2ray = nil; nodeInfo.Trojan = nil }()
|
defer func() {
|
||||||
|
nodeInfo.V2ray = nil
|
||||||
|
nodeInfo.Trojan = nil
|
||||||
|
}()
|
||||||
nodeInfo.V2ray = &api.V2rayConfig{}
|
nodeInfo.V2ray = &api.V2rayConfig{}
|
||||||
nodeInfo.V2ray.Inbounds = make([]conf.InboundDetourConfig, 1)
|
nodeInfo.V2ray.Inbounds = make([]conf.InboundDetourConfig, 1)
|
||||||
nodeInfo.V2ray.Inbounds[0].Protocol = "trojan"
|
nodeInfo.V2ray.Inbounds[0].Protocol = "trojan"
|
||||||
@ -63,6 +68,10 @@ func InboundBuilder(config *Config, nodeInfo *api.NodeInfo, tag string) (*core.I
|
|||||||
t := conf.TransportProtocol(nodeInfo.SS.TransportProtocol)
|
t := conf.TransportProtocol(nodeInfo.SS.TransportProtocol)
|
||||||
nodeInfo.V2ray.Inbounds[0].StreamSetting = &conf.StreamConfig{Network: &t}
|
nodeInfo.V2ray.Inbounds[0].StreamSetting = &conf.StreamConfig{Network: &t}
|
||||||
} else if nodeInfo.NodeType == "Shadowsocks" {
|
} else if nodeInfo.NodeType == "Shadowsocks" {
|
||||||
|
defer func() {
|
||||||
|
nodeInfo.V2ray = nil
|
||||||
|
nodeInfo.SS = nil
|
||||||
|
}()
|
||||||
defer func() { nodeInfo.V2ray = nil; nodeInfo.SS = nil }()
|
defer func() { nodeInfo.V2ray = nil; nodeInfo.SS = nil }()
|
||||||
nodeInfo.V2ray = &api.V2rayConfig{}
|
nodeInfo.V2ray = &api.V2rayConfig{}
|
||||||
nodeInfo.V2ray.Inbounds = []conf.InboundDetourConfig{{Protocol: "shadowsocks"}}
|
nodeInfo.V2ray.Inbounds = []conf.InboundDetourConfig{{Protocol: "shadowsocks"}}
|
||||||
|
Loading…
Reference in New Issue
Block a user