From a52faa96a88050bfbf39b807f4f9172ee8dba21c Mon Sep 17 00:00:00 2001 From: qaq <1937228092@qq.com> Date: Wed, 18 Jun 2025 12:33:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dv6=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=9A=A7=E9=81=93=E7=B1=BB=E5=9E=8B=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 18 +++++++++ go-gost/main.go | 7 ++++ go-gost/x/handler/forward/local/handler.go | 40 ++++++++++++++----- .../x/handler/forward/local/traffic_bridge.go | 28 ++++++++++++- 4 files changed, 81 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 8627361..f14cbca 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,24 @@ curl -fsSL https://gitee.com/bqlpfy/forward-panel/raw/master/panel_install.sh -o https://gitee.com/bqlpfy/forward-panel/raw/master/install.sh ``` +### 卸载 + +```bash +面板端 + cd到compose所在位置执行下面的命令 + 改操作会删除所有数据 包括数据库文件 + docker compose down --rmi all --volumes --remove-orphans + 或 + docker-compose down --rmi all --volumes --remove-orphans +节点端 + systemctl stop gost + systemctl disable gost + rm -f /etc/systemd/system/gost.service + rm -rf /etc/gost + systemctl daemon-reload + +``` + #### 默认管理员账号 diff --git a/go-gost/main.go b/go-gost/main.go index bcd9c5a..9f523ad 100644 --- a/go-gost/main.go +++ b/go-gost/main.go @@ -11,6 +11,7 @@ import ( "runtime" "strings" "sync" + "time" "github.com/go-gost/gost/traffic" @@ -129,9 +130,15 @@ func main() { // 设置流量记录器给 handler 使用 traffic.SetupTrafficRecorder(trafficMgr) + // 设置实时流量记录器 + traffic.SetupRealtimeTrafficRecorder(trafficMgr) + fmt.Println("✅ 流量管理器已初始化(使用内存存储)") logger.Default().Info("Traffic manager initialized (using memory storage)") + // 启动实时流量统计(每5秒收集一次) + traffic.StartRealtimeTrafficStatistics(5 * time.Second) + traffic.SetHTTPReportURL(config.Addr, config.Secret) traffic.StartTrafficReporter(trafficMgr) wsReporter := traffic.StartWebSocketReporterWithConfig(config.Addr, config.Secret) diff --git a/go-gost/x/handler/forward/local/handler.go b/go-gost/x/handler/forward/local/handler.go index b4ea350..32f2c3d 100644 --- a/go-gost/x/handler/forward/local/handler.go +++ b/go-gost/x/handler/forward/local/handler.go @@ -4,6 +4,8 @@ import ( "bufio" "bytes" "context" + "crypto/rand" + "encoding/hex" "errors" "net" "time" @@ -12,7 +14,6 @@ import ( "github.com/go-gost/core/handler" "github.com/go-gost/core/hop" md "github.com/go-gost/core/metadata" - "github.com/go-gost/core/observer/stats" "github.com/go-gost/core/recorder" ctxvalue "github.com/go-gost/x/ctx" xnet "github.com/go-gost/x/internal/net" @@ -57,6 +58,13 @@ func NewHandler(opts ...handler.Option) handler.Handler { } } +// generateConnectionID 生成连接唯一标识 +func generateConnectionID() string { + bytes := make([]byte, 8) + rand.Read(bytes) + return hex.EncodeToString(bytes) +} + func (h *forwardHandler) Init(md md.Metadata) (err error) { if err = h.parseMetadata(md); err != nil { return @@ -88,6 +96,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand defer conn.Close() start := time.Now() + connID := generateConnectionID() ro := &xrecorder.HandlerRecorderObject{ Service: h.options.Service, @@ -114,6 +123,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand "local": conn.LocalAddr().String(), "sid": ro.SID, "client": ro.ClientIP, + "connID": connID, }) network := "tcp" @@ -126,21 +136,19 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand ccStats := xstats.Stats{} conn = stats_wrapper.WrapConn(conn, &connStats) + // 获取实时流量管理器并注册连接 + rtm := GetGlobalRealtimeTrafficManager() + if rtm != nil { + rtm.RegisterConnection(connID+":conn", h.options.Service+":conn", &connStats) + defer rtm.UnregisterConnection(connID + ":conn") + } + defer func() { if err != nil { ro.Err = err.Error() } ro.Duration = time.Since(start) - if h.trafficRecorder != nil { - connOutputBytes := connStats.Get(stats.KindOutputBytes) - connInputBytes := connStats.Get(stats.KindInputBytes) - ccOutputBytes := ccStats.Get(stats.KindOutputBytes) - ccInputBytes := ccStats.Get(stats.KindInputBytes) - - h.trafficRecorder.RecordTraffic(ctx, ro.Service+":conn", int64(connOutputBytes), int64(connInputBytes)) - h.trafficRecorder.RecordTraffic(ctx, ro.Service+":cc", int64(ccOutputBytes), int64(ccInputBytes)) - } }() if !h.checkRateLimit(conn.RemoteAddr()) { @@ -168,6 +176,12 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand cc = stats_wrapper.WrapConn(cc, &ccStats) + // 为目标连接也注册到实时流量统计 + if rtm != nil && err == nil { + rtm.RegisterConnection(connID+":cc", h.options.Service+":cc", &ccStats) + // 注意:这里不能defer UnregisterConnection,因为dial函数可能被多次调用 + } + return cc, err } sniffer := &forwarder.Sniffer{ @@ -244,6 +258,12 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand cc = stats_wrapper.WrapConn(cc, &ccStats) + // 为目标连接注册到实时流量统计 + if rtm != nil { + rtm.RegisterConnection(connID+":cc", h.options.Service+":cc", &ccStats) + defer rtm.UnregisterConnection(connID + ":cc") + } + defer cc.Close() xnet.Transport(conn, cc) diff --git a/go-gost/x/handler/forward/local/traffic_bridge.go b/go-gost/x/handler/forward/local/traffic_bridge.go index f307de6..f8c0101 100644 --- a/go-gost/x/handler/forward/local/traffic_bridge.go +++ b/go-gost/x/handler/forward/local/traffic_bridge.go @@ -2,11 +2,21 @@ package local import ( "sync" + + "github.com/go-gost/core/observer/stats" ) +// RealtimeTrafficManager 实时流量管理器接口(简化版) +type RealtimeTrafficManager interface { + RegisterConnection(id, service string, stats stats.Stats) + UnregisterConnection(id string) + GetActiveConnectionsCount() int +} + var ( - globalTrafficRecorder TrafficRecorder - trafficMutex sync.RWMutex + globalTrafficRecorder TrafficRecorder + globalRealtimeTrafficManager RealtimeTrafficManager + trafficMutex sync.RWMutex ) // SetGlobalTrafficRecorder 设置全局流量记录器 @@ -22,3 +32,17 @@ func GetGlobalTrafficRecorder() TrafficRecorder { defer trafficMutex.RUnlock() return globalTrafficRecorder } + +// SetGlobalRealtimeTrafficManager 设置全局实时流量管理器 +func SetGlobalRealtimeTrafficManager(manager RealtimeTrafficManager) { + trafficMutex.Lock() + defer trafficMutex.Unlock() + globalRealtimeTrafficManager = manager +} + +// GetGlobalRealtimeTrafficManager 获取全局实时流量管理器 +func GetGlobalRealtimeTrafficManager() RealtimeTrafficManager { + trafficMutex.RLock() + defer trafficMutex.RUnlock() + return globalRealtimeTrafficManager +}