From c66027103910ab413a51dede50f64f767ef582ae Mon Sep 17 00:00:00 2001 From: Aleksey Savchuk Date: Fri, 28 Feb 2025 15:14:15 +0300 Subject: [PATCH] [#1658] node: Validate RPC limiter configuration Validate that configured limits match the methods registered earlier. Signed-off-by: Aleksey Savchuk --- cmd/frostfs-node/grpc.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/cmd/frostfs-node/grpc.go b/cmd/frostfs-node/grpc.go index 9ea3dd8a2b..6b6d447501 100644 --- a/cmd/frostfs-node/grpc.go +++ b/cmd/frostfs-node/grpc.go @@ -240,6 +240,10 @@ func initRPCLimiter(c *cfg) error { limits = append(limits, limiting.KeyLimit{Keys: l.Methods, Limit: l.MaxOps}) } + if err := validateRPCLimits(c, limits); err != nil { + return fmt.Errorf("validate RPC limits: %w", err) + } + limiter, err := limiting.NewSemaphoreLimiter(limits) if err != nil { return fmt.Errorf("create RPC limiter: %w", err) @@ -248,3 +252,35 @@ func initRPCLimiter(c *cfg) error { c.cfgGRPC.limiter.Store(limiter) return nil } + +func validateRPCLimits(c *cfg, limits []limiting.KeyLimit) error { + availableMethods := getAvailableMethods(c.cfgGRPC.servers) + for _, limit := range limits { + for _, method := range limit.Keys { + if _, ok := availableMethods[method]; !ok { + return fmt.Errorf("set limit on an unknown method %q", method) + } + } + } + return nil +} + +func getAvailableMethods(servers []grpcServer) map[string]struct{} { + res := make(map[string]struct{}) + for _, server := range servers { + for _, method := range getMethodsForServer(server.Server) { + res[method] = struct{}{} + } + } + return res +} + +func getMethodsForServer(server *grpc.Server) []string { + var res []string + for service, info := range server.GetServiceInfo() { + for _, method := range info.Methods { + res = append(res, fmt.Sprintf("/%s/%s", service, method.Name)) + } + } + return res +}