diff --git a/internal/nodes/client_conn.go b/internal/nodes/client_conn.go index 3818980..fd16752 100644 --- a/internal/nodes/client_conn.go +++ b/internal/nodes/client_conn.go @@ -12,6 +12,7 @@ import ( "github.com/TeaOSLab/EdgeNode/internal/stats" "github.com/TeaOSLab/EdgeNode/internal/ttlcache" "github.com/TeaOSLab/EdgeNode/internal/utils" + connutils "github.com/TeaOSLab/EdgeNode/internal/utils/conns" "github.com/TeaOSLab/EdgeNode/internal/utils/fasttime" "github.com/TeaOSLab/EdgeNode/internal/waf" "github.com/iwind/TeaGo/Tea" @@ -34,6 +35,7 @@ type ClientConn struct { hasRead bool isLO bool // 是否为环路 + isNoStat bool // 是否不统计带宽 isInAllowList bool hasResetSYNFlood bool @@ -53,15 +55,15 @@ type ClientConn struct { func NewClientConn(rawConn net.Conn, isHTTP bool, isTLS bool, isInAllowList bool) net.Conn { // 是否为环路 var remoteAddr = rawConn.RemoteAddr().String() - var isLO = strings.HasPrefix(remoteAddr, "127.0.0.1:") || strings.HasPrefix(remoteAddr, "[::1]:") var conn = &ClientConn{ BaseClientConn: BaseClientConn{rawConn: rawConn}, isTLS: isTLS, isHTTP: isHTTP, - isLO: isLO, + isLO: strings.HasPrefix(remoteAddr, "127.0.0.1:") || strings.HasPrefix(remoteAddr, "[::1]:"), + isNoStat: connutils.IsNoStatConn(rawConn.RemoteAddr().String()), isInAllowList: isInAllowList, - createdAt: time.Now().Unix(), + createdAt: fasttime.Now().Unix(), } var globalServerConfig = sharedNodeConfig.GlobalServerConfig @@ -85,7 +87,7 @@ func NewClientConn(rawConn net.Conn, isHTTP bool, isTLS bool, isInAllowList bool func (this *ClientConn) Read(b []byte) (n int, err error) { if this.isDebugging { - this.lastReadAt = time.Now().Unix() + this.lastReadAt = fasttime.Now().Unix() defer func() { if err != nil { @@ -151,7 +153,7 @@ func (this *ClientConn) Write(b []byte) (n int, err error) { } if this.isDebugging { - this.lastWriteAt = time.Now().Unix() + this.lastWriteAt = fasttime.Now().Unix() defer func() { if err != nil { @@ -184,7 +186,7 @@ func (this *ClientConn) Write(b []byte) (n int, err error) { // 统计当前服务带宽 if this.serverId > 0 { // TODO 需要加入在serverId绑定之前的带宽 - if !this.isLO || Tea.IsTesting() { // 环路不统计带宽,避免缓存预热等行为产生带宽 + if !this.isNoStat || Tea.IsTesting() { // 环路不统计带宽,避免缓存预热等行为产生带宽 atomic.AddUint64(&teaconst.OutTrafficBytes, uint64(n)) var cost = time.Since(before).Seconds() @@ -309,7 +311,7 @@ func (this *ClientConn) increaseSYNFlood(synFloodConfig *firewallconfigs.SYNFloo _ = this.SetLinger(0) _ = this.Close() - waf.SharedIPBlackList.RecordIP(waf.IPTypeAll, firewallconfigs.FirewallScopeGlobal, 0, ip, time.Now().Unix()+int64(timeout), 0, true, 0, 0, "疑似SYN Flood攻击,当前1分钟"+types.String(result)+"次空连接") + waf.SharedIPBlackList.RecordIP(waf.IPTypeAll, firewallconfigs.FirewallScopeGlobal, 0, ip, fasttime.Now().Unix()+int64(timeout), 0, true, 0, 0, "疑似SYN Flood攻击,当前1分钟"+types.String(result)+"次空连接") } } } diff --git a/internal/nodes/http_cache_task_manager.go b/internal/nodes/http_cache_task_manager.go index 710a1c5..bdaf5de 100644 --- a/internal/nodes/http_cache_task_manager.go +++ b/internal/nodes/http_cache_task_manager.go @@ -14,6 +14,7 @@ import ( "github.com/TeaOSLab/EdgeNode/internal/goman" "github.com/TeaOSLab/EdgeNode/internal/remotelogs" "github.com/TeaOSLab/EdgeNode/internal/rpc" + connutils "github.com/TeaOSLab/EdgeNode/internal/utils/conns" "github.com/iwind/TeaGo/Tea" "io" "net" @@ -61,7 +62,12 @@ func NewHTTPCacheTaskManager() *HTTPCacheTaskManager { if err != nil { return nil, err } - return net.Dial(network, "127.0.0.1:"+port) + conn, err := net.Dial(network, "127.0.0.1:"+port) + if err != nil { + return nil, err + } + + return connutils.NewNoStat(conn), nil }, MaxIdleConns: 128, MaxIdleConnsPerHost: 32, diff --git a/internal/utils/conns/conn_no_stat.go b/internal/utils/conns/conn_no_stat.go new file mode 100644 index 0000000..f226d5f --- /dev/null +++ b/internal/utils/conns/conn_no_stat.go @@ -0,0 +1,72 @@ +// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn . + +package connutils + +import ( + "github.com/TeaOSLab/EdgeNode/internal/zero" + "net" + "sync" + "time" +) + +// 记录不需要带宽统计的连接 +// 比如本地的清理和预热 +var noStatAddrMap = map[string]zero.Zero{} // addr => Zero +var noStatLocker = &sync.RWMutex{} + +// IsNoStatConn 检查是否为不统计连接 +func IsNoStatConn(addr string) bool { + noStatLocker.RLock() + _, ok := noStatAddrMap[addr] + noStatLocker.RUnlock() + return ok +} + +type NoStatConn struct { + rawConn net.Conn +} + +func NewNoStat(rawConn net.Conn) net.Conn { + noStatLocker.Lock() + noStatAddrMap[rawConn.LocalAddr().String()] = zero.New() + noStatLocker.Unlock() + return &NoStatConn{rawConn: rawConn} +} + +func (this *NoStatConn) Read(b []byte) (n int, err error) { + return this.rawConn.Read(b) +} + +func (this *NoStatConn) Write(b []byte) (n int, err error) { + return this.rawConn.Write(b) +} + +func (this *NoStatConn) Close() error { + err := this.rawConn.Close() + + noStatLocker.Lock() + delete(noStatAddrMap, this.rawConn.LocalAddr().String()) + noStatLocker.Unlock() + + return err +} + +func (this *NoStatConn) LocalAddr() net.Addr { + return this.rawConn.LocalAddr() +} + +func (this *NoStatConn) RemoteAddr() net.Addr { + return this.rawConn.RemoteAddr() +} + +func (this *NoStatConn) SetDeadline(t time.Time) error { + return this.rawConn.SetDeadline(t) +} + +func (this *NoStatConn) SetReadDeadline(t time.Time) error { + return this.rawConn.SetReadDeadline(t) +} + +func (this *NoStatConn) SetWriteDeadline(t time.Time) error { + return this.rawConn.SetWriteDeadline(t) +}