fix bug,optimize performance

This commit is contained in:
yuzuki999 2022-06-05 13:19:39 +08:00
parent 3eadd58da4
commit 5434e86d93
5 changed files with 81 additions and 51 deletions

View File

@ -50,6 +50,7 @@ type Client struct {
RemoteRuleCache *Rule
access sync.Mutex
NodeInfoRspMd5 [16]byte
NodeRuleRspMd5 [16]byte
UserListCheckNum int
}

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}

View File

@ -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"}}