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