From 9c94742d0cfa51de8e3b35c1c16fb077a1744cd1 Mon Sep 17 00:00:00 2001 From: sagitchu Date: Thu, 23 Apr 2026 15:25:57 +0800 Subject: [PATCH] feat: add CLimiters support for websocket reporter --- go-gost/x/socket/limiter.go | 68 ++++++++++++++++++++++++ go-gost/x/socket/websocket_reporter.go | 73 ++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) diff --git a/go-gost/x/socket/limiter.go b/go-gost/x/socket/limiter.go index 61ed9e5..e623f4e 100644 --- a/go-gost/x/socket/limiter.go +++ b/go-gost/x/socket/limiter.go @@ -102,3 +102,71 @@ type updateLimiterRequest struct { type deleteLimiterRequest struct { Limiter string `json:"limiter"` } + +func createConnLimiter(req createLimiterRequest) error { + name := strings.TrimSpace(req.Data.Name) + if name == "" { + return errors.New("limiter name is required") + } + req.Data.Name = name + + if registry.ConnLimiterRegistry().IsRegistered(name) { + return errors.New("conn limiter " + name + " already exists") + } + + v := parser.ParseConnLimiter(&req.Data) + + if err := registry.ConnLimiterRegistry().Register(name, v); err != nil { + return errors.New("conn limiter " + name + " already exists") + } + + if c := config.Global(); c != nil { + c.CLimiters = append(c.CLimiters, &req.Data) + } + return nil +} + +func updateConnLimiter(req updateLimiterRequest) error { + name := strings.TrimSpace(req.Limiter) + req.Data.Name = name + if registry.ConnLimiterRegistry().IsRegistered(name) { + registry.ConnLimiterRegistry().Unregister(name) + } + + v := parser.ParseConnLimiter(&req.Data) + + if err := registry.ConnLimiterRegistry().Register(name, v); err != nil { + return errors.New("conn limiter " + name + " already exists") + } + + if c := config.Global(); c != nil { + for i := range c.CLimiters { + if c.CLimiters[i].Name == name { + c.CLimiters[i] = &req.Data + return nil + } + } + c.CLimiters = append(c.CLimiters, &req.Data) + } + return nil +} + +func deleteConnLimiter(req deleteLimiterRequest) error { + name := strings.TrimSpace(req.Limiter) + + if registry.ConnLimiterRegistry().IsRegistered(name) { + registry.ConnLimiterRegistry().Unregister(name) + } + + if c := config.Global(); c != nil { + limiteres := c.CLimiters + c.CLimiters = nil + for _, s := range limiteres { + if s.Name == name { + continue + } + c.CLimiters = append(c.CLimiters, s) + } + } + return nil +} diff --git a/go-gost/x/socket/websocket_reporter.go b/go-gost/x/socket/websocket_reporter.go index 72100b8..c32a963 100644 --- a/go-gost/x/socket/websocket_reporter.go +++ b/go-gost/x/socket/websocket_reporter.go @@ -836,6 +836,18 @@ func (w *WebSocketReporter) routeCommand(cmd CommandMessage) { err = w.handleDeleteLimiter(cmd.Data) response.Type = "DeleteLimitersResponse" needSaveConfig = true + case "AddCLimiters": + err = w.handleAddCLimiter(cmd.Data) + response.Type = "AddCLimitersResponse" + needSaveConfig = true + case "UpdateCLimiters": + err = w.handleUpdateCLimiter(cmd.Data) + response.Type = "UpdateCLimitersResponse" + needSaveConfig = true + case "DeleteCLimiters": + err = w.handleDeleteCLimiter(cmd.Data) + response.Type = "DeleteCLimitersResponse" + needSaveConfig = true // TCP Ping 诊断命令(只读,不需要保存配置) case "TcpPing": @@ -1130,6 +1142,67 @@ func (w *WebSocketReporter) handleDeleteLimiter(data interface{}) error { return deleteLimiter(deleteReq) } +func (w *WebSocketReporter) handleAddCLimiter(data interface{}) error { + jsonData, err := json.Marshal(data) + if err != nil { + return fmt.Errorf("序列化数据失败: %v", err) + } + + var limiterConfig config.LimiterConfig + if err := json.Unmarshal(jsonData, &limiterConfig); err != nil { + return fmt.Errorf("解析限流器配置失败: %v", err) + } + + req := createLimiterRequest{Data: limiterConfig} + return createConnLimiter(req) +} + +func (w *WebSocketReporter) handleUpdateCLimiter(data interface{}) error { + jsonData, err := json.Marshal(data) + if err != nil { + return fmt.Errorf("序列化数据失败: %v", err) + } + + var updateReq struct { + Limiter string `json:"limiter"` + Data config.LimiterConfig `json:"data"` + } + + if err := json.Unmarshal(jsonData, &updateReq); err != nil { + var limiterConfig config.LimiterConfig + if err := json.Unmarshal(jsonData, &limiterConfig); err != nil { + return fmt.Errorf("解析更新请求失败: %v", err) + } + updateReq.Limiter = limiterConfig.Name + updateReq.Data = limiterConfig + } + + req := updateLimiterRequest{ + Limiter: updateReq.Limiter, + Data: updateReq.Data, + } + return updateConnLimiter(req) +} + +func (w *WebSocketReporter) handleDeleteCLimiter(data interface{}) error { + jsonData, err := json.Marshal(data) + if err != nil { + return fmt.Errorf("序列化数据失败: %v", err) + } + + var deleteReq deleteLimiterRequest + + if err := json.Unmarshal(jsonData, &deleteReq); err != nil { + var limiterName string + if err := json.Unmarshal(jsonData, &limiterName); err != nil { + return fmt.Errorf("解析删除请求失败: %v", err) + } + deleteReq.Limiter = limiterName + } + + return deleteConnLimiter(deleteReq) +} + // handleSetProtocol 处理设置屏蔽协议的命令 func (w *WebSocketReporter) handleSetProtocol(data interface{}) error { jsonData, err := json.Marshal(data)