From 26d3caf14f5d1299088e199a461e4005266fd2d8 Mon Sep 17 00:00:00 2001 From: tat5522 <81008809+tat5522@users.noreply.github.com> Date: Sat, 20 Mar 2021 20:46:34 +0800 Subject: [PATCH 1/9] Add the routing management gRPC API --- app/router/command/command.go | 103 ++- app/router/command/command.pb.go | 973 +++++++++++++++++++++++--- app/router/command/command.proto | 45 +- app/router/command/command_grpc.pb.go | 245 ++++++- app/router/command/command_test.go | 584 +++++++++++++++- app/router/command/config.go | 1 + app/router/config.go | 42 +- app/router/config.pb.go | 189 ++--- app/router/config.proto | 3 +- app/router/router.go | 127 +++- app/router/router_test.go | 149 +++- features/routing/context.go | 3 + features/routing/router.go | 52 ++ features/routing/session/context.go | 4 + infra/conf/api.go | 3 + infra/conf/router.go | 17 +- infra/conf/router_test.go | 32 +- infra/conf/xray_test.go | 4 +- testing/scenarios/command_test.go | 12 +- testing/scenarios/dns_test.go | 4 +- testing/scenarios/feature_test.go | 12 +- testing/scenarios/reverse_test.go | 32 +- testing/scenarios/socks_test.go | 4 +- 23 files changed, 2347 insertions(+), 293 deletions(-) diff --git a/app/router/command/command.go b/app/router/command/command.go index fff78cb717ab..1b7fc9b0836a 100644 --- a/app/router/command/command.go +++ b/app/router/command/command.go @@ -4,6 +4,7 @@ package command import ( "context" + "github.com/xtls/xray-core/features/outbound" "time" "google.golang.org/grpc" @@ -16,6 +17,8 @@ import ( // routingServer is an implementation of RoutingService. type routingServer struct { + s *core.Instance + ohm outbound.Manager router routing.Router routingStats stats.Channel } @@ -43,6 +46,82 @@ func (s *routingServer) TestRoute(ctx context.Context, request *TestRouteRequest return AsProtobufMessage(request.FieldSelectors)(route), nil } +func (s *routingServer) AddRoutingRule(ctx context.Context, request *AddRoutingRuleRequest) (*AddRoutingRuleResponse, error) { + if request.RoutingRule == nil { + return nil, newError("Invalid RoutingRule request.") + } + err := s.router.AddRoutingRule(ctx, request.RoutingRule) + if err != nil { + return nil, err + } + return &AddRoutingRuleResponse{}, nil +} + +func (s *routingServer) AlterRoutingRule(ctx context.Context, request *AlterRoutingRuleRequest) (*AlterRoutingRuleResponse, error) { + if request.RoutingRule == nil { + return nil, newError("Invalid RoutingRule request.") + } + + if len(request.Tag) == 0 { + return nil, newError("Invalid Tag.") + } + + err := s.router.AlterRoutingRule(ctx, request.Tag, request.RoutingRule) + if err != nil { + return nil, err + } + return &AlterRoutingRuleResponse{}, nil +} + +func (s *routingServer) RemoveRoutingRule(ctx context.Context, request *RemoveRoutingRuleRequest) (*RemoveRoutingRuleResponse, error) { + if len(request.Tag) == 0 { + return nil, newError("Invalid Tag.") + } + err := s.router.RemoveRoutingRule(ctx, request.Tag) + if err != nil { + return nil, err + } + return &RemoveRoutingRuleResponse{}, nil +} + +func (s *routingServer) AddBalancingRule(ctx context.Context, request *AddBalancingRuleRequest) (*AddBalancingRuleResponse, error) { + if request.Balancing == nil { + return nil, newError("Invalid Balancing request.") + } + + err := s.router.AddBalancingRule(ctx, request.Balancing, s.ohm) + if err != nil { + return nil, err + } + return &AddBalancingRuleResponse{}, nil +} + +func (s *routingServer) AlterBalancingRule(ctx context.Context, request *AlterBalancingRuleRequest) (*AlterBalancingRuleResponse, error) { + if request.Balancing == nil { + return nil, newError("Invalid Balancing request.") + } + + if len(request.Tag) == 0 { + return nil, newError("Invalid Tag.") + } + err := s.router.AlterBalancingRule(ctx, request.Tag, request.Balancing, s.ohm) + if err != nil { + return nil, err + } + return &AlterBalancingRuleResponse{}, nil +} + +func (s *routingServer) RemoveBalancingRule(ctx context.Context, request *RemoveBalancingRuleRequest) (*RemoveBalancingRuleResponse, error) { + if len(request.Tag) == 0 { + return nil, newError("Invalid Tag.") + } + err := s.router.RemoveBalancingRule(ctx, request.Tag) + if err != nil { + return nil, err + } + return &RemoveBalancingRuleResponse{}, nil +} + func (s *routingServer) SubscribeRoutingStats(request *SubscribeRoutingStatsRequest, stream RoutingService_SubscribeRoutingStatsServer) error { if s.routingStats == nil { return newError("Routing statistics not enabled.") @@ -80,15 +159,23 @@ type service struct { } func (s *service) Register(server *grpc.Server) { - common.Must(s.v.RequireFeatures(func(router routing.Router, stats stats.Manager) { - rs := NewRoutingServer(router, nil) - RegisterRoutingServiceServer(server, rs) - - // For compatibility purposes - vCoreDesc := RoutingService_ServiceDesc - vCoreDesc.ServiceName = "v2ray.core.app.router.command.RoutingService" - server.RegisterService(&vCoreDesc, rs) + rs := &routingServer{ + s: s.v, + ohm: nil, + router: nil, + routingStats: nil, + } + + common.Must(s.v.RequireFeatures(func(router routing.Router, stats stats.Manager, om outbound.Manager) { + rs.ohm = om + rs.router = router })) + + RegisterRoutingServiceServer(server, rs) + // For compatibility purposes + vCoreDesc := RoutingService_ServiceDesc + vCoreDesc.ServiceName = "v2ray.core.app.router.command.RoutingService" + server.RegisterService(&vCoreDesc, rs) } func init() { diff --git a/app/router/command/command.pb.go b/app/router/command/command.pb.go index 2017669df168..ff8eaf975741 100644 --- a/app/router/command/command.pb.go +++ b/app/router/command/command.pb.go @@ -1,13 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.14.0 +// protoc-gen-go v1.26.0 +// protoc v3.15.6 // source: app/router/command/command.proto package command import ( - proto "github.com/golang/protobuf/proto" + router "github.com/xtls/xray-core/app/router" net "github.com/xtls/xray-core/common/net" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -22,10 +22,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // RoutingContext is the context with information relative to routing process. // It conforms to the structure of xray.features.routing.Context and // xray.features.routing.Route. @@ -46,6 +42,7 @@ type RoutingContext struct { Attributes map[string]string `protobuf:"bytes,10,rep,name=Attributes,proto3" json:"Attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` OutboundGroupTags []string `protobuf:"bytes,11,rep,name=OutboundGroupTags,proto3" json:"OutboundGroupTags,omitempty"` OutboundTag string `protobuf:"bytes,12,opt,name=OutboundTag,proto3" json:"OutboundTag,omitempty"` + Tag string `protobuf:"bytes,13,opt,name=Tag,proto3" json:"Tag,omitempty"` } func (x *RoutingContext) Reset() { @@ -164,6 +161,13 @@ func (x *RoutingContext) GetOutboundTag() string { return "" } +func (x *RoutingContext) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + // SubscribeRoutingStatsRequest subscribes to routing statistics channel if // opened by xray-core. // * FieldSelectors selects a subset of fields in routing statistics to return. @@ -298,6 +302,532 @@ func (x *TestRouteRequest) GetPublishResult() bool { return false } +type AddRoutingRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RoutingRule *router.RoutingRule `protobuf:"bytes,1,opt,name=routingRule,proto3" json:"routingRule,omitempty"` +} + +func (x *AddRoutingRuleRequest) Reset() { + *x = AddRoutingRuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddRoutingRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddRoutingRuleRequest) ProtoMessage() {} + +func (x *AddRoutingRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddRoutingRuleRequest.ProtoReflect.Descriptor instead. +func (*AddRoutingRuleRequest) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{3} +} + +func (x *AddRoutingRuleRequest) GetRoutingRule() *router.RoutingRule { + if x != nil { + return x.RoutingRule + } + return nil +} + +type AddRoutingRuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *AddRoutingRuleResponse) Reset() { + *x = AddRoutingRuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddRoutingRuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddRoutingRuleResponse) ProtoMessage() {} + +func (x *AddRoutingRuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddRoutingRuleResponse.ProtoReflect.Descriptor instead. +func (*AddRoutingRuleResponse) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{4} +} + +type AlterRoutingRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + RoutingRule *router.RoutingRule `protobuf:"bytes,2,opt,name=routingRule,proto3" json:"routingRule,omitempty"` +} + +func (x *AlterRoutingRuleRequest) Reset() { + *x = AlterRoutingRuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AlterRoutingRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlterRoutingRuleRequest) ProtoMessage() {} + +func (x *AlterRoutingRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlterRoutingRuleRequest.ProtoReflect.Descriptor instead. +func (*AlterRoutingRuleRequest) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{5} +} + +func (x *AlterRoutingRuleRequest) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + +func (x *AlterRoutingRuleRequest) GetRoutingRule() *router.RoutingRule { + if x != nil { + return x.RoutingRule + } + return nil +} + +type AlterRoutingRuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *AlterRoutingRuleResponse) Reset() { + *x = AlterRoutingRuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AlterRoutingRuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlterRoutingRuleResponse) ProtoMessage() {} + +func (x *AlterRoutingRuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlterRoutingRuleResponse.ProtoReflect.Descriptor instead. +func (*AlterRoutingRuleResponse) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{6} +} + +type RemoveRoutingRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` +} + +func (x *RemoveRoutingRuleRequest) Reset() { + *x = RemoveRoutingRuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveRoutingRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveRoutingRuleRequest) ProtoMessage() {} + +func (x *RemoveRoutingRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveRoutingRuleRequest.ProtoReflect.Descriptor instead. +func (*RemoveRoutingRuleRequest) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{7} +} + +func (x *RemoveRoutingRuleRequest) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + +type RemoveRoutingRuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *RemoveRoutingRuleResponse) Reset() { + *x = RemoveRoutingRuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveRoutingRuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveRoutingRuleResponse) ProtoMessage() {} + +func (x *RemoveRoutingRuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveRoutingRuleResponse.ProtoReflect.Descriptor instead. +func (*RemoveRoutingRuleResponse) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{8} +} + +type AddBalancingRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Balancing *router.BalancingRule `protobuf:"bytes,1,opt,name=balancing,proto3" json:"balancing,omitempty"` +} + +func (x *AddBalancingRuleRequest) Reset() { + *x = AddBalancingRuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddBalancingRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddBalancingRuleRequest) ProtoMessage() {} + +func (x *AddBalancingRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddBalancingRuleRequest.ProtoReflect.Descriptor instead. +func (*AddBalancingRuleRequest) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{9} +} + +func (x *AddBalancingRuleRequest) GetBalancing() *router.BalancingRule { + if x != nil { + return x.Balancing + } + return nil +} + +type AddBalancingRuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *AddBalancingRuleResponse) Reset() { + *x = AddBalancingRuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddBalancingRuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddBalancingRuleResponse) ProtoMessage() {} + +func (x *AddBalancingRuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddBalancingRuleResponse.ProtoReflect.Descriptor instead. +func (*AddBalancingRuleResponse) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{10} +} + +type AlterBalancingRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + Balancing *router.BalancingRule `protobuf:"bytes,2,opt,name=balancing,proto3" json:"balancing,omitempty"` +} + +func (x *AlterBalancingRuleRequest) Reset() { + *x = AlterBalancingRuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AlterBalancingRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlterBalancingRuleRequest) ProtoMessage() {} + +func (x *AlterBalancingRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlterBalancingRuleRequest.ProtoReflect.Descriptor instead. +func (*AlterBalancingRuleRequest) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{11} +} + +func (x *AlterBalancingRuleRequest) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + +func (x *AlterBalancingRuleRequest) GetBalancing() *router.BalancingRule { + if x != nil { + return x.Balancing + } + return nil +} + +type AlterBalancingRuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *AlterBalancingRuleResponse) Reset() { + *x = AlterBalancingRuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AlterBalancingRuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlterBalancingRuleResponse) ProtoMessage() {} + +func (x *AlterBalancingRuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlterBalancingRuleResponse.ProtoReflect.Descriptor instead. +func (*AlterBalancingRuleResponse) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{12} +} + +type RemoveBalancingRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` +} + +func (x *RemoveBalancingRuleRequest) Reset() { + *x = RemoveBalancingRuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveBalancingRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveBalancingRuleRequest) ProtoMessage() {} + +func (x *RemoveBalancingRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveBalancingRuleRequest.ProtoReflect.Descriptor instead. +func (*RemoveBalancingRuleRequest) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{13} +} + +func (x *RemoveBalancingRuleRequest) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + +type RemoveBalancingRuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *RemoveBalancingRuleResponse) Reset() { + *x = RemoveBalancingRuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveBalancingRuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveBalancingRuleResponse) ProtoMessage() {} + +func (x *RemoveBalancingRuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveBalancingRuleResponse.ProtoReflect.Descriptor instead. +func (*RemoveBalancingRuleResponse) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{14} +} + type Config struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -307,7 +837,7 @@ type Config struct { func (x *Config) Reset() { *x = Config{} if protoimpl.UnsafeEnabled { - mi := &file_app_router_command_command_proto_msgTypes[3] + mi := &file_app_router_command_command_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -320,7 +850,7 @@ func (x *Config) String() string { func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { - mi := &file_app_router_command_command_proto_msgTypes[3] + mi := &file_app_router_command_command_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -333,7 +863,7 @@ func (x *Config) ProtoReflect() protoreflect.Message { // Deprecated: Use Config.ProtoReflect.Descriptor instead. func (*Config) Descriptor() ([]byte, []int) { - return file_app_router_command_command_proto_rawDescGZIP(), []int{3} + return file_app_router_command_command_proto_rawDescGZIP(), []int{15} } var File_app_router_command_command_proto protoreflect.FileDescriptor @@ -344,72 +874,163 @@ var file_app_router_command_command_proto_rawDesc = []byte{ 0x74, 0x6f, 0x12, 0x17, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x1a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9c, 0x04, 0x0a, 0x0e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x6e, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x49, 0x6e, - 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x32, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x52, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x1c, 0x0a, 0x09, - 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x50, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, - 0x09, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x50, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x49, 0x50, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x54, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x49, 0x50, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x57, 0x0a, 0x0a, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x37, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x11, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, - 0x61, 0x67, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, - 0x61, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x54, 0x61, 0x67, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0x46, 0x0a, 0x1c, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0xb1, 0x01, 0x0a, - 0x10, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x4f, 0x0a, 0x0e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xae, + 0x04, 0x0a, 0x0e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, + 0x67, 0x12, 0x32, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x07, 0x4e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, + 0x50, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x49, 0x50, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x49, 0x50, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x49, 0x50, + 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, + 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x72, + 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x57, 0x0a, 0x0a, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x52, 0x0e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x22, 0x08, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x32, 0xf0, 0x01, 0x0a, 0x0e, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7b, 0x0a, - 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x35, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x78, 0x74, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0a, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x2c, + 0x0a, 0x11, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, + 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x4f, 0x75, 0x74, 0x62, 0x6f, + 0x75, 0x6e, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x73, 0x12, 0x20, 0x0a, 0x0b, + 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x10, + 0x0a, 0x03, 0x54, 0x61, 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x54, 0x61, 0x67, + 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x46, 0x0a, 0x1c, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x26, 0x0a, 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0xb1, 0x01, 0x0a, 0x10, 0x54, 0x65, 0x73, 0x74, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4f, 0x0a, 0x0e, + 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0e, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x26, 0x0a, + 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x57, 0x0a, 0x15, 0x41, + 0x64, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6b, + 0x0a, 0x17, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x3e, 0x0a, 0x0b, 0x72, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0b, + 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x41, + 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x18, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0x1b, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x57, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, + 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x52, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x22, 0x1a, 0x0a, 0x18, 0x41, + 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6b, 0x0a, 0x19, 0x41, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x3c, 0x0a, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x69, 0x6e, 0x67, 0x22, 0x1c, 0x0a, 0x1a, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x2e, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, + 0x61, 0x67, 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x08, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x32, 0xdf, 0x07, 0x0a, 0x0e, + 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7b, + 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x35, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, + 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x61, 0x0a, 0x09, 0x54, + 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, + 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, 0x12, 0x73, + 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x12, 0x2e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x79, 0x0a, 0x10, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, + 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7c, + 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x12, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, + 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x79, 0x0a, 0x10, + 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x12, 0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x42, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, + 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x12, 0x41, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x61, 0x0a, 0x09, 0x54, 0x65, - 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, - 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, 0x42, 0x67, 0x0a, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x33, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, + 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x82, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x12, 0x33, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x67, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, @@ -431,28 +1052,58 @@ func file_app_router_command_command_proto_rawDescGZIP() []byte { return file_app_router_command_command_proto_rawDescData } -var file_app_router_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_app_router_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 17) var file_app_router_command_command_proto_goTypes = []interface{}{ (*RoutingContext)(nil), // 0: xray.app.router.command.RoutingContext (*SubscribeRoutingStatsRequest)(nil), // 1: xray.app.router.command.SubscribeRoutingStatsRequest (*TestRouteRequest)(nil), // 2: xray.app.router.command.TestRouteRequest - (*Config)(nil), // 3: xray.app.router.command.Config - nil, // 4: xray.app.router.command.RoutingContext.AttributesEntry - (net.Network)(0), // 5: xray.common.net.Network + (*AddRoutingRuleRequest)(nil), // 3: xray.app.router.command.AddRoutingRuleRequest + (*AddRoutingRuleResponse)(nil), // 4: xray.app.router.command.AddRoutingRuleResponse + (*AlterRoutingRuleRequest)(nil), // 5: xray.app.router.command.AlterRoutingRuleRequest + (*AlterRoutingRuleResponse)(nil), // 6: xray.app.router.command.AlterRoutingRuleResponse + (*RemoveRoutingRuleRequest)(nil), // 7: xray.app.router.command.RemoveRoutingRuleRequest + (*RemoveRoutingRuleResponse)(nil), // 8: xray.app.router.command.RemoveRoutingRuleResponse + (*AddBalancingRuleRequest)(nil), // 9: xray.app.router.command.AddBalancingRuleRequest + (*AddBalancingRuleResponse)(nil), // 10: xray.app.router.command.AddBalancingRuleResponse + (*AlterBalancingRuleRequest)(nil), // 11: xray.app.router.command.AlterBalancingRuleRequest + (*AlterBalancingRuleResponse)(nil), // 12: xray.app.router.command.AlterBalancingRuleResponse + (*RemoveBalancingRuleRequest)(nil), // 13: xray.app.router.command.RemoveBalancingRuleRequest + (*RemoveBalancingRuleResponse)(nil), // 14: xray.app.router.command.RemoveBalancingRuleResponse + (*Config)(nil), // 15: xray.app.router.command.Config + nil, // 16: xray.app.router.command.RoutingContext.AttributesEntry + (net.Network)(0), // 17: xray.common.net.Network + (*router.RoutingRule)(nil), // 18: xray.app.router.RoutingRule + (*router.BalancingRule)(nil), // 19: xray.app.router.BalancingRule } var file_app_router_command_command_proto_depIdxs = []int32{ - 5, // 0: xray.app.router.command.RoutingContext.Network:type_name -> xray.common.net.Network - 4, // 1: xray.app.router.command.RoutingContext.Attributes:type_name -> xray.app.router.command.RoutingContext.AttributesEntry - 0, // 2: xray.app.router.command.TestRouteRequest.RoutingContext:type_name -> xray.app.router.command.RoutingContext - 1, // 3: xray.app.router.command.RoutingService.SubscribeRoutingStats:input_type -> xray.app.router.command.SubscribeRoutingStatsRequest - 2, // 4: xray.app.router.command.RoutingService.TestRoute:input_type -> xray.app.router.command.TestRouteRequest - 0, // 5: xray.app.router.command.RoutingService.SubscribeRoutingStats:output_type -> xray.app.router.command.RoutingContext - 0, // 6: xray.app.router.command.RoutingService.TestRoute:output_type -> xray.app.router.command.RoutingContext - 5, // [5:7] is the sub-list for method output_type - 3, // [3:5] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 17, // 0: xray.app.router.command.RoutingContext.Network:type_name -> xray.common.net.Network + 16, // 1: xray.app.router.command.RoutingContext.Attributes:type_name -> xray.app.router.command.RoutingContext.AttributesEntry + 0, // 2: xray.app.router.command.TestRouteRequest.RoutingContext:type_name -> xray.app.router.command.RoutingContext + 18, // 3: xray.app.router.command.AddRoutingRuleRequest.routingRule:type_name -> xray.app.router.RoutingRule + 18, // 4: xray.app.router.command.AlterRoutingRuleRequest.routingRule:type_name -> xray.app.router.RoutingRule + 19, // 5: xray.app.router.command.AddBalancingRuleRequest.balancing:type_name -> xray.app.router.BalancingRule + 19, // 6: xray.app.router.command.AlterBalancingRuleRequest.balancing:type_name -> xray.app.router.BalancingRule + 1, // 7: xray.app.router.command.RoutingService.SubscribeRoutingStats:input_type -> xray.app.router.command.SubscribeRoutingStatsRequest + 2, // 8: xray.app.router.command.RoutingService.TestRoute:input_type -> xray.app.router.command.TestRouteRequest + 3, // 9: xray.app.router.command.RoutingService.AddRoutingRule:input_type -> xray.app.router.command.AddRoutingRuleRequest + 5, // 10: xray.app.router.command.RoutingService.AlterRoutingRule:input_type -> xray.app.router.command.AlterRoutingRuleRequest + 7, // 11: xray.app.router.command.RoutingService.RemoveRoutingRule:input_type -> xray.app.router.command.RemoveRoutingRuleRequest + 9, // 12: xray.app.router.command.RoutingService.AddBalancingRule:input_type -> xray.app.router.command.AddBalancingRuleRequest + 11, // 13: xray.app.router.command.RoutingService.AlterBalancingRule:input_type -> xray.app.router.command.AlterBalancingRuleRequest + 13, // 14: xray.app.router.command.RoutingService.RemoveBalancingRule:input_type -> xray.app.router.command.RemoveBalancingRuleRequest + 0, // 15: xray.app.router.command.RoutingService.SubscribeRoutingStats:output_type -> xray.app.router.command.RoutingContext + 0, // 16: xray.app.router.command.RoutingService.TestRoute:output_type -> xray.app.router.command.RoutingContext + 4, // 17: xray.app.router.command.RoutingService.AddRoutingRule:output_type -> xray.app.router.command.AddRoutingRuleResponse + 6, // 18: xray.app.router.command.RoutingService.AlterRoutingRule:output_type -> xray.app.router.command.AlterRoutingRuleResponse + 8, // 19: xray.app.router.command.RoutingService.RemoveRoutingRule:output_type -> xray.app.router.command.RemoveRoutingRuleResponse + 10, // 20: xray.app.router.command.RoutingService.AddBalancingRule:output_type -> xray.app.router.command.AddBalancingRuleResponse + 12, // 21: xray.app.router.command.RoutingService.AlterBalancingRule:output_type -> xray.app.router.command.AlterBalancingRuleResponse + 14, // 22: xray.app.router.command.RoutingService.RemoveBalancingRule:output_type -> xray.app.router.command.RemoveBalancingRuleResponse + 15, // [15:23] is the sub-list for method output_type + 7, // [7:15] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_app_router_command_command_proto_init() } @@ -498,6 +1149,150 @@ func file_app_router_command_command_proto_init() { } } file_app_router_command_command_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddRoutingRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddRoutingRuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AlterRoutingRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AlterRoutingRuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveRoutingRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveRoutingRuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddBalancingRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddBalancingRuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AlterBalancingRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AlterBalancingRuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveBalancingRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveBalancingRuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Config); i { case 0: return &v.state @@ -516,7 +1311,7 @@ func file_app_router_command_command_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_app_router_command_command_proto_rawDesc, NumEnums: 0, - NumMessages: 5, + NumMessages: 17, NumExtensions: 0, NumServices: 1, }, diff --git a/app/router/command/command.proto b/app/router/command/command.proto index 5f77704488e1..fcc165f6fb81 100644 --- a/app/router/command/command.proto +++ b/app/router/command/command.proto @@ -7,6 +7,7 @@ option java_package = "com.xray.app.router.command"; option java_multiple_files = true; import "common/net/network.proto"; +import "app/router/config.proto"; // RoutingContext is the context with information relative to routing process. // It conforms to the structure of xray.features.routing.Context and @@ -24,6 +25,7 @@ message RoutingContext { map Attributes = 10; repeated string OutboundGroupTags = 11; string OutboundTag = 12; + string Tag = 13; } // SubscribeRoutingStatsRequest subscribes to routing statistics channel if @@ -60,10 +62,49 @@ message TestRouteRequest { bool PublishResult = 3; } +message AddRoutingRuleRequest{ + xray.app.router.RoutingRule routingRule = 1; +} + +message AddRoutingRuleResponse {} + +message AlterRoutingRuleRequest{ + string tag = 1; + xray.app.router.RoutingRule routingRule = 2; +} +message AlterRoutingRuleResponse {} + +message RemoveRoutingRuleRequest{ + string tag = 1; +} +message RemoveRoutingRuleResponse {} + +message AddBalancingRuleRequest{ + xray.app.router.BalancingRule balancing = 1; +} + +message AddBalancingRuleResponse {} + +message AlterBalancingRuleRequest{ + string tag = 1; + xray.app.router.BalancingRule balancing = 2; +} +message AlterBalancingRuleResponse {} + +message RemoveBalancingRuleRequest{ + string tag = 1; +} +message RemoveBalancingRuleResponse {} + service RoutingService { - rpc SubscribeRoutingStats(SubscribeRoutingStatsRequest) - returns (stream RoutingContext) {} + rpc SubscribeRoutingStats(SubscribeRoutingStatsRequest) returns (stream RoutingContext) {} rpc TestRoute(TestRouteRequest) returns (RoutingContext) {} + rpc AddRoutingRule(AddRoutingRuleRequest) returns (AddRoutingRuleResponse){} + rpc AlterRoutingRule(AlterRoutingRuleRequest) returns (AlterRoutingRuleResponse){} + rpc RemoveRoutingRule(RemoveRoutingRuleRequest) returns (RemoveRoutingRuleResponse){} + rpc AddBalancingRule(AddBalancingRuleRequest) returns (AddBalancingRuleResponse){} + rpc AlterBalancingRule(AlterBalancingRuleRequest) returns (AlterBalancingRuleResponse){} + rpc RemoveBalancingRule(RemoveBalancingRuleRequest) returns (RemoveBalancingRuleResponse){} } message Config {} diff --git a/app/router/command/command_grpc.pb.go b/app/router/command/command_grpc.pb.go index 663442b8c55f..8e0432e48c2b 100644 --- a/app/router/command/command_grpc.pb.go +++ b/app/router/command/command_grpc.pb.go @@ -9,17 +9,26 @@ import ( status "google.golang.org/grpc/status" ) +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +const _ = grpc.SupportPackageIsVersion6 // RoutingServiceClient is the client API for RoutingService service. // -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type RoutingServiceClient interface { SubscribeRoutingStats(ctx context.Context, in *SubscribeRoutingStatsRequest, opts ...grpc.CallOption) (RoutingService_SubscribeRoutingStatsClient, error) TestRoute(ctx context.Context, in *TestRouteRequest, opts ...grpc.CallOption) (*RoutingContext, error) + AddRoutingRule(ctx context.Context, in *AddRoutingRuleRequest, opts ...grpc.CallOption) (*AddRoutingRuleResponse, error) + AlterRoutingRule(ctx context.Context, in *AlterRoutingRuleRequest, opts ...grpc.CallOption) (*AlterRoutingRuleResponse, error) + RemoveRoutingRule(ctx context.Context, in *RemoveRoutingRuleRequest, opts ...grpc.CallOption) (*RemoveRoutingRuleResponse, error) + AddBalancingRule(ctx context.Context, in *AddBalancingRuleRequest, opts ...grpc.CallOption) (*AddBalancingRuleResponse, error) + AlterBalancingRule(ctx context.Context, in *AlterBalancingRuleRequest, opts ...grpc.CallOption) (*AlterBalancingRuleResponse, error) + RemoveBalancingRule(ctx context.Context, in *RemoveBalancingRuleRequest, opts ...grpc.CallOption) (*RemoveBalancingRuleResponse, error) } type routingServiceClient struct { @@ -71,35 +80,102 @@ func (c *routingServiceClient) TestRoute(ctx context.Context, in *TestRouteReque return out, nil } +func (c *routingServiceClient) AddRoutingRule(ctx context.Context, in *AddRoutingRuleRequest, opts ...grpc.CallOption) (*AddRoutingRuleResponse, error) { + out := new(AddRoutingRuleResponse) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AddRoutingRule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *routingServiceClient) AlterRoutingRule(ctx context.Context, in *AlterRoutingRuleRequest, opts ...grpc.CallOption) (*AlterRoutingRuleResponse, error) { + out := new(AlterRoutingRuleResponse) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AlterRoutingRule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *routingServiceClient) RemoveRoutingRule(ctx context.Context, in *RemoveRoutingRuleRequest, opts ...grpc.CallOption) (*RemoveRoutingRuleResponse, error) { + out := new(RemoveRoutingRuleResponse) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/RemoveRoutingRule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *routingServiceClient) AddBalancingRule(ctx context.Context, in *AddBalancingRuleRequest, opts ...grpc.CallOption) (*AddBalancingRuleResponse, error) { + out := new(AddBalancingRuleResponse) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AddBalancingRule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *routingServiceClient) AlterBalancingRule(ctx context.Context, in *AlterBalancingRuleRequest, opts ...grpc.CallOption) (*AlterBalancingRuleResponse, error) { + out := new(AlterBalancingRuleResponse) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AlterBalancingRule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *routingServiceClient) RemoveBalancingRule(ctx context.Context, in *RemoveBalancingRuleRequest, opts ...grpc.CallOption) (*RemoveBalancingRuleResponse, error) { + out := new(RemoveBalancingRuleResponse) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/RemoveBalancingRule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // RoutingServiceServer is the server API for RoutingService service. -// All implementations must embed UnimplementedRoutingServiceServer -// for forward compatibility type RoutingServiceServer interface { SubscribeRoutingStats(*SubscribeRoutingStatsRequest, RoutingService_SubscribeRoutingStatsServer) error TestRoute(context.Context, *TestRouteRequest) (*RoutingContext, error) - mustEmbedUnimplementedRoutingServiceServer() + AddRoutingRule(context.Context, *AddRoutingRuleRequest) (*AddRoutingRuleResponse, error) + AlterRoutingRule(context.Context, *AlterRoutingRuleRequest) (*AlterRoutingRuleResponse, error) + RemoveRoutingRule(context.Context, *RemoveRoutingRuleRequest) (*RemoveRoutingRuleResponse, error) + AddBalancingRule(context.Context, *AddBalancingRuleRequest) (*AddBalancingRuleResponse, error) + AlterBalancingRule(context.Context, *AlterBalancingRuleRequest) (*AlterBalancingRuleResponse, error) + RemoveBalancingRule(context.Context, *RemoveBalancingRuleRequest) (*RemoveBalancingRuleResponse, error) } -// UnimplementedRoutingServiceServer must be embedded to have forward compatible implementations. +// UnimplementedRoutingServiceServer can be embedded to have forward compatible implementations. type UnimplementedRoutingServiceServer struct { } -func (UnimplementedRoutingServiceServer) SubscribeRoutingStats(*SubscribeRoutingStatsRequest, RoutingService_SubscribeRoutingStatsServer) error { +func (*UnimplementedRoutingServiceServer) SubscribeRoutingStats(*SubscribeRoutingStatsRequest, RoutingService_SubscribeRoutingStatsServer) error { return status.Errorf(codes.Unimplemented, "method SubscribeRoutingStats not implemented") } -func (UnimplementedRoutingServiceServer) TestRoute(context.Context, *TestRouteRequest) (*RoutingContext, error) { +func (*UnimplementedRoutingServiceServer) TestRoute(context.Context, *TestRouteRequest) (*RoutingContext, error) { return nil, status.Errorf(codes.Unimplemented, "method TestRoute not implemented") } -func (UnimplementedRoutingServiceServer) mustEmbedUnimplementedRoutingServiceServer() {} - -// UnsafeRoutingServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to RoutingServiceServer will -// result in compilation errors. -type UnsafeRoutingServiceServer interface { - mustEmbedUnimplementedRoutingServiceServer() +func (*UnimplementedRoutingServiceServer) AddRoutingRule(context.Context, *AddRoutingRuleRequest) (*AddRoutingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddRoutingRule not implemented") +} +func (*UnimplementedRoutingServiceServer) AlterRoutingRule(context.Context, *AlterRoutingRuleRequest) (*AlterRoutingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AlterRoutingRule not implemented") +} +func (*UnimplementedRoutingServiceServer) RemoveRoutingRule(context.Context, *RemoveRoutingRuleRequest) (*RemoveRoutingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveRoutingRule not implemented") +} +func (*UnimplementedRoutingServiceServer) AddBalancingRule(context.Context, *AddBalancingRuleRequest) (*AddBalancingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddBalancingRule not implemented") +} +func (*UnimplementedRoutingServiceServer) AlterBalancingRule(context.Context, *AlterBalancingRuleRequest) (*AlterBalancingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AlterBalancingRule not implemented") +} +func (*UnimplementedRoutingServiceServer) RemoveBalancingRule(context.Context, *RemoveBalancingRuleRequest) (*RemoveBalancingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveBalancingRule not implemented") } -func RegisterRoutingServiceServer(s grpc.ServiceRegistrar, srv RoutingServiceServer) { +func RegisterRoutingServiceServer(s *grpc.Server, srv RoutingServiceServer) { s.RegisterService(&RoutingService_ServiceDesc, srv) } @@ -142,9 +218,114 @@ func _RoutingService_TestRoute_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } -// RoutingService_ServiceDesc is the grpc.ServiceDesc for RoutingService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) +func _RoutingService_AddRoutingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddRoutingRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoutingServiceServer).AddRoutingRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/xray.app.router.command.RoutingService/AddRoutingRule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoutingServiceServer).AddRoutingRule(ctx, req.(*AddRoutingRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoutingService_AlterRoutingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AlterRoutingRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoutingServiceServer).AlterRoutingRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/xray.app.router.command.RoutingService/AlterRoutingRule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoutingServiceServer).AlterRoutingRule(ctx, req.(*AlterRoutingRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoutingService_RemoveRoutingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveRoutingRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoutingServiceServer).RemoveRoutingRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/xray.app.router.command.RoutingService/RemoveRoutingRule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoutingServiceServer).RemoveRoutingRule(ctx, req.(*RemoveRoutingRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoutingService_AddBalancingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddBalancingRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoutingServiceServer).AddBalancingRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/xray.app.router.command.RoutingService/AddBalancingRule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoutingServiceServer).AddBalancingRule(ctx, req.(*AddBalancingRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoutingService_AlterBalancingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AlterBalancingRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoutingServiceServer).AlterBalancingRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/xray.app.router.command.RoutingService/AlterBalancingRule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoutingServiceServer).AlterBalancingRule(ctx, req.(*AlterBalancingRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoutingService_RemoveBalancingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveBalancingRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoutingServiceServer).RemoveBalancingRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/xray.app.router.command.RoutingService/RemoveBalancingRule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoutingServiceServer).RemoveBalancingRule(ctx, req.(*RemoveBalancingRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + var RoutingService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "xray.app.router.command.RoutingService", HandlerType: (*RoutingServiceServer)(nil), @@ -153,6 +334,30 @@ var RoutingService_ServiceDesc = grpc.ServiceDesc{ MethodName: "TestRoute", Handler: _RoutingService_TestRoute_Handler, }, + { + MethodName: "AddRoutingRule", + Handler: _RoutingService_AddRoutingRule_Handler, + }, + { + MethodName: "AlterRoutingRule", + Handler: _RoutingService_AlterRoutingRule_Handler, + }, + { + MethodName: "RemoveRoutingRule", + Handler: _RoutingService_RemoveRoutingRule_Handler, + }, + { + MethodName: "AddBalancingRule", + Handler: _RoutingService_AddBalancingRule_Handler, + }, + { + MethodName: "AlterBalancingRule", + Handler: _RoutingService_AlterBalancingRule_Handler, + }, + { + MethodName: "RemoveBalancingRule", + Handler: _RoutingService_RemoveBalancingRule_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/app/router/command/command_test.go b/app/router/command/command_test.go index e8e50cc65ba2..e97e8989446b 100644 --- a/app/router/command/command_test.go +++ b/app/router/command/command_test.go @@ -2,6 +2,8 @@ package command_test import ( "context" + "errors" + "fmt" "testing" "time" @@ -200,7 +202,7 @@ func TestServiceSubscribeRoutingStats(t *testing.T) { } } -func TestSerivceTestRoute(t *testing.T) { +func TestServiceTestRoute(t *testing.T) { c := stats.NewChannel(&stats.ChannelConfig{ SubscriberLimit: 1, BufferSize: 16, @@ -216,35 +218,379 @@ func TestSerivceTestRoute(t *testing.T) { Rule: []*router.RoutingRule{ { InboundTag: []string{"in"}, - TargetTag: &router.RoutingRule_Tag{Tag: "out"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, }, { + Networks: []net.Network{net.Network_UDP, net.Network_TCP}, Protocol: []string{"bittorrent"}, - TargetTag: &router.RoutingRule_Tag{Tag: "blocked"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "blocked"}, }, { PortList: &net.PortList{Range: []*net.PortRange{{From: 8080, To: 8080}}}, - TargetTag: &router.RoutingRule_Tag{Tag: "out"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, }, { SourcePortList: &net.PortList{Range: []*net.PortRange{{From: 9999, To: 9999}}}, - TargetTag: &router.RoutingRule_Tag{Tag: "out"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, }, { Domain: []*router.Domain{{Type: router.Domain_Domain, Value: "com"}}, - TargetTag: &router.RoutingRule_Tag{Tag: "out"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, }, { SourceGeoip: []*router.GeoIP{{CountryCode: "private", Cidr: []*router.CIDR{{Ip: []byte{127, 0, 0, 0}, Prefix: 8}}}}, - TargetTag: &router.RoutingRule_Tag{Tag: "out"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, }, { UserEmail: []string{"example@example.com"}, - TargetTag: &router.RoutingRule_Tag{Tag: "out"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + { + Networks: []net.Network{net.Network_TCP}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + }, + }, mocks.NewDNSClient(mockCtl), mocks.NewOutboundManager(mockCtl))) + + lis := bufconn.Listen(1024 * 1024) + bufDialer := func(context.Context, string) (net.Conn, error) { + return lis.Dial() + } + + errCh := make(chan error) + + // Server goroutine + go func() { + server := grpc.NewServer() + RegisterRoutingServiceServer(server, NewRoutingServer(r, c)) + errCh <- server.Serve(lis) + }() + + // Client goroutine + go func() { + defer lis.Close() + conn, err := grpc.DialContext(context.Background(), "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure()) + if err != nil { + errCh <- err + } + defer conn.Close() + client := NewRoutingServiceClient(conn) + + testCases := []*RoutingContext{ + {InboundTag: "in", OutboundTag: "out"}, + {TargetIPs: [][]byte{{1, 2, 3, 4}}, TargetPort: 8080, OutboundTag: "out"}, + {TargetDomain: "example.com", TargetPort: 443, OutboundTag: "out"}, + {SourcePort: 9999, TargetPort: 9999, OutboundTag: "out"}, + {Network: net.Network_UDP, Protocol: "bittorrent", OutboundTag: "blocked"}, + {User: "example@example.com", OutboundTag: "out"}, + {SourceIPs: [][]byte{{127, 0, 0, 1}}, Attributes: map[string]string{"attr": "value"}, OutboundTag: "out"}, + } + + // Test simple TestRoute + testSimple := func() error { + for _, tc := range testCases { + route, err := client.TestRoute(context.Background(), &TestRouteRequest{RoutingContext: tc}) + if err != nil { + return err + } + if r := cmp.Diff(route, tc, cmpopts.IgnoreUnexported(RoutingContext{})); r != "" { + t.Error(r) + } + } + return nil + } + + // Test TestRoute with special options + testOptions := func() error { + sub, err := c.Subscribe() + if err != nil { + return err + } + for _, tc := range testCases { + route, err := client.TestRoute(context.Background(), &TestRouteRequest{ + RoutingContext: tc, + FieldSelectors: []string{"ip", "port", "domain", "outbound"}, + PublishResult: true, + }) + if err != nil { + return err + } + stat := &RoutingContext{ // Only a subset of stats is retrieved + SourceIPs: tc.SourceIPs, + TargetIPs: tc.TargetIPs, + SourcePort: tc.SourcePort, + TargetPort: tc.TargetPort, + TargetDomain: tc.TargetDomain, + OutboundGroupTags: tc.OutboundGroupTags, + OutboundTag: tc.OutboundTag, + } + if r := cmp.Diff(route, stat, cmpopts.IgnoreUnexported(RoutingContext{})); r != "" { + t.Error(r) + } + select { // Check that routing result has been published to statistics channel + case msg, received := <-sub: + if route, ok := msg.(routing.Route); received && ok { + if r := cmp.Diff(AsProtobufMessage(nil)(route), tc, cmpopts.IgnoreUnexported(RoutingContext{})); r != "" { + t.Error(r) + } + } else { + t.Error("unexpected failure in receiving published routing result for testcase", tc) + } + case <-time.After(100 * time.Millisecond): + t.Error("unexpected failure in receiving published routing result", tc) + } + } + return nil + } + + if err := testSimple(); err != nil { + errCh <- err + } + if err := testOptions(); err != nil { + errCh <- err + } + errCh <- nil // Client passed all tests successfully + }() + + // Wait for goroutines to complete + select { + case <-time.After(2 * time.Second): + t.Fatal("Test timeout after 2s") + case err := <-errCh: + if err != nil { + t.Fatal(err) + } + } +} + +func TestServiceAddRoutingRule(t *testing.T) { + c := stats.NewChannel(&stats.ChannelConfig{ + SubscriberLimit: 1, + BufferSize: 16, + Blocking: true, + }) + common.Must(c.Start()) + defer c.Close() + + r := new(router.Router) + mockCtl := gomock.NewController(t) + defer mockCtl.Finish() + common.Must(r.Init(&router.Config{}, mocks.NewDNSClient(mockCtl), mocks.NewOutboundManager(mockCtl))) + + lis := bufconn.Listen(1024 * 1024) + bufDialer := func(context.Context, string) (net.Conn, error) { + return lis.Dial() + } + + errCh := make(chan error) + + // Server goroutine + go func() { + server := grpc.NewServer() + RegisterRoutingServiceServer(server, NewRoutingServer(r, c)) + errCh <- server.Serve(lis) + }() + + // Client goroutine + go func() { + defer lis.Close() + conn, err := grpc.DialContext(context.Background(), "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure()) + if err != nil { + errCh <- err + } + defer conn.Close() + client := NewRoutingServiceClient(conn) + + testAddRuleCases := []*router.RoutingRule{ + { + InboundTag: []string{"in"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, }, { Networks: []net.Network{net.Network_UDP, net.Network_TCP}, - TargetTag: &router.RoutingRule_Tag{Tag: "out"}, + Protocol: []string{"bittorrent"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "blocked"}, + }, + { + PortList: &net.PortList{Range: []*net.PortRange{{From: 8080, To: 8080}}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + { + SourcePortList: &net.PortList{Range: []*net.PortRange{{From: 9999, To: 9999}}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + { + Domain: []*router.Domain{{Type: router.Domain_Domain, Value: "com"}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + { + SourceGeoip: []*router.GeoIP{{CountryCode: "private", Cidr: []*router.CIDR{{Ip: []byte{127, 0, 0, 0}, Prefix: 8}}}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + { + UserEmail: []string{"example@example.com"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + { + Networks: []net.Network{net.Network_TCP}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + } + + // Test add rule + testAddRule := func() error { + for _, tc := range testAddRuleCases { + _, err := client.AddRoutingRule(context.Background(), &AddRoutingRuleRequest{RoutingRule: tc}) + if err != nil { + return err + } + } + return nil + } + + testCases := []*RoutingContext{ + {InboundTag: "in", OutboundTag: "out"}, + {TargetIPs: [][]byte{{1, 2, 3, 4}}, TargetPort: 8080, OutboundTag: "out"}, + {TargetDomain: "example.com", TargetPort: 443, OutboundTag: "out"}, + {SourcePort: 9999, TargetPort: 9999, OutboundTag: "out"}, + {Network: net.Network_UDP, Protocol: "bittorrent", OutboundTag: "blocked"}, + {User: "example@example.com", OutboundTag: "out"}, + {SourceIPs: [][]byte{{127, 0, 0, 1}}, Attributes: map[string]string{"attr": "value"}, OutboundTag: "out"}, + } + + // Test simple TestRoute + testSimple := func() error { + for _, tc := range testCases { + route, err := client.TestRoute(context.Background(), &TestRouteRequest{RoutingContext: tc}) + if err != nil { + return err + } + if r := cmp.Diff(route, tc, cmpopts.IgnoreUnexported(RoutingContext{})); r != "" { + t.Error(r) + } + } + return nil + } + + // Test TestRoute with special options + testOptions := func() error { + sub, err := c.Subscribe() + if err != nil { + return err + } + for _, tc := range testCases { + route, err := client.TestRoute(context.Background(), &TestRouteRequest{ + RoutingContext: tc, + FieldSelectors: []string{"ip", "port", "domain", "outbound"}, + PublishResult: true, + }) + if err != nil { + return err + } + stat := &RoutingContext{ // Only a subset of stats is retrieved + SourceIPs: tc.SourceIPs, + TargetIPs: tc.TargetIPs, + SourcePort: tc.SourcePort, + TargetPort: tc.TargetPort, + TargetDomain: tc.TargetDomain, + OutboundGroupTags: tc.OutboundGroupTags, + OutboundTag: tc.OutboundTag, + } + if r := cmp.Diff(route, stat, cmpopts.IgnoreUnexported(RoutingContext{})); r != "" { + t.Error(r) + } + select { // Check that routing result has been published to statistics channel + case msg, received := <-sub: + if route, ok := msg.(routing.Route); received && ok { + if r := cmp.Diff(AsProtobufMessage(nil)(route), tc, cmpopts.IgnoreUnexported(RoutingContext{})); r != "" { + t.Error(r) + } + } else { + t.Error("unexpected failure in receiving published routing result for testcase", tc) + } + case <-time.After(100 * time.Millisecond): + t.Error("unexpected failure in receiving published routing result", tc) + } + } + return nil + } + + if err := testAddRule(); err != nil { + errCh <- err + } + if err := testSimple(); err != nil { + errCh <- err + } + if err := testOptions(); err != nil { + errCh <- err + } + errCh <- nil // Client passed all tests successfully + }() + + // Wait for goroutines to complete + select { + case <-time.After(2 * time.Second): + t.Fatal("Test timeout after 2s") + case err := <-errCh: + if err != nil { + t.Fatal(err) + } + } +} + +func TestServiceAlterRoutingRule(t *testing.T) { + c := stats.NewChannel(&stats.ChannelConfig{ + SubscriberLimit: 1, + BufferSize: 16, + Blocking: true, + }) + common.Must(c.Start()) + defer c.Close() + + r := new(router.Router) + mockCtl := gomock.NewController(t) + defer mockCtl.Finish() + common.Must(r.Init(&router.Config{ + Rule: []*router.RoutingRule{ + { + InboundTag: []string{"in"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "test"}, + Tag: "in_out", + }, + { + InboundTag: []string{"in"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "test"}, + Tag: "udp_bittorrent_blocked", + }, + { + InboundTag: []string{"in"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "test"}, + Tag: "8080_out", + }, + { + InboundTag: []string{"in"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "test"}, + Tag: "9999_out", + }, + { + InboundTag: []string{"in"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "test"}, + Tag: "com_out", + }, + { + InboundTag: []string{"in"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "test"}, + Tag: "127.0.0.1_out", + }, + { + InboundTag: []string{"in"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "test"}, + Tag: "example_out", + }, + { + InboundTag: []string{"in"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "test"}, + Tag: "tcp_out", }, }, }, mocks.NewDNSClient(mockCtl), mocks.NewOutboundManager(mockCtl))) @@ -273,6 +619,77 @@ func TestSerivceTestRoute(t *testing.T) { defer conn.Close() client := NewRoutingServiceClient(conn) + testAlterRuleCases := []*AlterRoutingRuleRequest{ + { + Tag: "in_out", + RoutingRule: &router.RoutingRule{ + InboundTag: []string{"in"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + }, + { + Tag: "udp_bittorrent_blocked", + RoutingRule: &router.RoutingRule{ + Networks: []net.Network{net.Network_UDP, net.Network_TCP}, + Protocol: []string{"bittorrent"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "blocked"}, + }, + }, + { + Tag: "8080_out", + RoutingRule: &router.RoutingRule{ + PortList: &net.PortList{Range: []*net.PortRange{{From: 8080, To: 8080}}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + }, + { + Tag: "9999_out", + RoutingRule: &router.RoutingRule{ + SourcePortList: &net.PortList{Range: []*net.PortRange{{From: 9999, To: 9999}}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + }, + { + Tag: "com_out", + RoutingRule: &router.RoutingRule{ + Domain: []*router.Domain{{Type: router.Domain_Domain, Value: "com"}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + }, + { + Tag: "127.0.0.1_out", + RoutingRule: &router.RoutingRule{ + SourceGeoip: []*router.GeoIP{{CountryCode: "private", Cidr: []*router.CIDR{{Ip: []byte{127, 0, 0, 0}, Prefix: 8}}}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + }, + { + Tag: "example_out", + RoutingRule: &router.RoutingRule{ + UserEmail: []string{"example@example.com"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + }, + { + Tag: "tcp_out", + RoutingRule: &router.RoutingRule{ + Networks: []net.Network{net.Network_TCP}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + }, + }, + } + + // Test alter rule + testAlterRule := func() error { + for _, tc := range testAlterRuleCases { + _, err := client.AlterRoutingRule(context.Background(), tc) + if err != nil { + return err + } + } + return nil + } + testCases := []*RoutingContext{ {InboundTag: "in", OutboundTag: "out"}, {TargetIPs: [][]byte{{1, 2, 3, 4}}, TargetPort: 8080, OutboundTag: "out"}, @@ -340,6 +757,9 @@ func TestSerivceTestRoute(t *testing.T) { return nil } + if err := testAlterRule(); err != nil { + errCh <- err + } if err := testSimple(); err != nil { errCh <- err } @@ -359,3 +779,149 @@ func TestSerivceTestRoute(t *testing.T) { } } } + +func TestServiceRemoveRoutingRule(t *testing.T) { + c := stats.NewChannel(&stats.ChannelConfig{ + SubscriberLimit: 1, + BufferSize: 16, + Blocking: true, + }) + common.Must(c.Start()) + defer c.Close() + + r := new(router.Router) + mockCtl := gomock.NewController(t) + defer mockCtl.Finish() + common.Must(r.Init(&router.Config{ + Rule: []*router.RoutingRule{ + { + InboundTag: []string{"in"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + Tag: "in_out", + }, + { + Networks: []net.Network{net.Network_UDP, net.Network_TCP}, + Protocol: []string{"bittorrent"}, + Tag: "udp_bittorrent_blocked", + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "blocked"}, + }, + { + PortList: &net.PortList{Range: []*net.PortRange{{From: 8080, To: 8080}}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + Tag: "8080_out", + }, + { + SourcePortList: &net.PortList{Range: []*net.PortRange{{From: 9999, To: 9999}}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + Tag: "9999_out", + }, + { + Domain: []*router.Domain{{Type: router.Domain_Domain, Value: "com"}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + Tag: "com_out", + }, + { + SourceGeoip: []*router.GeoIP{{CountryCode: "private", Cidr: []*router.CIDR{{Ip: []byte{127, 0, 0, 0}, Prefix: 8}}}}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + Tag: "127.0.0.1_out", + }, + { + UserEmail: []string{"example@example.com"}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + Tag: "example_out", + }, + { + Networks: []net.Network{net.Network_TCP}, + TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, + Tag: "tcp_out", + }, + }, + }, mocks.NewDNSClient(mockCtl), mocks.NewOutboundManager(mockCtl))) + + lis := bufconn.Listen(1024 * 1024) + bufDialer := func(context.Context, string) (net.Conn, error) { + return lis.Dial() + } + + errCh := make(chan error) + + // Server goroutine + go func() { + server := grpc.NewServer() + RegisterRoutingServiceServer(server, NewRoutingServer(r, c)) + errCh <- server.Serve(lis) + }() + + // Client goroutine + go func() { + defer lis.Close() + conn, err := grpc.DialContext(context.Background(), "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure()) + if err != nil { + errCh <- err + } + defer conn.Close() + client := NewRoutingServiceClient(conn) + + testRemoveRuleCases := []string{ + "in_out", + "udp_bittorrent_blocked", + "8080_out", + "9999_out", + "com_out", + "127.0.0.1_out", + "example_out", + "tcp_out", + } + + // Test alter rule + testRemoveRule := func() error { + for _, tc := range testRemoveRuleCases { + _, err := client.RemoveRoutingRule(context.Background(), &RemoveRoutingRuleRequest{Tag: tc}) + if err != nil { + return err + } + } + return nil + } + + testCases := []*RoutingContext{ + {InboundTag: "in", OutboundTag: "out"}, + {TargetIPs: [][]byte{{1, 2, 3, 4}}, TargetPort: 8080, OutboundTag: "out"}, + {TargetDomain: "example.com", TargetPort: 443, OutboundTag: "out"}, + {SourcePort: 9999, TargetPort: 9999, OutboundTag: "out"}, + {Network: net.Network_UDP, Protocol: "bittorrent", OutboundTag: "blocked"}, + {User: "example@example.com", OutboundTag: "out"}, + {SourceIPs: [][]byte{{127, 0, 0, 1}}, Attributes: map[string]string{"attr": "value"}, OutboundTag: "out"}, + } + + // Test simple TestRoute + testSimple := func() error { + for _, tc := range testCases { + route, err := client.TestRoute(context.Background(), &TestRouteRequest{RoutingContext: tc}) + if err == nil { + return errors.New(fmt.Sprintf("Delete route failed, remaining route:[%s]", route.Tag)) + } + } + return nil + } + + if err := testRemoveRule(); err != nil { + errCh <- err + } + if err := testSimple(); err != nil { + errCh <- err + } + errCh <- nil // Client passed all tests successfully + }() + + // Wait for goroutines to complete + select { + case <-time.After(2 * time.Second): + t.Fatal("Test timeout after 2s") + case err := <-errCh: + if err != nil { + t.Fatal(err) + } + } +} + diff --git a/app/router/command/config.go b/app/router/command/config.go index e95418dcf5da..e5fcb2d1efe1 100644 --- a/app/router/command/config.go +++ b/app/router/command/config.go @@ -51,6 +51,7 @@ var fieldMap = map[string]func(*RoutingContext, routing.Route){ "attributes": func(s *RoutingContext, r routing.Route) { s.Attributes = r.GetAttributes() }, "outbound_group": func(s *RoutingContext, r routing.Route) { s.OutboundGroupTags = r.GetOutboundGroupTags() }, "outbound": func(s *RoutingContext, r routing.Route) { s.OutboundTag = r.GetOutboundTag() }, + "tag": func(s *RoutingContext, r routing.Route) { s.Tag = r.GetTag() }, } // AsProtobufMessage takes selectors of fields and returns a function to convert routing.Route to protobuf RoutingContext. diff --git a/app/router/config.go b/app/router/config.go index 07167a530198..196eaff92b92 100644 --- a/app/router/config.go +++ b/app/router/config.go @@ -2,6 +2,7 @@ package router import ( "github.com/xtls/xray-core/common/net" + "github.com/xtls/xray-core/common/uuid" "github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/features/routing" ) @@ -47,15 +48,16 @@ func (l *CIDRList) Swap(i int, j int) { type Rule struct { Tag string + TargetTag string Balancer *Balancer Condition Condition } -func (r *Rule) GetTag() (string, error) { +func (r *Rule) GetTargetTag() (string, error) { if r.Balancer != nil { return r.Balancer.PickOutbound() } - return r.Tag, nil + return r.TargetTag, nil } // Apply checks rule matching of current routing context. @@ -145,6 +147,42 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) { return conds, nil } +// Build RoutingRule translates into Rule. +func (rr *RoutingRule) Build(r *Router) (*Rule, error) { + tag := rr.Tag + rule := &Rule{ + Tag: tag, + } + + if len(rule.Tag) > 0 { + if _, found := r.rules[tag]; found { + return nil, newError("existing tag found: " + tag) + } + } else { + u := uuid.New() + rule.Tag = u.String() + } + + btag := rr.GetBalancingTag() + if len(btag) > 0 { + brule, found := r.balancers[btag] + if !found { + return nil, newError("balancer ", btag, " not found") + } + rule.Balancer = brule + } else { + rule.TargetTag = rr.GetTargetTag().(*RoutingRule_OutboundTag).OutboundTag + } + + cond, err := rr.BuildCondition() + if err != nil { + return nil, err + } + + rule.Condition = cond + return rule, nil +} + func (br *BalancingRule) Build(ohm outbound.Manager) (*Balancer, error) { return &Balancer{ selectors: br.OutboundSelector, diff --git a/app/router/config.pb.go b/app/router/config.pb.go index 69abd3706158..e3581d402e83 100644 --- a/app/router/config.pb.go +++ b/app/router/config.pb.go @@ -1,13 +1,12 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.14.0 +// protoc-gen-go v1.26.0 +// protoc v3.15.6 // source: app/router/config.proto package router import ( - proto "github.com/golang/protobuf/proto" net "github.com/xtls/xray-core/common/net" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -22,10 +21,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // Type of domain value. type Domain_Type int32 @@ -474,7 +469,7 @@ type RoutingRule struct { unknownFields protoimpl.UnknownFields // Types that are assignable to TargetTag: - // *RoutingRule_Tag + // *RoutingRule_OutboundTag // *RoutingRule_BalancingTag TargetTag isRoutingRule_TargetTag `protobuf_oneof:"target_tag"` // List of domains for target domain matching. @@ -515,6 +510,7 @@ type RoutingRule struct { InboundTag []string `protobuf:"bytes,8,rep,name=inbound_tag,json=inboundTag,proto3" json:"inbound_tag,omitempty"` Protocol []string `protobuf:"bytes,9,rep,name=protocol,proto3" json:"protocol,omitempty"` Attributes string `protobuf:"bytes,15,opt,name=attributes,proto3" json:"attributes,omitempty"` + Tag string `protobuf:"bytes,17,opt,name=tag,proto3" json:"tag,omitempty"` } func (x *RoutingRule) Reset() { @@ -556,9 +552,9 @@ func (m *RoutingRule) GetTargetTag() isRoutingRule_TargetTag { return nil } -func (x *RoutingRule) GetTag() string { - if x, ok := x.GetTargetTag().(*RoutingRule_Tag); ok { - return x.Tag +func (x *RoutingRule) GetOutboundTag() string { + if x, ok := x.GetTargetTag().(*RoutingRule_OutboundTag); ok { + return x.OutboundTag } return "" } @@ -672,13 +668,20 @@ func (x *RoutingRule) GetAttributes() string { return "" } +func (x *RoutingRule) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + type isRoutingRule_TargetTag interface { isRoutingRule_TargetTag() } -type RoutingRule_Tag struct { +type RoutingRule_OutboundTag struct { // Tag of outbound that this rule is pointing to. - Tag string `protobuf:"bytes,1,opt,name=tag,proto3,oneof"` + OutboundTag string `protobuf:"bytes,1,opt,name=outbound_tag,json=outboundTag,proto3,oneof"` } type RoutingRule_BalancingTag struct { @@ -686,7 +689,7 @@ type RoutingRule_BalancingTag struct { BalancingTag string `protobuf:"bytes,12,opt,name=balancing_tag,json=balancingTag,proto3,oneof"` } -func (*RoutingRule_Tag) isRoutingRule_TargetTag() {} +func (*RoutingRule_OutboundTag) isRoutingRule_TargetTag() {} func (*RoutingRule_BalancingTag) isRoutingRule_TargetTag() {} @@ -946,84 +949,86 @@ var file_app_router_config_proto_rawDesc = []byte{ 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x22, 0x8e, 0x06, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, - 0x65, 0x12, 0x12, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, - 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x25, 0x0a, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, - 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x67, 0x12, 0x2f, 0x0a, 0x06, - 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x2d, 0x0a, - 0x04, 0x63, 0x69, 0x64, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x49, - 0x44, 0x52, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x12, 0x2c, 0x0a, 0x05, - 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, - 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x3d, 0x0a, 0x0a, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, - 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, - 0x70, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x70, 0x6f, 0x72, - 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, - 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, - 0x74, 0x12, 0x43, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x52, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x3a, 0x0a, 0x0b, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0a, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x43, 0x69, 0x64, 0x72, 0x12, 0x39, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, - 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x65, - 0x6f, 0x69, 0x70, 0x12, 0x43, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x79, 0x22, 0xb1, 0x06, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, + 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x25, 0x0a, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x67, 0x12, 0x2f, 0x0a, + 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, + 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x2d, + 0x0a, 0x04, 0x63, 0x69, 0x64, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, + 0x49, 0x44, 0x52, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x12, 0x2c, 0x0a, + 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, + 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x3d, 0x0a, 0x0a, 0x70, + 0x6f, 0x72, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, + 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, + 0x09, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x70, 0x6f, + 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, - 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, - 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, - 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, - 0x61, 0x67, 0x22, 0x4e, 0x0a, 0x0d, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x22, 0x9b, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4f, 0x0a, - 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, - 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x30, - 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, - 0x12, 0x45, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, - 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, - 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x49, 0x70, 0x10, 0x01, 0x12, 0x10, - 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x02, - 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x70, 0x4f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x03, - 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, - 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0xaa, - 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x69, + 0x73, 0x74, 0x12, 0x43, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x6c, 0x69, + 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x52, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x3a, 0x0a, + 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0a, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x69, 0x64, 0x72, 0x12, 0x39, 0x0a, 0x0c, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, + 0x65, 0x6f, 0x69, 0x70, 0x12, 0x43, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, + 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, + 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x62, 0x6f, + 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, + 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x4e, 0x0a, 0x0d, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x9b, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, + 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, + 0x79, 0x12, 0x30, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, + 0x75, 0x6c, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, + 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, + 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x47, 0x0a, 0x0e, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, + 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x49, 0x70, 0x10, + 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, + 0x68, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x70, 0x4f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, + 0x64, 0x10, 0x03, 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, + 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, + 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0xaa, 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1213,7 +1218,7 @@ func file_app_router_config_proto_init() { } } file_app_router_config_proto_msgTypes[6].OneofWrappers = []interface{}{ - (*RoutingRule_Tag)(nil), + (*RoutingRule_OutboundTag)(nil), (*RoutingRule_BalancingTag)(nil), } file_app_router_config_proto_msgTypes[9].OneofWrappers = []interface{}{ diff --git a/app/router/config.proto b/app/router/config.proto index c5e655adeafc..47f6918530a9 100644 --- a/app/router/config.proto +++ b/app/router/config.proto @@ -72,7 +72,7 @@ message GeoSiteList { message RoutingRule { oneof target_tag { // Tag of outbound that this rule is pointing to. - string tag = 1; + string outbound_tag = 1; // Tag of routing balancer. string balancing_tag = 12; @@ -119,6 +119,7 @@ message RoutingRule { repeated string protocol = 9; string attributes = 15; + string tag = 17; } message BalancingRule { diff --git a/app/router/router.go b/app/router/router.go index 5d2bdc34adc1..aaf42f8ef668 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -4,21 +4,25 @@ package router import ( "context" - "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/session" + "github.com/xtls/xray-core/common/uuid" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/features/routing" routing_dns "github.com/xtls/xray-core/features/routing/dns" + "sync" ) // Router is an implementation of routing.Router. type Router struct { + access sync.RWMutex domainStrategy Config_DomainStrategy - rules []*Rule + rules map[string]*Rule balancers map[string]*Balancer dns dns.Client + Tag string } // Route is an implementation of routing.Route. @@ -33,7 +37,9 @@ func (r *Router) Init(config *Config, d dns.Client, ohm outbound.Manager) error r.domainStrategy = config.DomainStrategy r.dns = d - r.balancers = make(map[string]*Balancer, len(config.BalancingRule)) + r.access.Lock() + defer r.access.Unlock() + r.balancers = make(map[string]*Balancer) for _, rule := range config.BalancingRule { balancer, err := rule.Build(ohm) if err != nil { @@ -42,7 +48,7 @@ func (r *Router) Init(config *Config, d dns.Client, ohm outbound.Manager) error r.balancers[rule.Tag] = balancer } - r.rules = make([]*Rule, 0, len(config.Rule)) + r.rules = make(map[string]*Rule) for _, rule := range config.Rule { cond, err := rule.BuildCondition() if err != nil { @@ -59,8 +65,17 @@ func (r *Router) Init(config *Config, d dns.Client, ohm outbound.Manager) error return newError("balancer ", btag, " not found") } rr.Balancer = brule + rr.TargetTag = btag + } else { + rr.TargetTag = rule.GetTargetTag().(*RoutingRule_OutboundTag).OutboundTag + } + + if len(rr.Tag) == 0 { + u := uuid.New() + rr.Tag = u.String() } - r.rules = append(r.rules, rr) + + r.rules[rr.Tag] = rr } return nil @@ -72,7 +87,7 @@ func (r *Router) PickRoute(ctx routing.Context) (routing.Route, error) { if err != nil { return nil, err } - tag, err := rule.GetTag() + tag, err := rule.GetTargetTag() if err != nil { return nil, err } @@ -84,6 +99,9 @@ func (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routing.Context, ctx = routing_dns.ContextWithDNSClient(ctx, r.dns) } + r.access.RLock() + defer r.access.RUnlock() + for _, rule := range r.rules { if rule.Apply(ctx) { return rule, ctx, nil @@ -106,6 +124,103 @@ func (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routing.Context, return nil, ctx, common.ErrNoClue } +// AddRoutingRule implement the manager interface. +func (r *Router) AddRoutingRule(ctx context.Context, routingRule interface{}) error { + rr := routingRule.(*RoutingRule) + rule, err := rr.Build(r) + if err != nil { + return err + } + r.access.Lock() + defer r.access.Unlock() + + r.rules[rule.Tag] = rule + newError("Rule has been added through the API. [", rule.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) + return nil +} + +// AlterRoutingRule implement the manager interface. +func (r *Router) AlterRoutingRule(ctx context.Context, tag string, routingRule interface{}) error { + if _, found := r.rules[tag]; !found { + return newError("tag not found: " + tag) + } + + rr := routingRule.(*RoutingRule) + // Removing the tag ensures that Build works properly + rr.Tag = "" + rule, err := rr.Build(r) + if err != nil { + return err + } + r.access.Lock() + defer r.access.Unlock() + + rule.Tag = tag + r.rules[tag] = rule + newError("The rules have been modified through the API. [", rule.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) + return nil +} + +// RemoveRoutingRule implement the manager interface. +func (r *Router) RemoveRoutingRule(ctx context.Context, tag string) error { + if _, found := r.rules[tag]; !found { + return newError("tag not found: " + tag) + } + r.access.Lock() + defer r.access.Unlock() + + delete(r.rules, tag) + newError("The rule has been removed through the API. [", tag, "]").WriteToLog(session.ExportIDToError(ctx)) + return nil +} + +// AddBalancingRule implement the manager interface. +func (r *Router) AddBalancingRule(ctx context.Context, balancingRule interface{}, om outbound.Manager) error { + br := balancingRule.(*BalancingRule) + balancer, err := br.Build(om) + if err != nil { + return err + } + r.access.Lock() + defer r.access.Unlock() + + r.balancers[br.Tag] = balancer + newError("Rule has been added through the API. [", br.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) + return nil +} + +// AlterBalancingRule implement the manager interface. +func (r *Router) AlterBalancingRule(ctx context.Context, tag string, balancingRule interface{}, om outbound.Manager) error { + if _, found := r.balancers[tag]; !found { + return newError("tag not found: " + tag) + } + + br := balancingRule.(*BalancingRule) + balancer, err := br.Build(om) + if err != nil { + return err + } + r.access.Lock() + defer r.access.Unlock() + + r.balancers[tag] = balancer + newError("The rules have been modified through the API. [", tag, "]").WriteToLog(session.ExportIDToError(ctx)) + return nil +} + +// RemoveBalancingRule implement the manager interface. +func (r *Router) RemoveBalancingRule(ctx context.Context, tag string) error { + if _, found := r.balancers[tag]; !found { + return newError("tag not found: " + tag) + } + r.access.Lock() + defer r.access.Unlock() + + delete(r.balancers, tag) + newError("The rule has been removed through the API. [", tag, "]").WriteToLog(session.ExportIDToError(ctx)) + return nil +} + // Start implements common.Runnable. func (*Router) Start() error { return nil diff --git a/app/router/router_test.go b/app/router/router_test.go index 14ce8a3d4e64..468a311584e1 100644 --- a/app/router/router_test.go +++ b/app/router/router_test.go @@ -2,6 +2,7 @@ package router_test import ( "context" + "github.com/xtls/xray-core/core" "testing" "github.com/golang/mock/gomock" @@ -24,8 +25,8 @@ func TestSimpleRouter(t *testing.T) { config := &Config{ Rule: []*RoutingRule{ { - TargetTag: &RoutingRule_Tag{ - Tag: "test", + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "test", }, Networks: []net.Network{net.Network_TCP}, }, @@ -99,8 +100,8 @@ func TestIPOnDemand(t *testing.T) { DomainStrategy: Config_IpOnDemand, Rule: []*RoutingRule{ { - TargetTag: &RoutingRule_Tag{ - Tag: "test", + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "test", }, Cidr: []*CIDR{ { @@ -138,8 +139,8 @@ func TestIPIfNonMatchDomain(t *testing.T) { DomainStrategy: Config_IpIfNonMatch, Rule: []*RoutingRule{ { - TargetTag: &RoutingRule_Tag{ - Tag: "test", + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "test", }, Cidr: []*CIDR{ { @@ -177,8 +178,8 @@ func TestIPIfNonMatchIP(t *testing.T) { DomainStrategy: Config_IpIfNonMatch, Rule: []*RoutingRule{ { - TargetTag: &RoutingRule_Tag{ - Tag: "test", + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "test", }, Cidr: []*CIDR{ { @@ -205,3 +206,135 @@ func TestIPIfNonMatchIP(t *testing.T) { t.Error("expect tag 'test', bug actually ", tag) } } + +func TestRouter_AddRoutingRule(t *testing.T) { + config := &Config{} + + mockCtl := gomock.NewController(t) + defer mockCtl.Finish() + + mockDNS := mocks.NewDNSClient(mockCtl) + mockOhm := mocks.NewOutboundManager(mockCtl) + mockHs := mocks.NewOutboundHandlerSelector(mockCtl) + + r := new(Router) + common.Must(r.Init(config, mockDNS, &mockOutboundManager{ + Manager: mockOhm, + HandlerSelector: mockHs, + })) + + ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)}) + err := r.AddRoutingRule(ctx, &RoutingRule{ + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "test", + }, + Domain: []*Domain{ + { + Type: Domain_Domain, + Value: "example.com", + }, + }, + }) + common.Must(err) + + route, err := r.PickRoute(routing_session.AsRoutingContext(ctx)) + common.Must(err) + if tag := route.GetOutboundTag(); tag != "test" { + t.Error("expect tag 'test', bug actually ", tag) + } +} + +func TestRouter_AlterRoutingRule(t *testing.T) { + config := &Config{ + Rule: []*RoutingRule{ + { + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "example", + }, + Networks: []net.Network{net.Network_TCP}, + Tag: "test", + }, + }, + } + + mockCtl := gomock.NewController(t) + defer mockCtl.Finish() + + mockDNS := mocks.NewDNSClient(mockCtl) + mockOhm := mocks.NewOutboundManager(mockCtl) + mockHs := mocks.NewOutboundHandlerSelector(mockCtl) + + r := new(Router) + common.Must(r.Init(config, mockDNS, &mockOutboundManager{ + Manager: mockOhm, + HandlerSelector: mockHs, + })) + + ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)}) + err := r.AlterRoutingRule(ctx, "test", &RoutingRule{ + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "test", + }, + Domain: []*Domain{ + { + Type: Domain_Domain, + Value: "example.com", + }, + }, + Tag: "test", + }) + common.Must(err) + route, err := r.PickRoute(routing_session.AsRoutingContext(ctx)) + common.Must(err) + if tag := route.GetOutboundTag(); tag != "test" { + t.Error("expect tag 'test', bug actually ", tag) + } +} + +func TestRouter_RemoveRoutingRule(t *testing.T) { + config := &Config{ + Rule: []*RoutingRule{ + { + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "example", + }, + Domain: []*Domain{ + { + Type: Domain_Domain, + Value: "example.com", + }, + }, + Tag: "example", + }, + { + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "test", + }, + Networks: []net.Network{net.Network_TCP}, + Tag: "test", + }, + }, + } + + mockCtl := gomock.NewController(t) + defer mockCtl.Finish() + + mockDNS := mocks.NewDNSClient(mockCtl) + mockOhm := mocks.NewOutboundManager(mockCtl) + mockHs := mocks.NewOutboundHandlerSelector(mockCtl) + + r := new(Router) + common.Must(r.Init(config, mockDNS, &mockOutboundManager{ + Manager: mockOhm, + HandlerSelector: mockHs, + })) + + ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)}) + err := r.RemoveRoutingRule(ctx, "example") + common.Must(err) + route, err := r.PickRoute(routing_session.AsRoutingContext(ctx)) + common.Must(err) + if tag := route.GetOutboundTag(); tag != "test" { + t.Error("expect tag 'test', bug actually ", tag) + } +} diff --git a/features/routing/context.go b/features/routing/context.go index f5a732a4065e..d2d19f1657e3 100644 --- a/features/routing/context.go +++ b/features/routing/context.go @@ -37,4 +37,7 @@ type Context interface { // GetAttributes returns extra attributes from the conneciont content. GetAttributes() map[string]string + + // GetUser returns the user email from the connection content, if exists. + GetTag() string } diff --git a/features/routing/router.go b/features/routing/router.go index 3d6f150a299a..dd23915069d3 100644 --- a/features/routing/router.go +++ b/features/routing/router.go @@ -1,8 +1,10 @@ package routing import ( + "context" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/features" + "github.com/xtls/xray-core/features/outbound" ) // Router is a feature to choose an outbound tag for the given request. @@ -10,6 +12,7 @@ import ( // xray:api:stable type Router interface { features.Feature + Manager // PickRoute returns a route decision based on the given routing context. PickRoute(ctx Context) (Route, error) @@ -49,6 +52,36 @@ func (DefaultRouter) PickRoute(ctx Context) (Route, error) { return nil, common.ErrNoClue } +// AddRoutingRule implements Router. +func (DefaultRouter) AddRoutingRule(ctx context.Context, routingRule interface{}) error { + return common.ErrNoClue +} + +// AlterRoutingRule implements Router. +func (DefaultRouter) AlterRoutingRule(ctx context.Context, tag string, routingRule interface{}) error { + return common.ErrNoClue +} + +// RemoveRoutingRule implements Router. +func (DefaultRouter) RemoveRoutingRule(ctx context.Context, tag string) error { + return common.ErrNoClue +} + +// AddBalancingRule implements Router. +func (DefaultRouter) AddBalancingRule(ctx context.Context, balancingRule interface{}, handler outbound.Manager) error { + return common.ErrNoClue +} + +// AlterBalancingRule implements Router. +func (DefaultRouter) AlterBalancingRule(ctx context.Context, tag string, balancingRule interface{}, handler outbound.Manager) error { + return common.ErrNoClue +} + +// RemoveBalancingRule implements Router. +func (DefaultRouter) RemoveBalancingRule(ctx context.Context, tag string) error { + return common.ErrNoClue +} + // Start implements common.Runnable. func (DefaultRouter) Start() error { return nil @@ -58,3 +91,22 @@ func (DefaultRouter) Start() error { func (DefaultRouter) Close() error { return nil } + +// Manager is a feature that manages Router rule. +// +// xray:api:alpha +type Manager interface { + features.Feature + // AddRoutingRule adds the given routing rule into this Manager. + AddRoutingRule(ctx context.Context, routingRule interface{}) error + // AlterRoutingRule Modifies the specified routing rule + AlterRoutingRule(ctx context.Context, tag string, routingRule interface{}) error + // RemoveRoutingRule Remove the specified routing rule + RemoveRoutingRule(ctx context.Context, tag string) error + // AddBalancingRule adds the given balancing rules to this manager. + AddBalancingRule(ctx context.Context, balancingRule interface{}, handler outbound.Manager) error + // AlterBalancingRule Modifies the specified balancing rule + AlterBalancingRule(ctx context.Context, tag string, balancingRule interface{}, handler outbound.Manager) error + // RemoveBalancingRule Remove the specified balancing rule + RemoveBalancingRule(ctx context.Context, tag string) error +} diff --git a/features/routing/session/context.go b/features/routing/session/context.go index 0b37ebfa993a..fba1aa5dc85a 100644 --- a/features/routing/session/context.go +++ b/features/routing/session/context.go @@ -15,6 +15,10 @@ type Context struct { Content *session.Content } +func (ctx *Context) GetTag() string { + return "" +} + // GetInboundTag implements routing.Context. func (ctx *Context) GetInboundTag() string { if ctx.Inbound == nil { diff --git a/infra/conf/api.go b/infra/conf/api.go index 02bc77dc22c2..0ee0b087d4e0 100644 --- a/infra/conf/api.go +++ b/infra/conf/api.go @@ -6,6 +6,7 @@ import ( "github.com/xtls/xray-core/app/commander" loggerservice "github.com/xtls/xray-core/app/log/command" handlerservice "github.com/xtls/xray-core/app/proxyman/command" + routingservice "github.com/xtls/xray-core/app/router/command" statsservice "github.com/xtls/xray-core/app/stats/command" "github.com/xtls/xray-core/common/serial" ) @@ -27,6 +28,8 @@ func (c *APIConfig) Build() (*commander.Config, error) { services = append(services, serial.ToTypedMessage(&commander.ReflectionConfig{})) case "handlerservice": services = append(services, serial.ToTypedMessage(&handlerservice.Config{})) + case "routingservice": + services = append(services, serial.ToTypedMessage(&routingservice.Config{})) case "loggerservice": services = append(services, serial.ToTypedMessage(&loggerservice.Config{})) case "statsservice": diff --git a/infra/conf/router.go b/infra/conf/router.go index a93da6b11500..0d5c8e28050e 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -470,6 +470,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { InboundTag *StringList `json:"inboundTag"` Protocols *StringList `json:"protocol"` Attributes string `json:"attrs"` + Tag string `json:"tag"` } rawFieldRule := new(RawFieldRule) err := json.Unmarshal(msg, rawFieldRule) @@ -480,8 +481,8 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { rule := new(router.RoutingRule) switch { case len(rawFieldRule.OutboundTag) > 0: - rule.TargetTag = &router.RoutingRule_Tag{ - Tag: rawFieldRule.OutboundTag, + rule.TargetTag = &router.RoutingRule_OutboundTag{ + OutboundTag: rawFieldRule.OutboundTag, } case len(rawFieldRule.BalancerTag) > 0: rule.TargetTag = &router.RoutingRule_BalancingTag{ @@ -561,6 +562,10 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { rule.Attributes = rawFieldRule.Attributes } + if len(rawFieldRule.Tag) > 0 { + rule.Tag = rawFieldRule.Tag + } + return rule, nil } @@ -605,8 +610,8 @@ func parseChinaIPRule(data []byte) (*router.RoutingRule, error) { return nil, newError("failed to load geoip:cn").Base(err) } return &router.RoutingRule{ - TargetTag: &router.RoutingRule_Tag{ - Tag: rawRule.OutboundTag, + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: rawRule.OutboundTag, }, Cidr: chinaIPs, }, nil @@ -623,8 +628,8 @@ func parseChinaSitesRule(data []byte) (*router.RoutingRule, error) { return nil, newError("failed to load geosite:cn.").Base(err) } return &router.RoutingRule{ - TargetTag: &router.RoutingRule_Tag{ - Tag: rawRule.OutboundTag, + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: rawRule.OutboundTag, }, Domain: domains, }, nil diff --git a/infra/conf/router_test.go b/infra/conf/router_test.go index bb4fdc7d41a6..6b9b2c331f5a 100644 --- a/infra/conf/router_test.go +++ b/infra/conf/router_test.go @@ -83,8 +83,8 @@ func TestRouterConfig(t *testing.T) { Value: "qq.com", }, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "direct", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "direct", }, }, { @@ -102,8 +102,8 @@ func TestRouterConfig(t *testing.T) { }, }, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "test", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "test", }, }, { @@ -114,8 +114,8 @@ func TestRouterConfig(t *testing.T) { {From: 1000, To: 2000}, }, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "test", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "test", }, }, { @@ -124,8 +124,8 @@ func TestRouterConfig(t *testing.T) { {From: 123, To: 123}, }, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "test", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "test", }, }, }, @@ -171,8 +171,8 @@ func TestRouterConfig(t *testing.T) { Value: "qq.com", }, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "direct", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "direct", }, }, { @@ -190,8 +190,8 @@ func TestRouterConfig(t *testing.T) { }, }, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "test", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "test", }, }, }, @@ -234,8 +234,8 @@ func TestRouterConfig(t *testing.T) { Value: "qq.com", }, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "direct", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "direct", }, }, { @@ -253,8 +253,8 @@ func TestRouterConfig(t *testing.T) { }, }, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "test", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "test", }, }, }, diff --git a/infra/conf/xray_test.go b/infra/conf/xray_test.go index d4f0ba6b51fa..acaef65f1aef 100644 --- a/infra/conf/xray_test.go +++ b/infra/conf/xray_test.go @@ -164,8 +164,8 @@ func TestXrayConfig(t *testing.T) { }, }, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "blocked", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "blocked", }, }, }, diff --git a/testing/scenarios/command_test.go b/testing/scenarios/command_test.go index 7e5f1ef82b0b..7e21babd342c 100644 --- a/testing/scenarios/command_test.go +++ b/testing/scenarios/command_test.go @@ -55,8 +55,8 @@ func TestCommanderRemoveHandler(t *testing.T) { Rule: []*router.RoutingRule{ { InboundTag: []string{"api"}, - TargetTag: &router.RoutingRule_Tag{ - Tag: "api", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "api", }, }, }, @@ -153,8 +153,8 @@ func TestCommanderAddRemoveUser(t *testing.T) { Rule: []*router.RoutingRule{ { InboundTag: []string{"api"}, - TargetTag: &router.RoutingRule_Tag{ - Tag: "api", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "api", }, }, }, @@ -335,8 +335,8 @@ func TestCommanderStats(t *testing.T) { Rule: []*router.RoutingRule{ { InboundTag: []string{"api"}, - TargetTag: &router.RoutingRule_Tag{ - Tag: "api", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "api", }, }, }, diff --git a/testing/scenarios/dns_test.go b/testing/scenarios/dns_test.go index 886068d769e0..2357911a18d9 100644 --- a/testing/scenarios/dns_test.go +++ b/testing/scenarios/dns_test.go @@ -45,8 +45,8 @@ func TestResolveIP(t *testing.T) { Prefix: 8, }, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "direct", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "direct", }, }, }, diff --git a/testing/scenarios/feature_test.go b/testing/scenarios/feature_test.go index 3977606da609..3c4d7582842c 100644 --- a/testing/scenarios/feature_test.go +++ b/testing/scenarios/feature_test.go @@ -427,8 +427,8 @@ func TestBlackhole(t *testing.T) { serial.ToTypedMessage(&router.Config{ Rule: []*router.RoutingRule{ { - TargetTag: &router.RoutingRule_Tag{ - Tag: "blocked", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "blocked", }, PortRange: net.SinglePortRange(dest2.Port), }, @@ -602,13 +602,13 @@ func TestDomainSniffing(t *testing.T) { serial.ToTypedMessage(&router.Config{ Rule: []*router.RoutingRule{ { - TargetTag: &router.RoutingRule_Tag{ - Tag: "direct", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "direct", }, InboundTag: []string{"snif"}, }, { - TargetTag: &router.RoutingRule_Tag{ - Tag: "redir", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "redir", }, InboundTag: []string{"http"}, }, diff --git a/testing/scenarios/reverse_test.go b/testing/scenarios/reverse_test.go index cbe9abdf6004..ac824fd70800 100644 --- a/testing/scenarios/reverse_test.go +++ b/testing/scenarios/reverse_test.go @@ -56,14 +56,14 @@ func TestReverseProxy(t *testing.T) { Domain: []*router.Domain{ {Type: router.Domain_Full, Value: "test.example.com"}, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "portal", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "portal", }, }, { InboundTag: []string{"external"}, - TargetTag: &router.RoutingRule_Tag{ - Tag: "portal", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "portal", }, }, }, @@ -125,14 +125,14 @@ func TestReverseProxy(t *testing.T) { Domain: []*router.Domain{ {Type: router.Domain_Full, Value: "test.example.com"}, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "reverse", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "reverse", }, }, { InboundTag: []string{"bridge"}, - TargetTag: &router.RoutingRule_Tag{ - Tag: "freedom", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "freedom", }, }, }, @@ -241,14 +241,14 @@ func TestReverseProxyLongRunning(t *testing.T) { Domain: []*router.Domain{ {Type: router.Domain_Full, Value: "test.example.com"}, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "portal", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "portal", }, }, { InboundTag: []string{"external"}, - TargetTag: &router.RoutingRule_Tag{ - Tag: "portal", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "portal", }, }, }, @@ -324,14 +324,14 @@ func TestReverseProxyLongRunning(t *testing.T) { Domain: []*router.Domain{ {Type: router.Domain_Full, Value: "test.example.com"}, }, - TargetTag: &router.RoutingRule_Tag{ - Tag: "reverse", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "reverse", }, }, { InboundTag: []string{"bridge"}, - TargetTag: &router.RoutingRule_Tag{ - Tag: "freedom", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "freedom", }, }, }, diff --git a/testing/scenarios/socks_test.go b/testing/scenarios/socks_test.go index 72da1d84d74d..e41ffad19a47 100644 --- a/testing/scenarios/socks_test.go +++ b/testing/scenarios/socks_test.go @@ -198,8 +198,8 @@ func TestSocksBridageUDPWithRouting(t *testing.T) { serial.ToTypedMessage(&router.Config{ Rule: []*router.RoutingRule{ { - TargetTag: &router.RoutingRule_Tag{ - Tag: "out", + TargetTag: &router.RoutingRule_OutboundTag{ + OutboundTag: "out", }, InboundTag: []string{"socks"}, }, From 82aa6b358e65524d02de777190f2aa8f77c25e11 Mon Sep 17 00:00:00 2001 From: tat5522 <81008809+tat5522@users.noreply.github.com> Date: Sat, 20 Mar 2021 21:31:57 +0800 Subject: [PATCH 2/9] Fix the balancing that did not update the routing rule binding when the balance was changed --- app/router/router.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/app/router/router.go b/app/router/router.go index aaf42f8ef668..c60de860568a 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -135,7 +135,7 @@ func (r *Router) AddRoutingRule(ctx context.Context, routingRule interface{}) er defer r.access.Unlock() r.rules[rule.Tag] = rule - newError("Rule has been added through the API. [", rule.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) + newError("RoutingRule has been added through the API. [", rule.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) return nil } @@ -157,7 +157,7 @@ func (r *Router) AlterRoutingRule(ctx context.Context, tag string, routingRule i rule.Tag = tag r.rules[tag] = rule - newError("The rules have been modified through the API. [", rule.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) + newError("The RoutingRule have been modified through the API. [", rule.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) return nil } @@ -170,7 +170,7 @@ func (r *Router) RemoveRoutingRule(ctx context.Context, tag string) error { defer r.access.Unlock() delete(r.rules, tag) - newError("The rule has been removed through the API. [", tag, "]").WriteToLog(session.ExportIDToError(ctx)) + newError("The RoutingRule has been removed through the API. [", tag, "]").WriteToLog(session.ExportIDToError(ctx)) return nil } @@ -185,7 +185,7 @@ func (r *Router) AddBalancingRule(ctx context.Context, balancingRule interface{} defer r.access.Unlock() r.balancers[br.Tag] = balancer - newError("Rule has been added through the API. [", br.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) + newError("BalancingRule has been added through the API. [", br.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) return nil } @@ -203,8 +203,15 @@ func (r *Router) AlterBalancingRule(ctx context.Context, tag string, balancingRu r.access.Lock() defer r.access.Unlock() + // Update RoutingRle bind Balancing + for _, v := range r.rules { + if v.Balancer == r.balancers[tag] { + v.Balancer = balancer + } + } + r.balancers[tag] = balancer - newError("The rules have been modified through the API. [", tag, "]").WriteToLog(session.ExportIDToError(ctx)) + newError("The BalancingRule have been modified through the API. [", tag, "]").WriteToLog(session.ExportIDToError(ctx)) return nil } @@ -216,8 +223,15 @@ func (r *Router) RemoveBalancingRule(ctx context.Context, tag string) error { r.access.Lock() defer r.access.Unlock() + // Update RoutingRle bind Balancing + for _, v := range r.rules { + if v.Balancer == r.balancers[tag] { + v.Balancer = nil + } + } + delete(r.balancers, tag) - newError("The rule has been removed through the API. [", tag, "]").WriteToLog(session.ExportIDToError(ctx)) + newError("The BalancingRule has been removed through the API. [", tag, "]").WriteToLog(session.ExportIDToError(ctx)) return nil } From 5f78bea8bf8ae00dd8f60252d8de6c49c126cf85 Mon Sep 17 00:00:00 2001 From: tat5522 <81008809+tat5522@users.noreply.github.com> Date: Sat, 20 Mar 2021 22:49:12 +0800 Subject: [PATCH 3/9] Fix router_test imported but not used --- app/router/router_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/app/router/router_test.go b/app/router/router_test.go index 468a311584e1..7a678fc679dc 100644 --- a/app/router/router_test.go +++ b/app/router/router_test.go @@ -2,7 +2,6 @@ package router_test import ( "context" - "github.com/xtls/xray-core/core" "testing" "github.com/golang/mock/gomock" From 2403673537e3b0587c15e2c3bfb98880f7983a3a Mon Sep 17 00:00:00 2001 From: tat5522 <81008809+tat5522@users.noreply.github.com> Date: Sun, 21 Mar 2021 00:44:08 +0800 Subject: [PATCH 4/9] Router Rules from Map type change to slice --- app/router/command/command.go | 2 +- app/router/config.go | 13 +++------- app/router/router.go | 48 +++++++++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/app/router/command/command.go b/app/router/command/command.go index 1b7fc9b0836a..a2613e4fdb4d 100644 --- a/app/router/command/command.go +++ b/app/router/command/command.go @@ -4,13 +4,13 @@ package command import ( "context" - "github.com/xtls/xray-core/features/outbound" "time" "google.golang.org/grpc" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/core" + "github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/features/routing" "github.com/xtls/xray-core/features/stats" ) diff --git a/app/router/config.go b/app/router/config.go index 196eaff92b92..37cf1a95c5d0 100644 --- a/app/router/config.go +++ b/app/router/config.go @@ -150,19 +150,14 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) { // Build RoutingRule translates into Rule. func (rr *RoutingRule) Build(r *Router) (*Rule, error) { tag := rr.Tag + if len(tag) == 0 { + u := uuid.New() + tag = u.String() + } rule := &Rule{ Tag: tag, } - if len(rule.Tag) > 0 { - if _, found := r.rules[tag]; found { - return nil, newError("existing tag found: " + tag) - } - } else { - u := uuid.New() - rule.Tag = u.String() - } - btag := rr.GetBalancingTag() if len(btag) > 0 { brule, found := r.balancers[btag] diff --git a/app/router/router.go b/app/router/router.go index c60de860568a..fae1faca57e7 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -4,6 +4,8 @@ package router import ( "context" + "sync" + "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/common/uuid" @@ -12,14 +14,13 @@ import ( "github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/features/routing" routing_dns "github.com/xtls/xray-core/features/routing/dns" - "sync" ) // Router is an implementation of routing.Router. type Router struct { access sync.RWMutex domainStrategy Config_DomainStrategy - rules map[string]*Rule + rules []*Rule balancers map[string]*Balancer dns dns.Client Tag string @@ -48,7 +49,7 @@ func (r *Router) Init(config *Config, d dns.Client, ohm outbound.Manager) error r.balancers[rule.Tag] = balancer } - r.rules = make(map[string]*Rule) + r.rules = make([]*Rule, 0, len(config.Rule)) for _, rule := range config.Rule { cond, err := rule.BuildCondition() if err != nil { @@ -75,7 +76,7 @@ func (r *Router) Init(config *Config, d dns.Client, ohm outbound.Manager) error rr.Tag = u.String() } - r.rules[rr.Tag] = rr + r.rules = append(r.rules, rr) } return nil @@ -124,9 +125,29 @@ func (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routing.Context, return nil, ctx, common.ErrNoClue } +// FindRule +func (r *Router) FindRule(tag string) (idx int, rule *Rule) { + idx = -1 + for k, v := range r.rules { + if v.Tag == tag { + idx = k + rule = v + } + } + return +} + // AddRoutingRule implement the manager interface. func (r *Router) AddRoutingRule(ctx context.Context, routingRule interface{}) error { rr := routingRule.(*RoutingRule) + + if len(rr.Tag) > 0 { + idx, _ := r.FindRule(rr.Tag) + if idx != -1 { + return newError("existing tag found: " + rr.Tag) + } + } + rule, err := rr.Build(r) if err != nil { return err @@ -134,14 +155,15 @@ func (r *Router) AddRoutingRule(ctx context.Context, routingRule interface{}) er r.access.Lock() defer r.access.Unlock() - r.rules[rule.Tag] = rule + r.rules = append(r.rules, rule) newError("RoutingRule has been added through the API. [", rule.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) return nil } // AlterRoutingRule implement the manager interface. func (r *Router) AlterRoutingRule(ctx context.Context, tag string, routingRule interface{}) error { - if _, found := r.rules[tag]; !found { + idx, rule := r.FindRule(tag) + if idx == -1 { return newError("tag not found: " + tag) } @@ -156,27 +178,33 @@ func (r *Router) AlterRoutingRule(ctx context.Context, tag string, routingRule i defer r.access.Unlock() rule.Tag = tag - r.rules[tag] = rule + r.rules[idx] = rule newError("The RoutingRule have been modified through the API. [", rule.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) return nil } // RemoveRoutingRule implement the manager interface. func (r *Router) RemoveRoutingRule(ctx context.Context, tag string) error { - if _, found := r.rules[tag]; !found { + idx, rule := r.FindRule(tag) + if idx == -1 { return newError("tag not found: " + tag) } r.access.Lock() defer r.access.Unlock() - delete(r.rules, tag) - newError("The RoutingRule has been removed through the API. [", tag, "]").WriteToLog(session.ExportIDToError(ctx)) + // remove rule + r.rules = append(r.rules[:idx], r.rules[idx+1:]...) + newError("The RoutingRule has been removed through the API. [", rule.Tag, "] ").WriteToLog(session.ExportIDToError(ctx)) return nil } // AddBalancingRule implement the manager interface. func (r *Router) AddBalancingRule(ctx context.Context, balancingRule interface{}, om outbound.Manager) error { br := balancingRule.(*BalancingRule) + if _, found := r.balancers[br.Tag]; found { + return newError("existing tag found: " + br.Tag) + } + balancer, err := br.Build(om) if err != nil { return err From 3b112d90bbf4ee00a8cb19a52fe5e102872e13c6 Mon Sep 17 00:00:00 2001 From: tat5522 <81008809+tat5522@users.noreply.github.com> Date: Mon, 22 Mar 2021 20:39:41 +0800 Subject: [PATCH 5/9] Routing API change name and AddRule support index insert. --- app/router/command/command.go | 48 +- app/router/command/command.pb.go | 839 +++++++++++++++++++++----- app/router/command/command.proto | 48 +- app/router/command/command_grpc.pb.go | 292 ++++++--- app/router/command/command_test.go | 12 +- app/router/router.go | 78 ++- app/router/router_test.go | 6 +- features/routing/router.go | 77 ++- 8 files changed, 1099 insertions(+), 301 deletions(-) diff --git a/app/router/command/command.go b/app/router/command/command.go index a2613e4fdb4d..4b3638285611 100644 --- a/app/router/command/command.go +++ b/app/router/command/command.go @@ -46,18 +46,20 @@ func (s *routingServer) TestRoute(ctx context.Context, request *TestRouteRequest return AsProtobufMessage(request.FieldSelectors)(route), nil } -func (s *routingServer) AddRoutingRule(ctx context.Context, request *AddRoutingRuleRequest) (*AddRoutingRuleResponse, error) { +func (s *routingServer) AddRule(ctx context.Context, request *AddRoutingRuleRequest) (*AddRoutingRuleResponse, error) { + resp := new(AddRoutingRuleResponse) if request.RoutingRule == nil { - return nil, newError("Invalid RoutingRule request.") + return resp, newError("Invalid RoutingRule request.") } - err := s.router.AddRoutingRule(ctx, request.RoutingRule) + + err := s.router.AddRule(ctx, request.Index, request.RoutingRule) if err != nil { - return nil, err + return resp, err } - return &AddRoutingRuleResponse{}, nil + return resp, nil } -func (s *routingServer) AlterRoutingRule(ctx context.Context, request *AlterRoutingRuleRequest) (*AlterRoutingRuleResponse, error) { +func (s *routingServer) AlterRule(ctx context.Context, request *AlterRoutingRuleRequest) (*AlterRoutingRuleResponse, error) { if request.RoutingRule == nil { return nil, newError("Invalid RoutingRule request.") } @@ -66,37 +68,49 @@ func (s *routingServer) AlterRoutingRule(ctx context.Context, request *AlterRout return nil, newError("Invalid Tag.") } - err := s.router.AlterRoutingRule(ctx, request.Tag, request.RoutingRule) + err := s.router.AlterRule(ctx, request.Tag, request.RoutingRule) if err != nil { return nil, err } return &AlterRoutingRuleResponse{}, nil } -func (s *routingServer) RemoveRoutingRule(ctx context.Context, request *RemoveRoutingRuleRequest) (*RemoveRoutingRuleResponse, error) { +func (s *routingServer) RemoveRule(ctx context.Context, request *RemoveRoutingRuleRequest) (*RemoveRoutingRuleResponse, error) { if len(request.Tag) == 0 { return nil, newError("Invalid Tag.") } - err := s.router.RemoveRoutingRule(ctx, request.Tag) + err := s.router.RemoveRule(ctx, request.Tag) if err != nil { return nil, err } return &RemoveRoutingRuleResponse{}, nil } -func (s *routingServer) AddBalancingRule(ctx context.Context, request *AddBalancingRuleRequest) (*AddBalancingRuleResponse, error) { +func (s *routingServer) SetRules(ctx context.Context, rules *SetRoutingRulesRequest) (*SetRoutingRulesResponse, error) { + return nil, newError("not implement.") +} + +func (s *routingServer) GetRules(ctx context.Context, request *GetRoutingRulesRequest) (*GetRoutingRulesResponse, error) { + return nil, newError("not implement.") +} + +func (s *routingServer) GetRule(ctx context.Context, request *GetRoutingRuleRequest) (*GetRoutingRuleResponse, error) { + return nil, newError("not implement.") +} + +func (s *routingServer) AddBalancer(ctx context.Context, request *AddBalancingRuleRequest) (*AddBalancingRuleResponse, error) { if request.Balancing == nil { return nil, newError("Invalid Balancing request.") } - err := s.router.AddBalancingRule(ctx, request.Balancing, s.ohm) + err := s.router.AddBalancer(ctx, request.Balancing, s.ohm) if err != nil { return nil, err } return &AddBalancingRuleResponse{}, nil } -func (s *routingServer) AlterBalancingRule(ctx context.Context, request *AlterBalancingRuleRequest) (*AlterBalancingRuleResponse, error) { +func (s *routingServer) AlterBalancer(ctx context.Context, request *AlterBalancingRuleRequest) (*AlterBalancingRuleResponse, error) { if request.Balancing == nil { return nil, newError("Invalid Balancing request.") } @@ -104,24 +118,28 @@ func (s *routingServer) AlterBalancingRule(ctx context.Context, request *AlterBa if len(request.Tag) == 0 { return nil, newError("Invalid Tag.") } - err := s.router.AlterBalancingRule(ctx, request.Tag, request.Balancing, s.ohm) + err := s.router.AlterBalancer(ctx, request.Tag, request.Balancing, s.ohm) if err != nil { return nil, err } return &AlterBalancingRuleResponse{}, nil } -func (s *routingServer) RemoveBalancingRule(ctx context.Context, request *RemoveBalancingRuleRequest) (*RemoveBalancingRuleResponse, error) { +func (s *routingServer) RemoveBalancer(ctx context.Context, request *RemoveBalancingRuleRequest) (*RemoveBalancingRuleResponse, error) { if len(request.Tag) == 0 { return nil, newError("Invalid Tag.") } - err := s.router.RemoveBalancingRule(ctx, request.Tag) + err := s.router.RemoveBalancer(ctx, request.Tag) if err != nil { return nil, err } return &RemoveBalancingRuleResponse{}, nil } +func (s *routingServer) GetBalancers(ctx context.Context, request *GetBalancerRequest) (*GetBalancerResponse, error) { + return nil, newError("not implement.") +} + func (s *routingServer) SubscribeRoutingStats(request *SubscribeRoutingStatsRequest, stream RoutingService_SubscribeRoutingStatsServer) error { if s.routingStats == nil { return newError("Routing statistics not enabled.") diff --git a/app/router/command/command.pb.go b/app/router/command/command.pb.go index ff8eaf975741..e25a187f8451 100644 --- a/app/router/command/command.pb.go +++ b/app/router/command/command.pb.go @@ -308,6 +308,7 @@ type AddRoutingRuleRequest struct { unknownFields protoimpl.UnknownFields RoutingRule *router.RoutingRule `protobuf:"bytes,1,opt,name=routingRule,proto3" json:"routingRule,omitempty"` + Index int32 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"` } func (x *AddRoutingRuleRequest) Reset() { @@ -349,6 +350,13 @@ func (x *AddRoutingRuleRequest) GetRoutingRule() *router.RoutingRule { return nil } +func (x *AddRoutingRuleRequest) GetIndex() int32 { + if x != nil { + return x.Index + } + return 0 +} + type AddRoutingRuleResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -565,6 +573,261 @@ func (*RemoveRoutingRuleResponse) Descriptor() ([]byte, []int) { return file_app_router_command_command_proto_rawDescGZIP(), []int{8} } +type SetRoutingRulesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rules []*router.RoutingRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` +} + +func (x *SetRoutingRulesRequest) Reset() { + *x = SetRoutingRulesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetRoutingRulesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetRoutingRulesRequest) ProtoMessage() {} + +func (x *SetRoutingRulesRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetRoutingRulesRequest.ProtoReflect.Descriptor instead. +func (*SetRoutingRulesRequest) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{9} +} + +func (x *SetRoutingRulesRequest) GetRules() []*router.RoutingRule { + if x != nil { + return x.Rules + } + return nil +} + +type SetRoutingRulesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SetRoutingRulesResponse) Reset() { + *x = SetRoutingRulesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetRoutingRulesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetRoutingRulesResponse) ProtoMessage() {} + +func (x *SetRoutingRulesResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetRoutingRulesResponse.ProtoReflect.Descriptor instead. +func (*SetRoutingRulesResponse) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{10} +} + +type GetRoutingRulesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetRoutingRulesRequest) Reset() { + *x = GetRoutingRulesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetRoutingRulesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRoutingRulesRequest) ProtoMessage() {} + +func (x *GetRoutingRulesRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetRoutingRulesRequest.ProtoReflect.Descriptor instead. +func (*GetRoutingRulesRequest) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{11} +} + +type GetRoutingRulesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rules []*router.RoutingRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` +} + +func (x *GetRoutingRulesResponse) Reset() { + *x = GetRoutingRulesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetRoutingRulesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRoutingRulesResponse) ProtoMessage() {} + +func (x *GetRoutingRulesResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetRoutingRulesResponse.ProtoReflect.Descriptor instead. +func (*GetRoutingRulesResponse) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{12} +} + +func (x *GetRoutingRulesResponse) GetRules() []*router.RoutingRule { + if x != nil { + return x.Rules + } + return nil +} + +type GetRoutingRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetRoutingRuleRequest) Reset() { + *x = GetRoutingRuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetRoutingRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRoutingRuleRequest) ProtoMessage() {} + +func (x *GetRoutingRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetRoutingRuleRequest.ProtoReflect.Descriptor instead. +func (*GetRoutingRuleRequest) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{13} +} + +type GetRoutingRuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rule *router.RoutingRule `protobuf:"bytes,1,opt,name=rule,proto3" json:"rule,omitempty"` +} + +func (x *GetRoutingRuleResponse) Reset() { + *x = GetRoutingRuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetRoutingRuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRoutingRuleResponse) ProtoMessage() {} + +func (x *GetRoutingRuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetRoutingRuleResponse.ProtoReflect.Descriptor instead. +func (*GetRoutingRuleResponse) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{14} +} + +func (x *GetRoutingRuleResponse) GetRule() *router.RoutingRule { + if x != nil { + return x.Rule + } + return nil +} + type AddBalancingRuleRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -576,7 +839,7 @@ type AddBalancingRuleRequest struct { func (x *AddBalancingRuleRequest) Reset() { *x = AddBalancingRuleRequest{} if protoimpl.UnsafeEnabled { - mi := &file_app_router_command_command_proto_msgTypes[9] + mi := &file_app_router_command_command_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -589,7 +852,7 @@ func (x *AddBalancingRuleRequest) String() string { func (*AddBalancingRuleRequest) ProtoMessage() {} func (x *AddBalancingRuleRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_router_command_command_proto_msgTypes[9] + mi := &file_app_router_command_command_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -602,7 +865,7 @@ func (x *AddBalancingRuleRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddBalancingRuleRequest.ProtoReflect.Descriptor instead. func (*AddBalancingRuleRequest) Descriptor() ([]byte, []int) { - return file_app_router_command_command_proto_rawDescGZIP(), []int{9} + return file_app_router_command_command_proto_rawDescGZIP(), []int{15} } func (x *AddBalancingRuleRequest) GetBalancing() *router.BalancingRule { @@ -621,7 +884,7 @@ type AddBalancingRuleResponse struct { func (x *AddBalancingRuleResponse) Reset() { *x = AddBalancingRuleResponse{} if protoimpl.UnsafeEnabled { - mi := &file_app_router_command_command_proto_msgTypes[10] + mi := &file_app_router_command_command_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -634,7 +897,7 @@ func (x *AddBalancingRuleResponse) String() string { func (*AddBalancingRuleResponse) ProtoMessage() {} func (x *AddBalancingRuleResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_router_command_command_proto_msgTypes[10] + mi := &file_app_router_command_command_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -647,7 +910,7 @@ func (x *AddBalancingRuleResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AddBalancingRuleResponse.ProtoReflect.Descriptor instead. func (*AddBalancingRuleResponse) Descriptor() ([]byte, []int) { - return file_app_router_command_command_proto_rawDescGZIP(), []int{10} + return file_app_router_command_command_proto_rawDescGZIP(), []int{16} } type AlterBalancingRuleRequest struct { @@ -662,7 +925,7 @@ type AlterBalancingRuleRequest struct { func (x *AlterBalancingRuleRequest) Reset() { *x = AlterBalancingRuleRequest{} if protoimpl.UnsafeEnabled { - mi := &file_app_router_command_command_proto_msgTypes[11] + mi := &file_app_router_command_command_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -675,7 +938,7 @@ func (x *AlterBalancingRuleRequest) String() string { func (*AlterBalancingRuleRequest) ProtoMessage() {} func (x *AlterBalancingRuleRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_router_command_command_proto_msgTypes[11] + mi := &file_app_router_command_command_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -688,7 +951,7 @@ func (x *AlterBalancingRuleRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AlterBalancingRuleRequest.ProtoReflect.Descriptor instead. func (*AlterBalancingRuleRequest) Descriptor() ([]byte, []int) { - return file_app_router_command_command_proto_rawDescGZIP(), []int{11} + return file_app_router_command_command_proto_rawDescGZIP(), []int{17} } func (x *AlterBalancingRuleRequest) GetTag() string { @@ -714,7 +977,7 @@ type AlterBalancingRuleResponse struct { func (x *AlterBalancingRuleResponse) Reset() { *x = AlterBalancingRuleResponse{} if protoimpl.UnsafeEnabled { - mi := &file_app_router_command_command_proto_msgTypes[12] + mi := &file_app_router_command_command_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -727,7 +990,7 @@ func (x *AlterBalancingRuleResponse) String() string { func (*AlterBalancingRuleResponse) ProtoMessage() {} func (x *AlterBalancingRuleResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_router_command_command_proto_msgTypes[12] + mi := &file_app_router_command_command_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -740,7 +1003,7 @@ func (x *AlterBalancingRuleResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AlterBalancingRuleResponse.ProtoReflect.Descriptor instead. func (*AlterBalancingRuleResponse) Descriptor() ([]byte, []int) { - return file_app_router_command_command_proto_rawDescGZIP(), []int{12} + return file_app_router_command_command_proto_rawDescGZIP(), []int{18} } type RemoveBalancingRuleRequest struct { @@ -754,7 +1017,7 @@ type RemoveBalancingRuleRequest struct { func (x *RemoveBalancingRuleRequest) Reset() { *x = RemoveBalancingRuleRequest{} if protoimpl.UnsafeEnabled { - mi := &file_app_router_command_command_proto_msgTypes[13] + mi := &file_app_router_command_command_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -767,7 +1030,7 @@ func (x *RemoveBalancingRuleRequest) String() string { func (*RemoveBalancingRuleRequest) ProtoMessage() {} func (x *RemoveBalancingRuleRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_router_command_command_proto_msgTypes[13] + mi := &file_app_router_command_command_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -780,7 +1043,7 @@ func (x *RemoveBalancingRuleRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveBalancingRuleRequest.ProtoReflect.Descriptor instead. func (*RemoveBalancingRuleRequest) Descriptor() ([]byte, []int) { - return file_app_router_command_command_proto_rawDescGZIP(), []int{13} + return file_app_router_command_command_proto_rawDescGZIP(), []int{19} } func (x *RemoveBalancingRuleRequest) GetTag() string { @@ -799,7 +1062,7 @@ type RemoveBalancingRuleResponse struct { func (x *RemoveBalancingRuleResponse) Reset() { *x = RemoveBalancingRuleResponse{} if protoimpl.UnsafeEnabled { - mi := &file_app_router_command_command_proto_msgTypes[14] + mi := &file_app_router_command_command_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -812,7 +1075,7 @@ func (x *RemoveBalancingRuleResponse) String() string { func (*RemoveBalancingRuleResponse) ProtoMessage() {} func (x *RemoveBalancingRuleResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_router_command_command_proto_msgTypes[14] + mi := &file_app_router_command_command_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -825,7 +1088,92 @@ func (x *RemoveBalancingRuleResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveBalancingRuleResponse.ProtoReflect.Descriptor instead. func (*RemoveBalancingRuleResponse) Descriptor() ([]byte, []int) { - return file_app_router_command_command_proto_rawDescGZIP(), []int{14} + return file_app_router_command_command_proto_rawDescGZIP(), []int{20} +} + +type GetBalancerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetBalancerRequest) Reset() { + *x = GetBalancerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBalancerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBalancerRequest) ProtoMessage() {} + +func (x *GetBalancerRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBalancerRequest.ProtoReflect.Descriptor instead. +func (*GetBalancerRequest) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{21} +} + +type GetBalancerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Balancing []*router.BalancingRule `protobuf:"bytes,2,rep,name=balancing,proto3" json:"balancing,omitempty"` +} + +func (x *GetBalancerResponse) Reset() { + *x = GetBalancerResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_app_router_command_command_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBalancerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBalancerResponse) ProtoMessage() {} + +func (x *GetBalancerResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_router_command_command_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBalancerResponse.ProtoReflect.Descriptor instead. +func (*GetBalancerResponse) Descriptor() ([]byte, []int) { + return file_app_router_command_command_proto_rawDescGZIP(), []int{22} +} + +func (x *GetBalancerResponse) GetBalancing() []*router.BalancingRule { + if x != nil { + return x.Balancing + } + return nil } type Config struct { @@ -837,7 +1185,7 @@ type Config struct { func (x *Config) Reset() { *x = Config{} if protoimpl.UnsafeEnabled { - mi := &file_app_router_command_command_proto_msgTypes[15] + mi := &file_app_router_command_command_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -850,7 +1198,7 @@ func (x *Config) String() string { func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { - mi := &file_app_router_command_command_proto_msgTypes[15] + mi := &file_app_router_command_command_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -863,7 +1211,7 @@ func (x *Config) ProtoReflect() protoreflect.Message { // Deprecated: Use Config.ProtoReflect.Descriptor instead. func (*Config) Descriptor() ([]byte, []int) { - return file_app_router_command_command_proto_rawDescGZIP(), []int{15} + return file_app_router_command_command_proto_rawDescGZIP(), []int{23} } var File_app_router_command_command_proto protoreflect.FileDescriptor @@ -926,111 +1274,164 @@ var file_app_router_command_command_proto_rawDesc = []byte{ 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x57, 0x0a, 0x15, 0x41, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x6d, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x52, 0x75, 0x6c, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, - 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6b, - 0x0a, 0x17, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x18, 0x0a, 0x16, 0x41, 0x64, + 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6b, 0x0a, 0x17, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, + 0x67, 0x12, 0x3e, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x0a, + 0x18, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x3e, 0x0a, 0x0b, 0x72, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0b, - 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x41, - 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x18, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0x1b, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x57, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, - 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, - 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, - 0x52, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x22, 0x1a, 0x0a, 0x18, 0x41, - 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6b, 0x0a, 0x19, 0x41, 0x6c, 0x74, 0x65, 0x72, - 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x3c, 0x0a, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x69, 0x6e, 0x67, 0x22, 0x1c, 0x0a, 0x1a, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x2e, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, - 0x61, 0x67, 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x08, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x32, 0xdf, 0x07, 0x0a, 0x0e, - 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7b, - 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, - 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x35, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, - 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, - 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0x1b, 0x0a, 0x19, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4c, 0x0a, 0x16, 0x53, 0x65, 0x74, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x32, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4d, 0x0a, 0x17, 0x47, + 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, + 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x4a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, + 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, + 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x22, + 0x57, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x09, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, + 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x09, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x42, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6b, 0x0a, 0x19, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x74, 0x61, 0x67, 0x12, 0x3c, 0x0a, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, + 0x67, 0x22, 0x1c, 0x0a, 0x1a, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x2e, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, + 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, + 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x53, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x09, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x61, 0x0a, 0x09, 0x54, - 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, - 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, 0x12, 0x73, - 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, - 0x12, 0x2e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, - 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, - 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x79, 0x0a, 0x10, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, - 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7c, - 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x12, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x09, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x22, 0x08, 0x0a, 0x06, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x32, 0xf7, 0x0a, 0x0a, 0x0e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7b, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x35, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x00, 0x30, 0x01, 0x12, 0x61, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x12, 0x29, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x78, 0x72, + 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x52, 0x75, 0x6c, + 0x65, 0x12, 0x2e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x09, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x75, 0x6c, + 0x65, 0x12, 0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, + 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, + 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x79, 0x0a, 0x10, - 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, - 0x12, 0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x6f, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x78, 0x72, + 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x6f, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, + 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x6c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2e, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x74, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x30, + 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x42, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, - 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x12, 0x41, 0x6c, 0x74, 0x65, 0x72, - 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x32, 0x2e, + 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x0d, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x7d, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x12, 0x33, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, + 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x6b, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x73, + 0x12, 0x2b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x33, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, - 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x82, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, - 0x12, 0x33, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x67, 0x0a, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x67, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, @@ -1052,7 +1453,7 @@ func file_app_router_command_command_proto_rawDescGZIP() []byte { return file_app_router_command_command_proto_rawDescData } -var file_app_router_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_app_router_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 25) var file_app_router_command_command_proto_goTypes = []interface{}{ (*RoutingContext)(nil), // 0: xray.app.router.command.RoutingContext (*SubscribeRoutingStatsRequest)(nil), // 1: xray.app.router.command.SubscribeRoutingStatsRequest @@ -1063,47 +1464,67 @@ var file_app_router_command_command_proto_goTypes = []interface{}{ (*AlterRoutingRuleResponse)(nil), // 6: xray.app.router.command.AlterRoutingRuleResponse (*RemoveRoutingRuleRequest)(nil), // 7: xray.app.router.command.RemoveRoutingRuleRequest (*RemoveRoutingRuleResponse)(nil), // 8: xray.app.router.command.RemoveRoutingRuleResponse - (*AddBalancingRuleRequest)(nil), // 9: xray.app.router.command.AddBalancingRuleRequest - (*AddBalancingRuleResponse)(nil), // 10: xray.app.router.command.AddBalancingRuleResponse - (*AlterBalancingRuleRequest)(nil), // 11: xray.app.router.command.AlterBalancingRuleRequest - (*AlterBalancingRuleResponse)(nil), // 12: xray.app.router.command.AlterBalancingRuleResponse - (*RemoveBalancingRuleRequest)(nil), // 13: xray.app.router.command.RemoveBalancingRuleRequest - (*RemoveBalancingRuleResponse)(nil), // 14: xray.app.router.command.RemoveBalancingRuleResponse - (*Config)(nil), // 15: xray.app.router.command.Config - nil, // 16: xray.app.router.command.RoutingContext.AttributesEntry - (net.Network)(0), // 17: xray.common.net.Network - (*router.RoutingRule)(nil), // 18: xray.app.router.RoutingRule - (*router.BalancingRule)(nil), // 19: xray.app.router.BalancingRule + (*SetRoutingRulesRequest)(nil), // 9: xray.app.router.command.SetRoutingRulesRequest + (*SetRoutingRulesResponse)(nil), // 10: xray.app.router.command.SetRoutingRulesResponse + (*GetRoutingRulesRequest)(nil), // 11: xray.app.router.command.GetRoutingRulesRequest + (*GetRoutingRulesResponse)(nil), // 12: xray.app.router.command.GetRoutingRulesResponse + (*GetRoutingRuleRequest)(nil), // 13: xray.app.router.command.GetRoutingRuleRequest + (*GetRoutingRuleResponse)(nil), // 14: xray.app.router.command.GetRoutingRuleResponse + (*AddBalancingRuleRequest)(nil), // 15: xray.app.router.command.AddBalancingRuleRequest + (*AddBalancingRuleResponse)(nil), // 16: xray.app.router.command.AddBalancingRuleResponse + (*AlterBalancingRuleRequest)(nil), // 17: xray.app.router.command.AlterBalancingRuleRequest + (*AlterBalancingRuleResponse)(nil), // 18: xray.app.router.command.AlterBalancingRuleResponse + (*RemoveBalancingRuleRequest)(nil), // 19: xray.app.router.command.RemoveBalancingRuleRequest + (*RemoveBalancingRuleResponse)(nil), // 20: xray.app.router.command.RemoveBalancingRuleResponse + (*GetBalancerRequest)(nil), // 21: xray.app.router.command.GetBalancerRequest + (*GetBalancerResponse)(nil), // 22: xray.app.router.command.GetBalancerResponse + (*Config)(nil), // 23: xray.app.router.command.Config + nil, // 24: xray.app.router.command.RoutingContext.AttributesEntry + (net.Network)(0), // 25: xray.common.net.Network + (*router.RoutingRule)(nil), // 26: xray.app.router.RoutingRule + (*router.BalancingRule)(nil), // 27: xray.app.router.BalancingRule } var file_app_router_command_command_proto_depIdxs = []int32{ - 17, // 0: xray.app.router.command.RoutingContext.Network:type_name -> xray.common.net.Network - 16, // 1: xray.app.router.command.RoutingContext.Attributes:type_name -> xray.app.router.command.RoutingContext.AttributesEntry + 25, // 0: xray.app.router.command.RoutingContext.Network:type_name -> xray.common.net.Network + 24, // 1: xray.app.router.command.RoutingContext.Attributes:type_name -> xray.app.router.command.RoutingContext.AttributesEntry 0, // 2: xray.app.router.command.TestRouteRequest.RoutingContext:type_name -> xray.app.router.command.RoutingContext - 18, // 3: xray.app.router.command.AddRoutingRuleRequest.routingRule:type_name -> xray.app.router.RoutingRule - 18, // 4: xray.app.router.command.AlterRoutingRuleRequest.routingRule:type_name -> xray.app.router.RoutingRule - 19, // 5: xray.app.router.command.AddBalancingRuleRequest.balancing:type_name -> xray.app.router.BalancingRule - 19, // 6: xray.app.router.command.AlterBalancingRuleRequest.balancing:type_name -> xray.app.router.BalancingRule - 1, // 7: xray.app.router.command.RoutingService.SubscribeRoutingStats:input_type -> xray.app.router.command.SubscribeRoutingStatsRequest - 2, // 8: xray.app.router.command.RoutingService.TestRoute:input_type -> xray.app.router.command.TestRouteRequest - 3, // 9: xray.app.router.command.RoutingService.AddRoutingRule:input_type -> xray.app.router.command.AddRoutingRuleRequest - 5, // 10: xray.app.router.command.RoutingService.AlterRoutingRule:input_type -> xray.app.router.command.AlterRoutingRuleRequest - 7, // 11: xray.app.router.command.RoutingService.RemoveRoutingRule:input_type -> xray.app.router.command.RemoveRoutingRuleRequest - 9, // 12: xray.app.router.command.RoutingService.AddBalancingRule:input_type -> xray.app.router.command.AddBalancingRuleRequest - 11, // 13: xray.app.router.command.RoutingService.AlterBalancingRule:input_type -> xray.app.router.command.AlterBalancingRuleRequest - 13, // 14: xray.app.router.command.RoutingService.RemoveBalancingRule:input_type -> xray.app.router.command.RemoveBalancingRuleRequest - 0, // 15: xray.app.router.command.RoutingService.SubscribeRoutingStats:output_type -> xray.app.router.command.RoutingContext - 0, // 16: xray.app.router.command.RoutingService.TestRoute:output_type -> xray.app.router.command.RoutingContext - 4, // 17: xray.app.router.command.RoutingService.AddRoutingRule:output_type -> xray.app.router.command.AddRoutingRuleResponse - 6, // 18: xray.app.router.command.RoutingService.AlterRoutingRule:output_type -> xray.app.router.command.AlterRoutingRuleResponse - 8, // 19: xray.app.router.command.RoutingService.RemoveRoutingRule:output_type -> xray.app.router.command.RemoveRoutingRuleResponse - 10, // 20: xray.app.router.command.RoutingService.AddBalancingRule:output_type -> xray.app.router.command.AddBalancingRuleResponse - 12, // 21: xray.app.router.command.RoutingService.AlterBalancingRule:output_type -> xray.app.router.command.AlterBalancingRuleResponse - 14, // 22: xray.app.router.command.RoutingService.RemoveBalancingRule:output_type -> xray.app.router.command.RemoveBalancingRuleResponse - 15, // [15:23] is the sub-list for method output_type - 7, // [7:15] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 26, // 3: xray.app.router.command.AddRoutingRuleRequest.routingRule:type_name -> xray.app.router.RoutingRule + 26, // 4: xray.app.router.command.AlterRoutingRuleRequest.routingRule:type_name -> xray.app.router.RoutingRule + 26, // 5: xray.app.router.command.SetRoutingRulesRequest.rules:type_name -> xray.app.router.RoutingRule + 26, // 6: xray.app.router.command.GetRoutingRulesResponse.rules:type_name -> xray.app.router.RoutingRule + 26, // 7: xray.app.router.command.GetRoutingRuleResponse.rule:type_name -> xray.app.router.RoutingRule + 27, // 8: xray.app.router.command.AddBalancingRuleRequest.balancing:type_name -> xray.app.router.BalancingRule + 27, // 9: xray.app.router.command.AlterBalancingRuleRequest.balancing:type_name -> xray.app.router.BalancingRule + 27, // 10: xray.app.router.command.GetBalancerResponse.balancing:type_name -> xray.app.router.BalancingRule + 1, // 11: xray.app.router.command.RoutingService.SubscribeRoutingStats:input_type -> xray.app.router.command.SubscribeRoutingStatsRequest + 2, // 12: xray.app.router.command.RoutingService.TestRoute:input_type -> xray.app.router.command.TestRouteRequest + 3, // 13: xray.app.router.command.RoutingService.AddRule:input_type -> xray.app.router.command.AddRoutingRuleRequest + 5, // 14: xray.app.router.command.RoutingService.AlterRule:input_type -> xray.app.router.command.AlterRoutingRuleRequest + 7, // 15: xray.app.router.command.RoutingService.RemoveRule:input_type -> xray.app.router.command.RemoveRoutingRuleRequest + 9, // 16: xray.app.router.command.RoutingService.SetRules:input_type -> xray.app.router.command.SetRoutingRulesRequest + 11, // 17: xray.app.router.command.RoutingService.GetRules:input_type -> xray.app.router.command.GetRoutingRulesRequest + 13, // 18: xray.app.router.command.RoutingService.GetRule:input_type -> xray.app.router.command.GetRoutingRuleRequest + 15, // 19: xray.app.router.command.RoutingService.AddBalancer:input_type -> xray.app.router.command.AddBalancingRuleRequest + 17, // 20: xray.app.router.command.RoutingService.AlterBalancer:input_type -> xray.app.router.command.AlterBalancingRuleRequest + 19, // 21: xray.app.router.command.RoutingService.RemoveBalancer:input_type -> xray.app.router.command.RemoveBalancingRuleRequest + 21, // 22: xray.app.router.command.RoutingService.GetBalancers:input_type -> xray.app.router.command.GetBalancerRequest + 0, // 23: xray.app.router.command.RoutingService.SubscribeRoutingStats:output_type -> xray.app.router.command.RoutingContext + 0, // 24: xray.app.router.command.RoutingService.TestRoute:output_type -> xray.app.router.command.RoutingContext + 4, // 25: xray.app.router.command.RoutingService.AddRule:output_type -> xray.app.router.command.AddRoutingRuleResponse + 6, // 26: xray.app.router.command.RoutingService.AlterRule:output_type -> xray.app.router.command.AlterRoutingRuleResponse + 8, // 27: xray.app.router.command.RoutingService.RemoveRule:output_type -> xray.app.router.command.RemoveRoutingRuleResponse + 10, // 28: xray.app.router.command.RoutingService.SetRules:output_type -> xray.app.router.command.SetRoutingRulesResponse + 12, // 29: xray.app.router.command.RoutingService.GetRules:output_type -> xray.app.router.command.GetRoutingRulesResponse + 14, // 30: xray.app.router.command.RoutingService.GetRule:output_type -> xray.app.router.command.GetRoutingRuleResponse + 16, // 31: xray.app.router.command.RoutingService.AddBalancer:output_type -> xray.app.router.command.AddBalancingRuleResponse + 18, // 32: xray.app.router.command.RoutingService.AlterBalancer:output_type -> xray.app.router.command.AlterBalancingRuleResponse + 20, // 33: xray.app.router.command.RoutingService.RemoveBalancer:output_type -> xray.app.router.command.RemoveBalancingRuleResponse + 22, // 34: xray.app.router.command.RoutingService.GetBalancers:output_type -> xray.app.router.command.GetBalancerResponse + 23, // [23:35] is the sub-list for method output_type + 11, // [11:23] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_app_router_command_command_proto_init() } @@ -1221,7 +1642,7 @@ func file_app_router_command_command_proto_init() { } } file_app_router_command_command_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddBalancingRuleRequest); i { + switch v := v.(*SetRoutingRulesRequest); i { case 0: return &v.state case 1: @@ -1233,7 +1654,7 @@ func file_app_router_command_command_proto_init() { } } file_app_router_command_command_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddBalancingRuleResponse); i { + switch v := v.(*SetRoutingRulesResponse); i { case 0: return &v.state case 1: @@ -1245,7 +1666,7 @@ func file_app_router_command_command_proto_init() { } } file_app_router_command_command_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AlterBalancingRuleRequest); i { + switch v := v.(*GetRoutingRulesRequest); i { case 0: return &v.state case 1: @@ -1257,7 +1678,7 @@ func file_app_router_command_command_proto_init() { } } file_app_router_command_command_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AlterBalancingRuleResponse); i { + switch v := v.(*GetRoutingRulesResponse); i { case 0: return &v.state case 1: @@ -1269,7 +1690,7 @@ func file_app_router_command_command_proto_init() { } } file_app_router_command_command_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RemoveBalancingRuleRequest); i { + switch v := v.(*GetRoutingRuleRequest); i { case 0: return &v.state case 1: @@ -1281,7 +1702,7 @@ func file_app_router_command_command_proto_init() { } } file_app_router_command_command_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RemoveBalancingRuleResponse); i { + switch v := v.(*GetRoutingRuleResponse); i { case 0: return &v.state case 1: @@ -1293,6 +1714,102 @@ func file_app_router_command_command_proto_init() { } } file_app_router_command_command_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddBalancingRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddBalancingRuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AlterBalancingRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AlterBalancingRuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveBalancingRuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveBalancingRuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBalancerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBalancerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_app_router_command_command_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Config); i { case 0: return &v.state @@ -1311,7 +1828,7 @@ func file_app_router_command_command_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_app_router_command_command_proto_rawDesc, NumEnums: 0, - NumMessages: 17, + NumMessages: 25, NumExtensions: 0, NumServices: 1, }, diff --git a/app/router/command/command.proto b/app/router/command/command.proto index fcc165f6fb81..5b3091a3f5ee 100644 --- a/app/router/command/command.proto +++ b/app/router/command/command.proto @@ -64,6 +64,7 @@ message TestRouteRequest { message AddRoutingRuleRequest{ xray.app.router.RoutingRule routingRule = 1; + int32 index = 2; } message AddRoutingRuleResponse {} @@ -79,6 +80,27 @@ message RemoveRoutingRuleRequest{ } message RemoveRoutingRuleResponse {} +message SetRoutingRulesRequest{ + repeated xray.app.router.RoutingRule rules = 1; +} + +message SetRoutingRulesResponse{ +} + +message GetRoutingRulesRequest{ +} + +message GetRoutingRulesResponse{ + repeated xray.app.router.RoutingRule rules = 1; +} + +message GetRoutingRuleRequest{ +} + +message GetRoutingRuleResponse{ + xray.app.router.RoutingRule rule = 1; +} + message AddBalancingRuleRequest{ xray.app.router.BalancingRule balancing = 1; } @@ -96,15 +118,29 @@ message RemoveBalancingRuleRequest{ } message RemoveBalancingRuleResponse {} +message GetBalancerRequest{ +} + +message GetBalancerResponse { + repeated xray.app.router.BalancingRule balancing = 2; +} + service RoutingService { rpc SubscribeRoutingStats(SubscribeRoutingStatsRequest) returns (stream RoutingContext) {} rpc TestRoute(TestRouteRequest) returns (RoutingContext) {} - rpc AddRoutingRule(AddRoutingRuleRequest) returns (AddRoutingRuleResponse){} - rpc AlterRoutingRule(AlterRoutingRuleRequest) returns (AlterRoutingRuleResponse){} - rpc RemoveRoutingRule(RemoveRoutingRuleRequest) returns (RemoveRoutingRuleResponse){} - rpc AddBalancingRule(AddBalancingRuleRequest) returns (AddBalancingRuleResponse){} - rpc AlterBalancingRule(AlterBalancingRuleRequest) returns (AlterBalancingRuleResponse){} - rpc RemoveBalancingRule(RemoveBalancingRuleRequest) returns (RemoveBalancingRuleResponse){} + // AddRule When adding a routing rule, make sure that the new rule does not conflict with the API route, otherwise the API will not work properly + rpc AddRule(AddRoutingRuleRequest) returns (AddRoutingRuleResponse){} + rpc AlterRule(AlterRoutingRuleRequest) returns (AlterRoutingRuleResponse){} + rpc RemoveRule(RemoveRoutingRuleRequest) returns (RemoveRoutingRuleResponse){} + // SetRules Routing rules must be set to ensure that the API route must exist, otherwise the API will not work properly + rpc SetRules(SetRoutingRulesRequest)returns(SetRoutingRulesResponse){} + rpc GetRules(GetRoutingRulesRequest)returns(GetRoutingRulesResponse){} + rpc GetRule(GetRoutingRuleRequest)returns(GetRoutingRuleResponse){} + + rpc AddBalancer(AddBalancingRuleRequest) returns (AddBalancingRuleResponse){} + rpc AlterBalancer(AlterBalancingRuleRequest) returns (AlterBalancingRuleResponse){} + rpc RemoveBalancer(RemoveBalancingRuleRequest) returns (RemoveBalancingRuleResponse){} + rpc GetBalancers(GetBalancerRequest) returns (GetBalancerResponse){} } message Config {} diff --git a/app/router/command/command_grpc.pb.go b/app/router/command/command_grpc.pb.go index 8e0432e48c2b..b9f80763404a 100644 --- a/app/router/command/command_grpc.pb.go +++ b/app/router/command/command_grpc.pb.go @@ -23,12 +23,18 @@ const _ = grpc.SupportPackageIsVersion6 type RoutingServiceClient interface { SubscribeRoutingStats(ctx context.Context, in *SubscribeRoutingStatsRequest, opts ...grpc.CallOption) (RoutingService_SubscribeRoutingStatsClient, error) TestRoute(ctx context.Context, in *TestRouteRequest, opts ...grpc.CallOption) (*RoutingContext, error) - AddRoutingRule(ctx context.Context, in *AddRoutingRuleRequest, opts ...grpc.CallOption) (*AddRoutingRuleResponse, error) - AlterRoutingRule(ctx context.Context, in *AlterRoutingRuleRequest, opts ...grpc.CallOption) (*AlterRoutingRuleResponse, error) - RemoveRoutingRule(ctx context.Context, in *RemoveRoutingRuleRequest, opts ...grpc.CallOption) (*RemoveRoutingRuleResponse, error) - AddBalancingRule(ctx context.Context, in *AddBalancingRuleRequest, opts ...grpc.CallOption) (*AddBalancingRuleResponse, error) - AlterBalancingRule(ctx context.Context, in *AlterBalancingRuleRequest, opts ...grpc.CallOption) (*AlterBalancingRuleResponse, error) - RemoveBalancingRule(ctx context.Context, in *RemoveBalancingRuleRequest, opts ...grpc.CallOption) (*RemoveBalancingRuleResponse, error) + // AddRule When adding a routing rule, make sure that the new rule does not conflict with the API route, otherwise the API will not work properly + AddRule(ctx context.Context, in *AddRoutingRuleRequest, opts ...grpc.CallOption) (*AddRoutingRuleResponse, error) + AlterRule(ctx context.Context, in *AlterRoutingRuleRequest, opts ...grpc.CallOption) (*AlterRoutingRuleResponse, error) + RemoveRule(ctx context.Context, in *RemoveRoutingRuleRequest, opts ...grpc.CallOption) (*RemoveRoutingRuleResponse, error) + // SetRules Routing rules must be set to ensure that the API route must exist, otherwise the API will not work properly + SetRules(ctx context.Context, in *SetRoutingRulesRequest, opts ...grpc.CallOption) (*SetRoutingRulesResponse, error) + GetRules(ctx context.Context, in *GetRoutingRulesRequest, opts ...grpc.CallOption) (*GetRoutingRulesResponse, error) + GetRule(ctx context.Context, in *GetRoutingRuleRequest, opts ...grpc.CallOption) (*GetRoutingRuleResponse, error) + AddBalancer(ctx context.Context, in *AddBalancingRuleRequest, opts ...grpc.CallOption) (*AddBalancingRuleResponse, error) + AlterBalancer(ctx context.Context, in *AlterBalancingRuleRequest, opts ...grpc.CallOption) (*AlterBalancingRuleResponse, error) + RemoveBalancer(ctx context.Context, in *RemoveBalancingRuleRequest, opts ...grpc.CallOption) (*RemoveBalancingRuleResponse, error) + GetBalancers(ctx context.Context, in *GetBalancerRequest, opts ...grpc.CallOption) (*GetBalancerResponse, error) } type routingServiceClient struct { @@ -80,54 +86,90 @@ func (c *routingServiceClient) TestRoute(ctx context.Context, in *TestRouteReque return out, nil } -func (c *routingServiceClient) AddRoutingRule(ctx context.Context, in *AddRoutingRuleRequest, opts ...grpc.CallOption) (*AddRoutingRuleResponse, error) { +func (c *routingServiceClient) AddRule(ctx context.Context, in *AddRoutingRuleRequest, opts ...grpc.CallOption) (*AddRoutingRuleResponse, error) { out := new(AddRoutingRuleResponse) - err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AddRoutingRule", in, out, opts...) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AddRule", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *routingServiceClient) AlterRoutingRule(ctx context.Context, in *AlterRoutingRuleRequest, opts ...grpc.CallOption) (*AlterRoutingRuleResponse, error) { +func (c *routingServiceClient) AlterRule(ctx context.Context, in *AlterRoutingRuleRequest, opts ...grpc.CallOption) (*AlterRoutingRuleResponse, error) { out := new(AlterRoutingRuleResponse) - err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AlterRoutingRule", in, out, opts...) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AlterRule", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *routingServiceClient) RemoveRoutingRule(ctx context.Context, in *RemoveRoutingRuleRequest, opts ...grpc.CallOption) (*RemoveRoutingRuleResponse, error) { +func (c *routingServiceClient) RemoveRule(ctx context.Context, in *RemoveRoutingRuleRequest, opts ...grpc.CallOption) (*RemoveRoutingRuleResponse, error) { out := new(RemoveRoutingRuleResponse) - err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/RemoveRoutingRule", in, out, opts...) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/RemoveRule", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *routingServiceClient) AddBalancingRule(ctx context.Context, in *AddBalancingRuleRequest, opts ...grpc.CallOption) (*AddBalancingRuleResponse, error) { +func (c *routingServiceClient) SetRules(ctx context.Context, in *SetRoutingRulesRequest, opts ...grpc.CallOption) (*SetRoutingRulesResponse, error) { + out := new(SetRoutingRulesResponse) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/SetRules", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *routingServiceClient) GetRules(ctx context.Context, in *GetRoutingRulesRequest, opts ...grpc.CallOption) (*GetRoutingRulesResponse, error) { + out := new(GetRoutingRulesResponse) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/GetRules", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *routingServiceClient) GetRule(ctx context.Context, in *GetRoutingRuleRequest, opts ...grpc.CallOption) (*GetRoutingRuleResponse, error) { + out := new(GetRoutingRuleResponse) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/GetRule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *routingServiceClient) AddBalancer(ctx context.Context, in *AddBalancingRuleRequest, opts ...grpc.CallOption) (*AddBalancingRuleResponse, error) { out := new(AddBalancingRuleResponse) - err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AddBalancingRule", in, out, opts...) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AddBalancer", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *routingServiceClient) AlterBalancingRule(ctx context.Context, in *AlterBalancingRuleRequest, opts ...grpc.CallOption) (*AlterBalancingRuleResponse, error) { +func (c *routingServiceClient) AlterBalancer(ctx context.Context, in *AlterBalancingRuleRequest, opts ...grpc.CallOption) (*AlterBalancingRuleResponse, error) { out := new(AlterBalancingRuleResponse) - err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AlterBalancingRule", in, out, opts...) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/AlterBalancer", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *routingServiceClient) RemoveBalancingRule(ctx context.Context, in *RemoveBalancingRuleRequest, opts ...grpc.CallOption) (*RemoveBalancingRuleResponse, error) { +func (c *routingServiceClient) RemoveBalancer(ctx context.Context, in *RemoveBalancingRuleRequest, opts ...grpc.CallOption) (*RemoveBalancingRuleResponse, error) { out := new(RemoveBalancingRuleResponse) - err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/RemoveBalancingRule", in, out, opts...) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/RemoveBalancer", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *routingServiceClient) GetBalancers(ctx context.Context, in *GetBalancerRequest, opts ...grpc.CallOption) (*GetBalancerResponse, error) { + out := new(GetBalancerResponse) + err := c.cc.Invoke(ctx, "/xray.app.router.command.RoutingService/GetBalancers", in, out, opts...) if err != nil { return nil, err } @@ -138,12 +180,18 @@ func (c *routingServiceClient) RemoveBalancingRule(ctx context.Context, in *Remo type RoutingServiceServer interface { SubscribeRoutingStats(*SubscribeRoutingStatsRequest, RoutingService_SubscribeRoutingStatsServer) error TestRoute(context.Context, *TestRouteRequest) (*RoutingContext, error) - AddRoutingRule(context.Context, *AddRoutingRuleRequest) (*AddRoutingRuleResponse, error) - AlterRoutingRule(context.Context, *AlterRoutingRuleRequest) (*AlterRoutingRuleResponse, error) - RemoveRoutingRule(context.Context, *RemoveRoutingRuleRequest) (*RemoveRoutingRuleResponse, error) - AddBalancingRule(context.Context, *AddBalancingRuleRequest) (*AddBalancingRuleResponse, error) - AlterBalancingRule(context.Context, *AlterBalancingRuleRequest) (*AlterBalancingRuleResponse, error) - RemoveBalancingRule(context.Context, *RemoveBalancingRuleRequest) (*RemoveBalancingRuleResponse, error) + // AddRule When adding a routing rule, make sure that the new rule does not conflict with the API route, otherwise the API will not work properly + AddRule(context.Context, *AddRoutingRuleRequest) (*AddRoutingRuleResponse, error) + AlterRule(context.Context, *AlterRoutingRuleRequest) (*AlterRoutingRuleResponse, error) + RemoveRule(context.Context, *RemoveRoutingRuleRequest) (*RemoveRoutingRuleResponse, error) + // SetRules Routing rules must be set to ensure that the API route must exist, otherwise the API will not work properly + SetRules(context.Context, *SetRoutingRulesRequest) (*SetRoutingRulesResponse, error) + GetRules(context.Context, *GetRoutingRulesRequest) (*GetRoutingRulesResponse, error) + GetRule(context.Context, *GetRoutingRuleRequest) (*GetRoutingRuleResponse, error) + AddBalancer(context.Context, *AddBalancingRuleRequest) (*AddBalancingRuleResponse, error) + AlterBalancer(context.Context, *AlterBalancingRuleRequest) (*AlterBalancingRuleResponse, error) + RemoveBalancer(context.Context, *RemoveBalancingRuleRequest) (*RemoveBalancingRuleResponse, error) + GetBalancers(context.Context, *GetBalancerRequest) (*GetBalancerResponse, error) } // UnimplementedRoutingServiceServer can be embedded to have forward compatible implementations. @@ -156,23 +204,35 @@ func (*UnimplementedRoutingServiceServer) SubscribeRoutingStats(*SubscribeRoutin func (*UnimplementedRoutingServiceServer) TestRoute(context.Context, *TestRouteRequest) (*RoutingContext, error) { return nil, status.Errorf(codes.Unimplemented, "method TestRoute not implemented") } -func (*UnimplementedRoutingServiceServer) AddRoutingRule(context.Context, *AddRoutingRuleRequest) (*AddRoutingRuleResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddRoutingRule not implemented") +func (*UnimplementedRoutingServiceServer) AddRule(context.Context, *AddRoutingRuleRequest) (*AddRoutingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddRule not implemented") +} +func (*UnimplementedRoutingServiceServer) AlterRule(context.Context, *AlterRoutingRuleRequest) (*AlterRoutingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AlterRule not implemented") +} +func (*UnimplementedRoutingServiceServer) RemoveRule(context.Context, *RemoveRoutingRuleRequest) (*RemoveRoutingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveRule not implemented") +} +func (*UnimplementedRoutingServiceServer) SetRules(context.Context, *SetRoutingRulesRequest) (*SetRoutingRulesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetRules not implemented") +} +func (*UnimplementedRoutingServiceServer) GetRules(context.Context, *GetRoutingRulesRequest) (*GetRoutingRulesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRules not implemented") } -func (*UnimplementedRoutingServiceServer) AlterRoutingRule(context.Context, *AlterRoutingRuleRequest) (*AlterRoutingRuleResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method AlterRoutingRule not implemented") +func (*UnimplementedRoutingServiceServer) GetRule(context.Context, *GetRoutingRuleRequest) (*GetRoutingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRule not implemented") } -func (*UnimplementedRoutingServiceServer) RemoveRoutingRule(context.Context, *RemoveRoutingRuleRequest) (*RemoveRoutingRuleResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method RemoveRoutingRule not implemented") +func (*UnimplementedRoutingServiceServer) AddBalancer(context.Context, *AddBalancingRuleRequest) (*AddBalancingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddBalancer not implemented") } -func (*UnimplementedRoutingServiceServer) AddBalancingRule(context.Context, *AddBalancingRuleRequest) (*AddBalancingRuleResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddBalancingRule not implemented") +func (*UnimplementedRoutingServiceServer) AlterBalancer(context.Context, *AlterBalancingRuleRequest) (*AlterBalancingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AlterBalancer not implemented") } -func (*UnimplementedRoutingServiceServer) AlterBalancingRule(context.Context, *AlterBalancingRuleRequest) (*AlterBalancingRuleResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method AlterBalancingRule not implemented") +func (*UnimplementedRoutingServiceServer) RemoveBalancer(context.Context, *RemoveBalancingRuleRequest) (*RemoveBalancingRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveBalancer not implemented") } -func (*UnimplementedRoutingServiceServer) RemoveBalancingRule(context.Context, *RemoveBalancingRuleRequest) (*RemoveBalancingRuleResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method RemoveBalancingRule not implemented") +func (*UnimplementedRoutingServiceServer) GetBalancers(context.Context, *GetBalancerRequest) (*GetBalancerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBalancers not implemented") } func RegisterRoutingServiceServer(s *grpc.Server, srv RoutingServiceServer) { @@ -218,110 +278,182 @@ func _RoutingService_TestRoute_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } -func _RoutingService_AddRoutingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _RoutingService_AddRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AddRoutingRuleRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(RoutingServiceServer).AddRoutingRule(ctx, in) + return srv.(RoutingServiceServer).AddRule(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/xray.app.router.command.RoutingService/AddRoutingRule", + FullMethod: "/xray.app.router.command.RoutingService/AddRule", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RoutingServiceServer).AddRoutingRule(ctx, req.(*AddRoutingRuleRequest)) + return srv.(RoutingServiceServer).AddRule(ctx, req.(*AddRoutingRuleRequest)) } return interceptor(ctx, in, info, handler) } -func _RoutingService_AlterRoutingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _RoutingService_AlterRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AlterRoutingRuleRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(RoutingServiceServer).AlterRoutingRule(ctx, in) + return srv.(RoutingServiceServer).AlterRule(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/xray.app.router.command.RoutingService/AlterRoutingRule", + FullMethod: "/xray.app.router.command.RoutingService/AlterRule", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RoutingServiceServer).AlterRoutingRule(ctx, req.(*AlterRoutingRuleRequest)) + return srv.(RoutingServiceServer).AlterRule(ctx, req.(*AlterRoutingRuleRequest)) } return interceptor(ctx, in, info, handler) } -func _RoutingService_RemoveRoutingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _RoutingService_RemoveRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RemoveRoutingRuleRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(RoutingServiceServer).RemoveRoutingRule(ctx, in) + return srv.(RoutingServiceServer).RemoveRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/xray.app.router.command.RoutingService/RemoveRule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoutingServiceServer).RemoveRule(ctx, req.(*RemoveRoutingRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoutingService_SetRules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetRoutingRulesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoutingServiceServer).SetRules(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/xray.app.router.command.RoutingService/SetRules", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoutingServiceServer).SetRules(ctx, req.(*SetRoutingRulesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoutingService_GetRules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetRoutingRulesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoutingServiceServer).GetRules(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/xray.app.router.command.RoutingService/GetRules", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoutingServiceServer).GetRules(ctx, req.(*GetRoutingRulesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoutingService_GetRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetRoutingRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoutingServiceServer).GetRule(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/xray.app.router.command.RoutingService/RemoveRoutingRule", + FullMethod: "/xray.app.router.command.RoutingService/GetRule", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RoutingServiceServer).RemoveRoutingRule(ctx, req.(*RemoveRoutingRuleRequest)) + return srv.(RoutingServiceServer).GetRule(ctx, req.(*GetRoutingRuleRequest)) } return interceptor(ctx, in, info, handler) } -func _RoutingService_AddBalancingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _RoutingService_AddBalancer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AddBalancingRuleRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(RoutingServiceServer).AddBalancingRule(ctx, in) + return srv.(RoutingServiceServer).AddBalancer(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/xray.app.router.command.RoutingService/AddBalancingRule", + FullMethod: "/xray.app.router.command.RoutingService/AddBalancer", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RoutingServiceServer).AddBalancingRule(ctx, req.(*AddBalancingRuleRequest)) + return srv.(RoutingServiceServer).AddBalancer(ctx, req.(*AddBalancingRuleRequest)) } return interceptor(ctx, in, info, handler) } -func _RoutingService_AlterBalancingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _RoutingService_AlterBalancer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AlterBalancingRuleRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(RoutingServiceServer).AlterBalancingRule(ctx, in) + return srv.(RoutingServiceServer).AlterBalancer(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/xray.app.router.command.RoutingService/AlterBalancingRule", + FullMethod: "/xray.app.router.command.RoutingService/AlterBalancer", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RoutingServiceServer).AlterBalancingRule(ctx, req.(*AlterBalancingRuleRequest)) + return srv.(RoutingServiceServer).AlterBalancer(ctx, req.(*AlterBalancingRuleRequest)) } return interceptor(ctx, in, info, handler) } -func _RoutingService_RemoveBalancingRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _RoutingService_RemoveBalancer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RemoveBalancingRuleRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(RoutingServiceServer).RemoveBalancingRule(ctx, in) + return srv.(RoutingServiceServer).RemoveBalancer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/xray.app.router.command.RoutingService/RemoveBalancer", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RoutingServiceServer).RemoveBalancer(ctx, req.(*RemoveBalancingRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RoutingService_GetBalancers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBalancerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RoutingServiceServer).GetBalancers(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/xray.app.router.command.RoutingService/RemoveBalancingRule", + FullMethod: "/xray.app.router.command.RoutingService/GetBalancers", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RoutingServiceServer).RemoveBalancingRule(ctx, req.(*RemoveBalancingRuleRequest)) + return srv.(RoutingServiceServer).GetBalancers(ctx, req.(*GetBalancerRequest)) } return interceptor(ctx, in, info, handler) } @@ -335,28 +467,44 @@ var RoutingService_ServiceDesc = grpc.ServiceDesc{ Handler: _RoutingService_TestRoute_Handler, }, { - MethodName: "AddRoutingRule", - Handler: _RoutingService_AddRoutingRule_Handler, + MethodName: "AddRule", + Handler: _RoutingService_AddRule_Handler, + }, + { + MethodName: "AlterRule", + Handler: _RoutingService_AlterRule_Handler, + }, + { + MethodName: "RemoveRule", + Handler: _RoutingService_RemoveRule_Handler, + }, + { + MethodName: "SetRules", + Handler: _RoutingService_SetRules_Handler, + }, + { + MethodName: "GetRules", + Handler: _RoutingService_GetRules_Handler, }, { - MethodName: "AlterRoutingRule", - Handler: _RoutingService_AlterRoutingRule_Handler, + MethodName: "GetRule", + Handler: _RoutingService_GetRule_Handler, }, { - MethodName: "RemoveRoutingRule", - Handler: _RoutingService_RemoveRoutingRule_Handler, + MethodName: "AddBalancer", + Handler: _RoutingService_AddBalancer_Handler, }, { - MethodName: "AddBalancingRule", - Handler: _RoutingService_AddBalancingRule_Handler, + MethodName: "AlterBalancer", + Handler: _RoutingService_AlterBalancer_Handler, }, { - MethodName: "AlterBalancingRule", - Handler: _RoutingService_AlterBalancingRule_Handler, + MethodName: "RemoveBalancer", + Handler: _RoutingService_RemoveBalancer_Handler, }, { - MethodName: "RemoveBalancingRule", - Handler: _RoutingService_RemoveBalancingRule_Handler, + MethodName: "GetBalancers", + Handler: _RoutingService_GetBalancers_Handler, }, }, Streams: []grpc.StreamDesc{ diff --git a/app/router/command/command_test.go b/app/router/command/command_test.go index e97e8989446b..e949c35e3efe 100644 --- a/app/router/command/command_test.go +++ b/app/router/command/command_test.go @@ -221,9 +221,8 @@ func TestServiceTestRoute(t *testing.T) { TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, }, { - Networks: []net.Network{net.Network_UDP, net.Network_TCP}, - Protocol: []string{"bittorrent"}, TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "blocked"}, + Protocol: []string{"bittorrent"}, }, { PortList: &net.PortList{Range: []*net.PortRange{{From: 8080, To: 8080}}}, @@ -246,7 +245,7 @@ func TestServiceTestRoute(t *testing.T) { TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, }, { - Networks: []net.Network{net.Network_TCP}, + Networks: []net.Network{net.Network_UDP, net.Network_TCP}, TargetTag: &router.RoutingRule_OutboundTag{OutboundTag: "out"}, }, }, @@ -440,7 +439,7 @@ func TestServiceAddRoutingRule(t *testing.T) { // Test add rule testAddRule := func() error { for _, tc := range testAddRuleCases { - _, err := client.AddRoutingRule(context.Background(), &AddRoutingRuleRequest{RoutingRule: tc}) + _, err := client.AddRule(context.Background(), &AddRoutingRuleRequest{RoutingRule: tc}) if err != nil { return err } @@ -682,7 +681,7 @@ func TestServiceAlterRoutingRule(t *testing.T) { // Test alter rule testAlterRule := func() error { for _, tc := range testAlterRuleCases { - _, err := client.AlterRoutingRule(context.Background(), tc) + _, err := client.AlterRule(context.Background(), tc) if err != nil { return err } @@ -876,7 +875,7 @@ func TestServiceRemoveRoutingRule(t *testing.T) { // Test alter rule testRemoveRule := func() error { for _, tc := range testRemoveRuleCases { - _, err := client.RemoveRoutingRule(context.Background(), &RemoveRoutingRuleRequest{Tag: tc}) + _, err := client.RemoveRule(context.Background(), &RemoveRoutingRuleRequest{Tag: tc}) if err != nil { return err } @@ -924,4 +923,3 @@ func TestServiceRemoveRoutingRule(t *testing.T) { } } } - diff --git a/app/router/router.go b/app/router/router.go index fae1faca57e7..a6a7ecb4fcdb 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -137,8 +137,9 @@ func (r *Router) FindRule(tag string) (idx int, rule *Rule) { return } -// AddRoutingRule implement the manager interface. -func (r *Router) AddRoutingRule(ctx context.Context, routingRule interface{}) error { +// AddRule implement the manager interface. +// Index less than 1 or more than len(r.rules) is append to the end +func (r *Router) AddRule(ctx context.Context, index int32, routingRule interface{}) error { rr := routingRule.(*RoutingRule) if len(rr.Tag) > 0 { @@ -155,13 +156,24 @@ func (r *Router) AddRoutingRule(ctx context.Context, routingRule interface{}) er r.access.Lock() defer r.access.Unlock() - r.rules = append(r.rules, rule) + if len(r.rules) < int(index) || index < 1 { + // index must be greater than zero + // API rules must have precedence + r.rules = append(r.rules, rule) + } else { + // Insert to the specified location + temp := make([]*Rule, 0, len(r.rules)+1) + temp = append(r.rules[:index], rule) + temp = append(temp, r.rules[index:]...) + r.rules = temp + } + newError("RoutingRule has been added through the API. [", rule.Tag, "]").WriteToLog(session.ExportIDToError(ctx)) return nil } -// AlterRoutingRule implement the manager interface. -func (r *Router) AlterRoutingRule(ctx context.Context, tag string, routingRule interface{}) error { +// AlterRule implement the manager interface. +func (r *Router) AlterRule(ctx context.Context, tag string, routingRule interface{}) error { idx, rule := r.FindRule(tag) if idx == -1 { return newError("tag not found: " + tag) @@ -183,8 +195,8 @@ func (r *Router) AlterRoutingRule(ctx context.Context, tag string, routingRule i return nil } -// RemoveRoutingRule implement the manager interface. -func (r *Router) RemoveRoutingRule(ctx context.Context, tag string) error { +// RemoveRule implement the manager interface. +func (r *Router) RemoveRule(ctx context.Context, tag string) error { idx, rule := r.FindRule(tag) if idx == -1 { return newError("tag not found: " + tag) @@ -198,8 +210,43 @@ func (r *Router) RemoveRoutingRule(ctx context.Context, tag string) error { return nil } -// AddBalancingRule implement the manager interface. -func (r *Router) AddBalancingRule(ctx context.Context, balancingRule interface{}, om outbound.Manager) error { +// SetRules not implement . +func (r *Router) SetRules(ctx context.Context, rules interface{}) error { + rrs := rules.([]*RoutingRule) + + if len(rrs) == 0 { + return newError("Add at least one routing rule") + } + + temp := make([]*Rule, 0, len(rrs)) + for _, v := range rrs { + rr, err := v.Build(r) + if err != nil { + return err + } + temp = append(temp, rr) + } + + r.access.Lock() + defer r.access.Unlock() + + r.rules = temp + newError("Set [", len(temp), "] routing rules through the API").WriteToLog(session.ExportIDToError(ctx)) + return nil +} + +// GetRules not implement . +func (r *Router) GetRules(ctx context.Context) (interface{}, error) { + return nil, newError("not implement.") +} + +// GetRule implement the manager interface. +func (r *Router) GetRule(ctx context.Context, tag string) (interface{}, error) { + return nil, newError("not implement.") +} + +// AddBalancer implement the manager interface. +func (r *Router) AddBalancer(ctx context.Context, balancingRule interface{}, om outbound.Manager) error { br := balancingRule.(*BalancingRule) if _, found := r.balancers[br.Tag]; found { return newError("existing tag found: " + br.Tag) @@ -217,8 +264,8 @@ func (r *Router) AddBalancingRule(ctx context.Context, balancingRule interface{} return nil } -// AlterBalancingRule implement the manager interface. -func (r *Router) AlterBalancingRule(ctx context.Context, tag string, balancingRule interface{}, om outbound.Manager) error { +// AlterBalancer implement the manager interface. +func (r *Router) AlterBalancer(ctx context.Context, tag string, balancingRule interface{}, om outbound.Manager) error { if _, found := r.balancers[tag]; !found { return newError("tag not found: " + tag) } @@ -243,8 +290,8 @@ func (r *Router) AlterBalancingRule(ctx context.Context, tag string, balancingRu return nil } -// RemoveBalancingRule implement the manager interface. -func (r *Router) RemoveBalancingRule(ctx context.Context, tag string) error { +// RemoveBalancer implement the manager interface. +func (r *Router) RemoveBalancer(ctx context.Context, tag string) error { if _, found := r.balancers[tag]; !found { return newError("tag not found: " + tag) } @@ -263,6 +310,11 @@ func (r *Router) RemoveBalancingRule(ctx context.Context, tag string) error { return nil } +// GetBalancers not implement. +func (r *Router) GetBalancers(ctx context.Context) (interface{}, error) { + return nil, newError("not implement.") +} + // Start implements common.Runnable. func (*Router) Start() error { return nil diff --git a/app/router/router_test.go b/app/router/router_test.go index 7a678fc679dc..bb4346228194 100644 --- a/app/router/router_test.go +++ b/app/router/router_test.go @@ -223,7 +223,7 @@ func TestRouter_AddRoutingRule(t *testing.T) { })) ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)}) - err := r.AddRoutingRule(ctx, &RoutingRule{ + err := r.AddRule(ctx, -1, &RoutingRule{ TargetTag: &RoutingRule_OutboundTag{ OutboundTag: "test", }, @@ -270,7 +270,7 @@ func TestRouter_AlterRoutingRule(t *testing.T) { })) ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)}) - err := r.AlterRoutingRule(ctx, "test", &RoutingRule{ + err := r.AlterRule(ctx, "test", &RoutingRule{ TargetTag: &RoutingRule_OutboundTag{ OutboundTag: "test", }, @@ -329,7 +329,7 @@ func TestRouter_RemoveRoutingRule(t *testing.T) { })) ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)}) - err := r.RemoveRoutingRule(ctx, "example") + err := r.RemoveRule(ctx, "example") common.Must(err) route, err := r.PickRoute(routing_session.AsRoutingContext(ctx)) common.Must(err) diff --git a/features/routing/router.go b/features/routing/router.go index dd23915069d3..d0b61e96a68c 100644 --- a/features/routing/router.go +++ b/features/routing/router.go @@ -52,36 +52,56 @@ func (DefaultRouter) PickRoute(ctx Context) (Route, error) { return nil, common.ErrNoClue } -// AddRoutingRule implements Router. -func (DefaultRouter) AddRoutingRule(ctx context.Context, routingRule interface{}) error { +// AddRule implements Router. +func (DefaultRouter) AddRule(ctx context.Context, index int32, routingRule interface{}) error { return common.ErrNoClue } -// AlterRoutingRule implements Router. -func (DefaultRouter) AlterRoutingRule(ctx context.Context, tag string, routingRule interface{}) error { +// AlterRule implements Router. +func (DefaultRouter) AlterRule(ctx context.Context, tag string, routingRule interface{}) error { return common.ErrNoClue } -// RemoveRoutingRule implements Router. -func (DefaultRouter) RemoveRoutingRule(ctx context.Context, tag string) error { +// RemoveRule implements Router. +func (DefaultRouter) RemoveRule(ctx context.Context, tag string) error { return common.ErrNoClue } -// AddBalancingRule implements Router. -func (DefaultRouter) AddBalancingRule(ctx context.Context, balancingRule interface{}, handler outbound.Manager) error { +// SetRules implements Router. +func (DefaultRouter) SetRules(ctx context.Context, rules interface{}) error { return common.ErrNoClue } -// AlterBalancingRule implements Router. -func (DefaultRouter) AlterBalancingRule(ctx context.Context, tag string, balancingRule interface{}, handler outbound.Manager) error { +// GetRules implements Router. +func (DefaultRouter) GetRules(ctx context.Context) (interface{}, error) { + return nil, common.ErrNoClue +} + +// GetRule implements Router. +func (DefaultRouter) GetRule(ctx context.Context, tag string) (interface{}, error) { + return nil, common.ErrNoClue +} + +// AddBalancer implements Router. +func (DefaultRouter) AddBalancer(ctx context.Context, balancingRule interface{}, handler outbound.Manager) error { return common.ErrNoClue } -// RemoveBalancingRule implements Router. -func (DefaultRouter) RemoveBalancingRule(ctx context.Context, tag string) error { +// AlterBalancer implements Router. +func (DefaultRouter) AlterBalancer(ctx context.Context, tag string, balancingRule interface{}, handler outbound.Manager) error { return common.ErrNoClue } +// RemoveBalancer implements Router. +func (DefaultRouter) RemoveBalancer(ctx context.Context, tag string) error { + return common.ErrNoClue +} + +// GetBalancers implements Router. +func (DefaultRouter) GetBalancers(ctx context.Context) (interface{}, error) { + return nil, common.ErrNoClue +} + // Start implements common.Runnable. func (DefaultRouter) Start() error { return nil @@ -97,16 +117,25 @@ func (DefaultRouter) Close() error { // xray:api:alpha type Manager interface { features.Feature - // AddRoutingRule adds the given routing rule into this Manager. - AddRoutingRule(ctx context.Context, routingRule interface{}) error - // AlterRoutingRule Modifies the specified routing rule - AlterRoutingRule(ctx context.Context, tag string, routingRule interface{}) error - // RemoveRoutingRule Remove the specified routing rule - RemoveRoutingRule(ctx context.Context, tag string) error - // AddBalancingRule adds the given balancing rules to this manager. - AddBalancingRule(ctx context.Context, balancingRule interface{}, handler outbound.Manager) error - // AlterBalancingRule Modifies the specified balancing rule - AlterBalancingRule(ctx context.Context, tag string, balancingRule interface{}, handler outbound.Manager) error - // RemoveBalancingRule Remove the specified balancing rule - RemoveBalancingRule(ctx context.Context, tag string) error + // AddRule adds the given routing rule into this Manager. + AddRule(ctx context.Context, index int32, routingRule interface{}) error + // AlterRule Modifies the specified routing rule + AlterRule(ctx context.Context, tag string, routingRule interface{}) error + // RemoveRule Remove the specified routing rule + RemoveRule(ctx context.Context, tag string) error + // SetRules + SetRules(ctx context.Context, rules interface{}) error + // GetRules + GetRules(ctx context.Context) (interface{}, error) + // GetRule + GetRule(ctx context.Context, tag string) (interface{}, error) + + // Balancer adds the given balancing rules to this manager. + AddBalancer(ctx context.Context, balancingRule interface{}, handler outbound.Manager) error + // AlterBalancer Modifies the specified balancing rule + AlterBalancer(ctx context.Context, tag string, balancingRule interface{}, handler outbound.Manager) error + // RemoveBalancer Remove the specified balancing rule + RemoveBalancer(ctx context.Context, tag string) error + // GetBalancers + GetBalancers(ctx context.Context) (interface{}, error) } From a0d9fc90c7a8ad01ac5ebeef745239cf0cbc4bea Mon Sep 17 00:00:00 2001 From: tat5522 <81008809+tat5522@users.noreply.github.com> Date: Wed, 21 Apr 2021 17:24:59 +0800 Subject: [PATCH 6/9] implementation routing get and set api. --- app/router/command/command.go | 54 ++++- app/router/command/command.pb.go | 273 +++++++++++++---------- app/router/command/command.proto | 4 +- app/router/condition.go | 132 ++++++++++- app/router/condition_test.go | 110 +++++++++ app/router/config.go | 17 ++ app/router/router.go | 40 +++- app/router/router_test.go | 122 ++++++++++ common/net/port.go | 8 + common/strmatcher/RestoreDomain.go | 15 ++ common/strmatcher/domain_matcher.go | 30 +++ common/strmatcher/domain_matcher_test.go | 15 ++ common/strmatcher/full_matcher.go | 14 ++ common/strmatcher/matchers.go | 28 +++ common/strmatcher/strmatcher.go | 31 +++ features/routing/router.go | 14 +- 16 files changed, 758 insertions(+), 149 deletions(-) create mode 100644 common/strmatcher/RestoreDomain.go diff --git a/app/router/command/command.go b/app/router/command/command.go index 4b3638285611..bab91d8ffc80 100644 --- a/app/router/command/command.go +++ b/app/router/command/command.go @@ -4,15 +4,16 @@ package command import ( "context" + "os" "time" - "google.golang.org/grpc" - + "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/features/routing" "github.com/xtls/xray-core/features/stats" + "google.golang.org/grpc" ) // routingServer is an implementation of RoutingService. @@ -86,16 +87,49 @@ func (s *routingServer) RemoveRule(ctx context.Context, request *RemoveRoutingRu return &RemoveRoutingRuleResponse{}, nil } -func (s *routingServer) SetRules(ctx context.Context, rules *SetRoutingRulesRequest) (*SetRoutingRulesResponse, error) { - return nil, newError("not implement.") +func (s *routingServer) SetRules(ctx context.Context, request *SetRoutingRulesRequest) (*SetRoutingRulesResponse, error) { + // The routing API requires a backup content + if enable := os.Getenv("XRAY_ROUTER_API_GETSET"); enable != "1" { + return nil, newError("The environment variable XRAY_ROUTER_API_GETSET is not set to 1.") + } + + if len(request.Rules) == 0 { + return nil, newError("Rules is empty.") + } + err := s.router.SetRules(ctx, request.Rules) + if err != nil { + return nil, err + } + return &SetRoutingRulesResponse{}, nil } func (s *routingServer) GetRules(ctx context.Context, request *GetRoutingRulesRequest) (*GetRoutingRulesResponse, error) { - return nil, newError("not implement.") + // The routing API requires a backup content + if enable := os.Getenv("XRAY_ROUTER_API_GETSET"); enable != "1" { + return nil, newError("The environment variable XRAY_ROUTER_API_GETSET is not set to 1.") + } + rules, err := s.router.GetRules(ctx) + if err != nil { + return nil, err + } + return &GetRoutingRulesResponse{ + Rules: rules.([]*router.RoutingRule), + }, nil } func (s *routingServer) GetRule(ctx context.Context, request *GetRoutingRuleRequest) (*GetRoutingRuleResponse, error) { - return nil, newError("not implement.") + // The routing API requires a backup content + if enable := os.Getenv("XRAY_ROUTER_API_GETSET"); enable != "1" { + return nil, newError("The environment variable XRAY_ROUTER_API_GETSET is not set to 1.") + } + idx, rules, err := s.router.GetRule(ctx, request.Tag) + if err != nil { + return nil, err + } + return &GetRoutingRuleResponse{ + Rule: rules.(*router.RoutingRule), + Idx: int32(idx), + }, nil } func (s *routingServer) AddBalancer(ctx context.Context, request *AddBalancingRuleRequest) (*AddBalancingRuleResponse, error) { @@ -137,7 +171,13 @@ func (s *routingServer) RemoveBalancer(ctx context.Context, request *RemoveBalan } func (s *routingServer) GetBalancers(ctx context.Context, request *GetBalancerRequest) (*GetBalancerResponse, error) { - return nil, newError("not implement.") + balancers, err := s.router.GetBalancers(ctx) + if err != nil { + return nil, err + } + return &GetBalancerResponse{ + Balancing: balancers.([]*router.BalancingRule), + }, nil } func (s *routingServer) SubscribeRoutingStats(request *SubscribeRoutingStatsRequest, stream RoutingService_SubscribeRoutingStatsServer) error { diff --git a/app/router/command/command.pb.go b/app/router/command/command.pb.go index e25a187f8451..9f03339f950c 100644 --- a/app/router/command/command.pb.go +++ b/app/router/command/command.pb.go @@ -1,12 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 +// protoc-gen-go v1.25.0 // protoc v3.15.6 // source: app/router/command/command.proto package command import ( + proto "github.com/golang/protobuf/proto" router "github.com/xtls/xray-core/app/router" net "github.com/xtls/xray-core/common/net" protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -22,6 +23,10 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + // RoutingContext is the context with information relative to routing process. // It conforms to the structure of xray.features.routing.Context and // xray.features.routing.Route. @@ -747,6 +752,8 @@ type GetRoutingRuleRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` } func (x *GetRoutingRuleRequest) Reset() { @@ -781,12 +788,20 @@ func (*GetRoutingRuleRequest) Descriptor() ([]byte, []int) { return file_app_router_command_command_proto_rawDescGZIP(), []int{13} } +func (x *GetRoutingRuleRequest) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + type GetRoutingRuleResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Rule *router.RoutingRule `protobuf:"bytes,1,opt,name=rule,proto3" json:"rule,omitempty"` + Idx int32 `protobuf:"varint,2,opt,name=idx,proto3" json:"idx,omitempty"` } func (x *GetRoutingRuleResponse) Reset() { @@ -828,6 +843,13 @@ func (x *GetRoutingRuleResponse) GetRule() *router.RoutingRule { return nil } +func (x *GetRoutingRuleResponse) GetIdx() int32 { + if x != nil { + return x.Idx + } + return 0 +} + type AddBalancingRuleRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1134,7 +1156,7 @@ type GetBalancerResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Balancing []*router.BalancingRule `protobuf:"bytes,2,rep,name=balancing,proto3" json:"balancing,omitempty"` + Balancing []*router.BalancingRule `protobuf:"bytes,1,rep,name=balancing,proto3" json:"balancing,omitempty"` } func (x *GetBalancerResponse) Reset() { @@ -1309,136 +1331,139 @@ var file_app_router_command_command_proto_rawDesc = []byte{ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, + 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x29, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x4a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, - 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, - 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x22, - 0x57, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x09, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0x5c, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x30, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, - 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x09, 0x62, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x42, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6b, 0x0a, 0x19, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, + 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, + 0x69, 0x64, 0x78, 0x22, 0x57, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, + 0x0a, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x52, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x22, 0x1a, 0x0a, 0x18, + 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6b, 0x0a, 0x19, 0x41, 0x6c, 0x74, 0x65, + 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x3c, 0x0a, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x09, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x22, 0x1c, 0x0a, 0x1a, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x74, 0x61, 0x67, 0x12, 0x3c, 0x0a, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, - 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, - 0x67, 0x22, 0x1c, 0x0a, 0x1a, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x2e, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, - 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, - 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, - 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, - 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, - 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x22, 0x53, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x09, 0x62, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, - 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x09, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x22, 0x08, 0x0a, 0x06, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x32, 0xf7, 0x0a, 0x0a, 0x0e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7b, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, - 0x35, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, - 0x00, 0x30, 0x01, 0x12, 0x61, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x12, 0x29, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x52, 0x75, 0x6c, - 0x65, 0x12, 0x2e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x09, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x75, 0x6c, - 0x65, 0x12, 0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, - 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, - 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x6f, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x6f, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, + 0x74, 0x61, 0x67, 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x53, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x42, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3c, 0x0a, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x09, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x22, 0x08, 0x0a, + 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x32, 0xf7, 0x0a, 0x0a, 0x0e, 0x52, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7b, 0x0a, 0x15, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x12, 0x35, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x61, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x54, + 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x27, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x07, 0x41, 0x64, + 0x64, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, + 0x41, 0x64, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, + 0x41, 0x64, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x09, 0x41, 0x6c, 0x74, 0x65, + 0x72, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, + 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, + 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0a, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x31, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, - 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x6c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2e, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x74, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x30, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x6f, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x2f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x6f, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x12, 0x2f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, + 0x12, 0x2e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x72, 0x12, 0x30, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, + 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, + 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x0d, 0x41, 0x6c, 0x74, + 0x65, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x42, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x31, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x42, 0x61, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x0d, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x33, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, + 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x73, 0x12, 0x2b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, + 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x42, 0x67, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x78, 0x72, 0x61, - 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x7d, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x72, 0x12, 0x33, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, - 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x6b, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x73, - 0x12, 0x2b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, - 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x67, 0x0a, - 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x2c, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, - 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xaa, 0x02, 0x17, 0x58, - 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, + 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, + 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0xaa, 0x02, 0x17, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/app/router/command/command.proto b/app/router/command/command.proto index 5b3091a3f5ee..3a14ede1343e 100644 --- a/app/router/command/command.proto +++ b/app/router/command/command.proto @@ -95,10 +95,12 @@ message GetRoutingRulesResponse{ } message GetRoutingRuleRequest{ + string tag = 1; } message GetRoutingRuleResponse{ xray.app.router.RoutingRule rule = 1; + int32 idx = 2; } message AddBalancingRuleRequest{ @@ -122,7 +124,7 @@ message GetBalancerRequest{ } message GetBalancerResponse { - repeated xray.app.router.BalancingRule balancing = 2; + repeated xray.app.router.BalancingRule balancing = 1; } service RoutingService { diff --git a/app/router/condition.go b/app/router/condition.go index 8c5d1de87b1b..119762374e08 100644 --- a/app/router/condition.go +++ b/app/router/condition.go @@ -1,6 +1,7 @@ package router import ( + "os" "strings" "go.starlark.net/starlark" @@ -13,6 +14,7 @@ import ( type Condition interface { Apply(ctx routing.Context) bool + RestoreRoutingRule() interface{} } type ConditionChan []Condition @@ -37,6 +39,59 @@ func (v *ConditionChan) Apply(ctx routing.Context) bool { return true } +// RestoreRoutingRule Restore implements Condition. +func (v *ConditionChan) RestoreRoutingRule() interface{} { + rule := &RoutingRule{} + for _, condition := range *v { + cond := condition.RestoreRoutingRule() + switch condition.(type) { + case *AttributeMatcher: + { + rule.Attributes = cond.(string) + } + case *DomainMatcher: + { + rule.Domain = cond.([]*Domain) + } + case *InboundTagMatcher: + { + rule.InboundTag = cond.([]string) + } + case *MultiGeoIPMatcher: + { + if condition.(*MultiGeoIPMatcher).onSource { + rule.SourceGeoip = cond.([]*GeoIP) + } else { + rule.Geoip = cond.([]*GeoIP) + } + } + case NetworkMatcher: + { + rule.Networks = cond.([]net.Network) + } + case *PortMatcher: + { + if condition.(*PortMatcher).onSource { + rule.SourcePortList = cond.(*net.PortList) + } else { + rule.PortList = cond.(*net.PortList) + } + } + case *ProtocolMatcher: + { + rule.Protocol = cond.([]string) + } + case *UserMatcher: + { + rule.UserEmail = cond.([]string) + } + } + // fmt.Printf("%#v:={%#v}\n", condition, cond) + } + + return rule +} + func (v *ConditionChan) Len() int { return len(*v) } @@ -94,9 +149,28 @@ func (m *DomainMatcher) Apply(ctx routing.Context) bool { return m.ApplyDomain(strings.ToLower(domain)) } +// RestoreRoutingRule Restore implements Condition. +func (m *DomainMatcher) RestoreRoutingRule() interface{} { + domains := make([]*Domain, 0) + group := m.matchers.(*strmatcher.MatcherGroup) + restoreDomains := group.Restore() + for i := 1; i <= len(restoreDomains); i++ { + if rd, ok := restoreDomains[uint32(i)]; ok { + domains = append(domains, &Domain{ + Type: Domain_Type(rd.DomainType), + Value: rd.Value, + }) + } + } + + return domains +} + type MultiGeoIPMatcher struct { matchers []*GeoIPMatcher onSource bool + // geoips routing API requires this backup. + geoips []*GeoIP } func NewMultiGeoIPMatcher(geoips []*GeoIP, onSource bool) (*MultiGeoIPMatcher, error) { @@ -114,6 +188,11 @@ func NewMultiGeoIPMatcher(geoips []*GeoIP, onSource bool) (*MultiGeoIPMatcher, e onSource: onSource, } + // The routing API requires a backup content + if enable := os.Getenv("XRAY_ROUTER_API_GETSET"); enable == "1" { + matcher.geoips = geoips + } + return matcher, nil } @@ -135,6 +214,11 @@ func (m *MultiGeoIPMatcher) Apply(ctx routing.Context) bool { return false } +// RestoreRoutingRule Restore implements Condition. +func (m *MultiGeoIPMatcher) RestoreRoutingRule() interface{} { + return m.geoips +} + type PortMatcher struct { port net.MemoryPortList onSource bool @@ -157,8 +241,15 @@ func (v *PortMatcher) Apply(ctx routing.Context) bool { } } +// RestoreRoutingRule Restore implements Condition. +func (v *PortMatcher) RestoreRoutingRule() interface{} { + return v.port.RestorePortList() +} + type NetworkMatcher struct { list [8]bool + // network routing API requires this backup. + network []net.Network } func NewNetworkMatcher(network []net.Network) NetworkMatcher { @@ -166,6 +257,10 @@ func NewNetworkMatcher(network []net.Network) NetworkMatcher { for _, n := range network { matcher.list[int(n)] = true } + // The routing API requires a backup content + if enable := os.Getenv("XRAY_ROUTER_API_GETSET"); enable == "1" { + matcher.network = network + } return matcher } @@ -174,6 +269,11 @@ func (v NetworkMatcher) Apply(ctx routing.Context) bool { return v.list[int(ctx.GetNetwork())] } +// RestoreRoutingRule Restore implements Condition. +func (v NetworkMatcher) RestoreRoutingRule() interface{} { + return v.network +} + type UserMatcher struct { user []string } @@ -204,6 +304,11 @@ func (v *UserMatcher) Apply(ctx routing.Context) bool { return false } +// RestoreRoutingRule Restore implements Condition. +func (v *UserMatcher) RestoreRoutingRule() interface{} { + return v.user +} + type InboundTagMatcher struct { tags []string } @@ -234,6 +339,11 @@ func (v *InboundTagMatcher) Apply(ctx routing.Context) bool { return false } +// RestoreRoutingRule Restore implements Condition. +func (v *InboundTagMatcher) RestoreRoutingRule() interface{} { + return v.tags +} + type ProtocolMatcher struct { protocols []string } @@ -266,8 +376,15 @@ func (m *ProtocolMatcher) Apply(ctx routing.Context) bool { return false } +// RestoreRoutingRule Restore implements Condition. +func (m *ProtocolMatcher) RestoreRoutingRule() interface{} { + return m.protocols +} + type AttributeMatcher struct { program *starlark.Program + // code routing API requires this backup. + code string } func NewAttributeMatcher(code string) (*AttributeMatcher, error) { @@ -281,9 +398,15 @@ func NewAttributeMatcher(code string) (*AttributeMatcher, error) { if err != nil { return nil, err } - return &AttributeMatcher{ + + attr := &AttributeMatcher{ program: p, - }, nil + } + // The routing API requires a backup content + if addr := os.Getenv("XRAY_ROUTER_API_GETSET"); addr != "" { + attr.code = code + } + return attr, nil } // Match implements attributes matching. @@ -315,3 +438,8 @@ func (m *AttributeMatcher) Apply(ctx routing.Context) bool { } return m.Match(attributes) } + +// RestoreRoutingRule Restore implements Condition. +func (m *AttributeMatcher) RestoreRoutingRule() interface{} { + return m.code +} diff --git a/app/router/condition_test.go b/app/router/condition_test.go index 3f7185e6633c..39bfef4bf463 100644 --- a/app/router/condition_test.go +++ b/app/router/condition_test.go @@ -444,3 +444,113 @@ func BenchmarkMultiGeoIPMatcher(b *testing.B) { _ = matcher.Apply(ctx) } } + +func TestConditionChan_RestoreCondition(t *testing.T) { + rule := &RoutingRule{ + TargetTag: &RoutingRule_OutboundTag{OutboundTag: "test"}, + Domain: []*Domain{ + { + Value: "example.com", + Type: Domain_Plain, + }, + { + Value: "google.com", + Type: Domain_Domain, + }, + { + Value: "^facebook\\.com$", + Type: Domain_Regex, + }, + }, + Geoip: []*GeoIP{ + { + Cidr: []*CIDR{ + { + Ip: []byte{8, 8, 8, 8}, + Prefix: 32, + }, + { + Ip: []byte{8, 8, 8, 8}, + Prefix: 32, + }, + { + Ip: net.ParseAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334").IP(), + Prefix: 128, + }, + }, + }, + }, + PortList: &net.PortList{ + Range: []*net.PortRange{ + {From: 443, To: 443}, + {From: 1000, To: 1100}, + }, + }, + Networks: []net.Network{net.Network_TCP}, + SourceGeoip: []*GeoIP{{CountryCode: "private", Cidr: []*CIDR{{Ip: []byte{127, 0, 0, 0}, Prefix: 8}}}}, + SourcePortList: &net.PortList{Range: []*net.PortRange{{From: 9999, To: 9999}}}, + UserEmail: []string{"love@xray.com"}, + InboundTag: []string{"tag-vmess"}, + Protocol: []string{"http", "tls", "bittorrent"}, + Attributes: "attrs[':method'] == 'GET'", + Tag: "test", + } + + condition, err := rule.BuildCondition() + if err != nil { + common.Must(err) + return + } + + rr := condition.RestoreRoutingRule().(*RoutingRule) + + if len(rule.Domain) != len(rr.Domain) { + t.Fatal("The Domain are different") + return + } + + if len(rule.Geoip) != len(rr.Geoip) { + t.Fatal("The Geoip are different") + return + } + + if len(rule.PortList.Range) != len(rr.PortList.Range) { + t.Fatal("The Geoip are different") + return + } + + if len(rule.Networks) != len(rr.Networks) { + t.Fatal("The Networks are different") + return + } + + if len(rule.SourceGeoip) != len(rr.SourceGeoip) { + t.Fatal("The SourceGeoip are different") + return + } + + if len(rule.SourcePortList.Range) != len(rr.SourcePortList.Range) { + t.Fatal("The SourcePortList are different") + return + } + + if len(rule.UserEmail) != len(rr.UserEmail) { + t.Fatal("The UserEmail are different") + return + } + + if len(rule.InboundTag) != len(rr.InboundTag) { + t.Fatal("The InboundTag are different") + return + } + + if len(rule.Protocol) != len(rr.Protocol) { + t.Fatal("The Protocol are different") + return + } + + if rule.Attributes != rr.Attributes { + t.Fatal("The Attributes are different") + return + } +} diff --git a/app/router/config.go b/app/router/config.go index 37cf1a95c5d0..face053cba5a 100644 --- a/app/router/config.go +++ b/app/router/config.go @@ -65,6 +65,23 @@ func (r *Rule) Apply(ctx routing.Context) bool { return r.Condition.Apply(ctx) } +// RestoreRoutingRule Restore implements Condition. +func (r *Rule) RestoreRoutingRule() interface{} { + rule := r.Condition.RestoreRoutingRule().(*RoutingRule) + rule.Tag = r.Tag + if r.Balancer != nil { + rule.TargetTag = &RoutingRule_BalancingTag{ + BalancingTag: rule.Tag, + } + } else { + rule.TargetTag = &RoutingRule_OutboundTag{ + OutboundTag: rule.Tag, + } + } + + return rule +} + func (rr *RoutingRule) BuildCondition() (Condition, error) { conds := NewConditionChan() diff --git a/app/router/router.go b/app/router/router.go index a6a7ecb4fcdb..2fffa1ed6b62 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -125,7 +125,7 @@ func (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routing.Context, return nil, ctx, common.ErrNoClue } -// FindRule +// FindRule Find the corresponding rule based on Tag func (r *Router) FindRule(tag string) (idx int, rule *Rule) { idx = -1 for k, v := range r.rules { @@ -210,7 +210,7 @@ func (r *Router) RemoveRule(ctx context.Context, tag string) error { return nil } -// SetRules not implement . +// SetRules . func (r *Router) SetRules(ctx context.Context, rules interface{}) error { rrs := rules.([]*RoutingRule) @@ -235,14 +235,30 @@ func (r *Router) SetRules(ctx context.Context, rules interface{}) error { return nil } -// GetRules not implement . +// GetRules . func (r *Router) GetRules(ctx context.Context) (interface{}, error) { - return nil, newError("not implement.") + rules := make([]*RoutingRule, 0, len(r.rules)) + for _, rr := range r.rules { + rule := rr.RestoreRoutingRule().(*RoutingRule) + rules = append(rules, rule) + } + + newError("[", len(rules), "] rules were retrieved through the API").WriteToLog(session.ExportIDToError(ctx)) + return rules, nil } // GetRule implement the manager interface. -func (r *Router) GetRule(ctx context.Context, tag string) (interface{}, error) { - return nil, newError("not implement.") +func (r *Router) GetRule(ctx context.Context, tag string) (int, interface{}, error) { + idx, rr := r.FindRule(tag) + if idx == -1 { + err := newError("This [", tag, "] routing rule does not exist") + err.WriteToLog(session.ExportIDToError(ctx)) + return -1, nil, err + } + + rule := rr.RestoreRoutingRule() + newError("Get [", tag, "] routing rule through the API").WriteToLog(session.ExportIDToError(ctx)) + return idx, rule, nil } // AddBalancer implement the manager interface. @@ -310,9 +326,17 @@ func (r *Router) RemoveBalancer(ctx context.Context, tag string) error { return nil } -// GetBalancers not implement. +// GetBalancers . func (r *Router) GetBalancers(ctx context.Context) (interface{}, error) { - return nil, newError("not implement.") + balancers := make([]*BalancingRule, 0, len(r.balancers)) + for tag, balancer := range r.balancers { + balancers = append(balancers, &BalancingRule{ + Tag: tag, + OutboundSelector: balancer.selectors, + }) + } + newError("[", len(balancers), "] rules were retrieved through the API").WriteToLog(session.ExportIDToError(ctx)) + return balancers, nil } // Start implements common.Runnable. diff --git a/app/router/router_test.go b/app/router/router_test.go index bb4346228194..3cc4137b3605 100644 --- a/app/router/router_test.go +++ b/app/router/router_test.go @@ -337,3 +337,125 @@ func TestRouter_RemoveRoutingRule(t *testing.T) { t.Error("expect tag 'test', bug actually ", tag) } } + +func TestRouter_SetRules(t *testing.T) { + config := &Config{} + + mockCtl := gomock.NewController(t) + defer mockCtl.Finish() + + mockDNS := mocks.NewDNSClient(mockCtl) + mockOhm := mocks.NewOutboundManager(mockCtl) + mockHs := mocks.NewOutboundHandlerSelector(mockCtl) + + r := new(Router) + common.Must(r.Init(config, mockDNS, &mockOutboundManager{ + Manager: mockOhm, + HandlerSelector: mockHs, + })) + + ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)}) + rules := make([]*RoutingRule, 0, 2) + rules = append(rules, &RoutingRule{ + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "test", + }, + Domain: []*Domain{ + { + Type: Domain_Domain, + Value: "example.com", + }, + }, + Tag: "test", + }) + err := r.SetRules(ctx, rules) + common.Must(err) + + route, err := r.PickRoute(routing_session.AsRoutingContext(ctx)) + common.Must(err) + if tag := route.GetOutboundTag(); tag != "test" { + t.Error("expect tag 'test', bug actually ", tag) + } +} + +func TestRouter_GetRules(t *testing.T) { + config := &Config{} + + mockCtl := gomock.NewController(t) + defer mockCtl.Finish() + + mockDNS := mocks.NewDNSClient(mockCtl) + mockOhm := mocks.NewOutboundManager(mockCtl) + mockHs := mocks.NewOutboundHandlerSelector(mockCtl) + + r := new(Router) + common.Must(r.Init(config, mockDNS, &mockOutboundManager{ + Manager: mockOhm, + HandlerSelector: mockHs, + })) + + ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)}) + rules := make([]*RoutingRule, 0, 2) + rules = append(rules, &RoutingRule{ + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "test", + }, + Domain: []*Domain{ + { + Type: Domain_Domain, + Value: "example.com", + }, + }, + Tag: "test", + }) + err := r.SetRules(ctx, rules) + common.Must(err) + + getRules, err := r.GetRules(ctx) + common.Must(err) + rr := getRules.([]*RoutingRule)[0] + if tag := rr.GetOutboundTag(); tag != "test" { + t.Error("expect tag 'test', bug actually ", tag) + } +} + +func TestRouter_GetRule(t *testing.T) { + config := &Config{} + + mockCtl := gomock.NewController(t) + defer mockCtl.Finish() + + mockDNS := mocks.NewDNSClient(mockCtl) + mockOhm := mocks.NewOutboundManager(mockCtl) + mockHs := mocks.NewOutboundHandlerSelector(mockCtl) + + r := new(Router) + common.Must(r.Init(config, mockDNS, &mockOutboundManager{ + Manager: mockOhm, + HandlerSelector: mockHs, + })) + + ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)}) + rules := make([]*RoutingRule, 0, 2) + rules = append(rules, &RoutingRule{ + TargetTag: &RoutingRule_OutboundTag{ + OutboundTag: "test", + }, + Domain: []*Domain{ + { + Type: Domain_Domain, + Value: "example.com", + }, + }, + Tag: "test", + }) + err := r.SetRules(ctx, rules) + common.Must(err) + + _, getRules, err := r.GetRule(ctx, "test") + common.Must(err) + rr := getRules.(*RoutingRule) + if tag := rr.GetOutboundTag(); tag != "test" { + t.Error("expect tag 'test', bug actually ", tag) + } +} diff --git a/common/net/port.go b/common/net/port.go index 2a0bf637056f..7b58feb8b3ec 100644 --- a/common/net/port.go +++ b/common/net/port.go @@ -93,3 +93,11 @@ func (mpl MemoryPortList) Contains(port Port) bool { } return false } + +func (mpl MemoryPortList) RestorePortList() *PortList { + list := &PortList{} + for _, pr := range mpl { + list.Range = append(list.Range, &PortRange{From: uint32(pr.From), To: uint32(pr.To)}) + } + return list +} diff --git a/common/strmatcher/RestoreDomain.go b/common/strmatcher/RestoreDomain.go new file mode 100644 index 000000000000..be49898f1834 --- /dev/null +++ b/common/strmatcher/RestoreDomain.go @@ -0,0 +1,15 @@ +package strmatcher + +// RestoreDomainType of domain value. +type RestoreDomainType int32 + +const ( + // RestoreDomainTypePlain The value is used as is. + RestoreDomainTypePlain RestoreDomainType = 0 + // RestoreDomainTypeRegex The value is used as a regular expression. + RestoreDomainTypeRegex RestoreDomainType = 1 + // RestoreDomainTypeDomain The value is a root domain. + RestoreDomainTypeDomain RestoreDomainType = 2 + // RestoreDomainTypeFull The value is a domain. + RestoreDomainTypeFull RestoreDomainType = 3 +) diff --git a/common/strmatcher/domain_matcher.go b/common/strmatcher/domain_matcher.go index ae8e65bc211e..bf115a663486 100644 --- a/common/strmatcher/domain_matcher.go +++ b/common/strmatcher/domain_matcher.go @@ -96,3 +96,33 @@ func (g *DomainMatcherGroup) Match(domain string) []uint32 { return result } } + +func (g *DomainMatcherGroup) Restore() map[uint32]*RestoreDomain { + if g.root == nil { + return nil + } + domains := make(map[uint32]*RestoreDomain) + recursive(g.root, "", domains) + return domains +} + +func recursive(n *node, postfix string, domains map[uint32]*RestoreDomain) { + if len(n.values) > 0 { + domains[n.values[0]] = &RestoreDomain{ + Value: postfix, + DomainType: RestoreDomainTypeDomain, + } + + if len(n.sub) == 0 { + return + } + } + + for key, subNode := range n.sub { + subDomain := key + if postfix != "" { + subDomain = key + postfix + } + recursive(subNode, subDomain, domains) + } +} diff --git a/common/strmatcher/domain_matcher_test.go b/common/strmatcher/domain_matcher_test.go index 5a8ca35b2460..13fc5a2e8db0 100644 --- a/common/strmatcher/domain_matcher_test.go +++ b/common/strmatcher/domain_matcher_test.go @@ -2,6 +2,7 @@ package strmatcher_test import ( "reflect" + "strconv" "testing" . "github.com/xtls/xray-core/common/strmatcher" @@ -74,3 +75,17 @@ func TestEmptyDomainMatcherGroup(t *testing.T) { t.Error("Expect [], but ", r) } } + +func TestRestoreDomainMatcher(t *testing.T) { + g := new(DomainMatcherGroup) + + for i := 1; i <= 20; i++ { + g.Add(strconv.Itoa(i)+".example.com", uint32(i)) + } + + m := g.Restore() + + if len(m) != 10 { + t.Error("Restore Domain failed.") + } +} diff --git a/common/strmatcher/full_matcher.go b/common/strmatcher/full_matcher.go index e00d02aa9c7d..20531cda96aa 100644 --- a/common/strmatcher/full_matcher.go +++ b/common/strmatcher/full_matcher.go @@ -23,3 +23,17 @@ func (g *FullMatcherGroup) Match(str string) []uint32 { return g.matchers[str] } + +func (g *FullMatcherGroup) Restore() map[uint32]*RestoreDomain { + if g.matchers == nil { + return nil + } + m := make(map[uint32]*RestoreDomain) + for domain, idx := range g.matchers { + m[idx[0]] = &RestoreDomain{ + Value: domain, + DomainType: RestoreDomainTypeFull, + } + } + return m +} diff --git a/common/strmatcher/matchers.go b/common/strmatcher/matchers.go index b5ab09c4cb9f..3eb5e17b1bb3 100644 --- a/common/strmatcher/matchers.go +++ b/common/strmatcher/matchers.go @@ -15,6 +15,13 @@ func (m fullMatcher) String() string { return "full:" + string(m) } +func (m fullMatcher) Restore() *RestoreDomain { + return &RestoreDomain{ + Value: string(m), + DomainType: RestoreDomainTypePlain, + } +} + type substrMatcher string func (m substrMatcher) Match(s string) bool { @@ -25,6 +32,13 @@ func (m substrMatcher) String() string { return "keyword:" + string(m) } +func (m substrMatcher) Restore() *RestoreDomain { + return &RestoreDomain{ + Value: string(m), + DomainType: RestoreDomainTypePlain, + } +} + type domainMatcher string func (m domainMatcher) Match(s string) bool { @@ -39,6 +53,13 @@ func (m domainMatcher) String() string { return "domain:" + string(m) } +func (m domainMatcher) Restore() *RestoreDomain { + return &RestoreDomain{ + Value: string(m), + DomainType: RestoreDomainTypeDomain, + } +} + type regexMatcher struct { pattern *regexp.Regexp } @@ -50,3 +71,10 @@ func (m *regexMatcher) Match(s string) bool { func (m *regexMatcher) String() string { return "regexp:" + m.pattern.String() } + +func (m *regexMatcher) Restore() *RestoreDomain { + return &RestoreDomain{ + Value: m.pattern.String(), + DomainType: RestoreDomainTypeRegex, + } +} diff --git a/common/strmatcher/strmatcher.go b/common/strmatcher/strmatcher.go index 9728047d5632..d3c39af6d53a 100644 --- a/common/strmatcher/strmatcher.go +++ b/common/strmatcher/strmatcher.go @@ -9,6 +9,7 @@ type Matcher interface { // Match returns true if the given string matches a predefined pattern. Match(string) bool String() string + Restore() *RestoreDomain } // Type is the type of the matcher. @@ -51,6 +52,8 @@ func (t Type) New(pattern string) (Matcher, error) { type IndexMatcher interface { // Match returns the index of a matcher that matches the input. It returns empty array if no such matcher exists. Match(input string) []uint32 + // Restore Returns the domain + Restore() map[uint32]*RestoreDomain } type matcherEntry struct { @@ -67,6 +70,34 @@ type MatcherGroup struct { otherMatchers []matcherEntry } +type RestoreDomain struct { + Value string + DomainType RestoreDomainType +} + +func (g *MatcherGroup) Restore() map[uint32]*RestoreDomain { + if g.count == 0 { + return nil + } + m := make(map[uint32]*RestoreDomain) + fullMatchers := g.fullMatcher.Restore() + mergeMap(m, fullMatchers) + domainMatchers := g.domainMatcher.Restore() + mergeMap(m, domainMatchers) + + for _, matcher := range g.otherMatchers { + m[matcher.id] = matcher.m.Restore() + } + + return m +} + +func mergeMap(dst, src map[uint32]*RestoreDomain) { + for idx, domain := range src { + dst[idx] = domain + } +} + // Add adds a new Matcher into the MatcherGroup, and returns its index. The index will never be 0. func (g *MatcherGroup) Add(m Matcher) uint32 { g.count++ diff --git a/features/routing/router.go b/features/routing/router.go index d0b61e96a68c..c59b4d76e12b 100644 --- a/features/routing/router.go +++ b/features/routing/router.go @@ -78,8 +78,8 @@ func (DefaultRouter) GetRules(ctx context.Context) (interface{}, error) { } // GetRule implements Router. -func (DefaultRouter) GetRule(ctx context.Context, tag string) (interface{}, error) { - return nil, common.ErrNoClue +func (DefaultRouter) GetRule(ctx context.Context, tag string) (int, interface{}, error) { + return -1, nil, common.ErrNoClue } // AddBalancer implements Router. @@ -123,14 +123,14 @@ type Manager interface { AlterRule(ctx context.Context, tag string, routingRule interface{}) error // RemoveRule Remove the specified routing rule RemoveRule(ctx context.Context, tag string) error - // SetRules + // SetRules . SetRules(ctx context.Context, rules interface{}) error - // GetRules + // GetRules . GetRules(ctx context.Context) (interface{}, error) - // GetRule - GetRule(ctx context.Context, tag string) (interface{}, error) + // GetRule . + GetRule(ctx context.Context, tag string) (int, interface{}, error) - // Balancer adds the given balancing rules to this manager. + // AddBalancer Balancer adds the given balancing rules to this manager. AddBalancer(ctx context.Context, balancingRule interface{}, handler outbound.Manager) error // AlterBalancer Modifies the specified balancing rule AlterBalancer(ctx context.Context, tag string, balancingRule interface{}, handler outbound.Manager) error From ebfdcfc8b53fde0d1c430c60ff7ce3524f149ec3 Mon Sep 17 00:00:00 2001 From: tat5522 <81008809+tat5522@users.noreply.github.com> Date: Thu, 22 Apr 2021 11:06:15 +0800 Subject: [PATCH 7/9] implementation routing get and set api. --- app/router/condition.go | 25 ++++----- app/router/condition_test.go | 1 + app/router/config.go | 14 +++--- app/router/config.pb.go | 78 ++++++++++++++++------------- app/router/router_test.go | 3 ++ common/strmatcher/RestoreDomain.go | 15 ------ common/strmatcher/domain_matcher.go | 30 ----------- common/strmatcher/full_matcher.go | 14 ------ common/strmatcher/matchers.go | 28 ----------- common/strmatcher/strmatcher.go | 31 ------------ 10 files changed, 64 insertions(+), 175 deletions(-) delete mode 100644 common/strmatcher/RestoreDomain.go diff --git a/app/router/condition.go b/app/router/condition.go index 1a20aae8339f..fd2098bd95a4 100644 --- a/app/router/condition.go +++ b/app/router/condition.go @@ -119,6 +119,8 @@ func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) { type DomainMatcher struct { matchers strmatcher.IndexMatcher + // domains routing API requires this backup. + domains []*Domain } func NewMphMatcherGroup(domains []*Domain) (*DomainMatcher, error) { @@ -134,9 +136,14 @@ func NewMphMatcherGroup(domains []*Domain) (*DomainMatcher, error) { } } g.Build() - return &DomainMatcher{ + matcher := &DomainMatcher{ matchers: g, - }, nil + } + // The routing API requires a backup content + if enable := os.Getenv("XRAY_ROUTER_API_GETSET"); enable == "1" { + matcher.domains = domains + } + return matcher, nil } func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) { @@ -169,19 +176,7 @@ func (m *DomainMatcher) Apply(ctx routing.Context) bool { // RestoreRoutingRule Restore implements Condition. func (m *DomainMatcher) RestoreRoutingRule() interface{} { - domains := make([]*Domain, 0) - group := m.matchers.(*strmatcher.MatcherGroup) - restoreDomains := group.Restore() - for i := 1; i <= len(restoreDomains); i++ { - if rd, ok := restoreDomains[uint32(i)]; ok { - domains = append(domains, &Domain{ - Type: Domain_Type(rd.DomainType), - Value: rd.Value, - }) - } - } - - return domains + return m.domains } type MultiGeoIPMatcher struct { diff --git a/app/router/condition_test.go b/app/router/condition_test.go index 691a0553e01a..38f00750c477 100644 --- a/app/router/condition_test.go +++ b/app/router/condition_test.go @@ -536,6 +536,7 @@ func BenchmarkMultiGeoIPMatcher(b *testing.B) { } func TestConditionChan_RestoreCondition(t *testing.T) { + _ = os.Setenv("XRAY_ROUTER_API_GETSET", "1") rule := &RoutingRule{ TargetTag: &RoutingRule_OutboundTag{OutboundTag: "test"}, Domain: []*Domain{ diff --git a/app/router/config.go b/app/router/config.go index 8c4d75d9fa9f..2cb8933d2666 100644 --- a/app/router/config.go +++ b/app/router/config.go @@ -47,10 +47,11 @@ func (l *CIDRList) Swap(i int, j int) { } type Rule struct { - Tag string - TargetTag string - Balancer *Balancer - Condition Condition + Tag string + TargetTag string + DomainMatcher string + Balancer *Balancer + Condition Condition } func (r *Rule) GetTargetTag() (string, error) { @@ -69,6 +70,7 @@ func (r *Rule) Apply(ctx routing.Context) bool { func (r *Rule) RestoreRoutingRule() interface{} { rule := r.Condition.RestoreRoutingRule().(*RoutingRule) rule.Tag = r.Tag + rule.DomainMatcher = r.DomainMatcher if r.Balancer != nil { rule.TargetTag = &RoutingRule_BalancingTag{ BalancingTag: rule.Tag, @@ -103,7 +105,6 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) { newError("MphDomainMatcher is enabled for ", len(rr.Domain), " domain rule(s)").AtDebug().WriteToLog() conds.Add(matcher) } - } if len(rr.UserEmail) > 0 { @@ -185,7 +186,8 @@ func (rr *RoutingRule) Build(r *Router) (*Rule, error) { tag = u.String() } rule := &Rule{ - Tag: tag, + Tag: tag, + DomainMatcher: rr.DomainMatcher, } btag := rr.GetBalancingTag() diff --git a/app/router/config.pb.go b/app/router/config.pb.go index 6c38a6d2b726..6e3d8ba5ea0e 100644 --- a/app/router/config.pb.go +++ b/app/router/config.pb.go @@ -1,12 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.14.0 +// protoc-gen-go v1.25.0 +// protoc v3.15.6 // source: app/router/config.proto package router import ( + proto "github.com/golang/protobuf/proto" net "github.com/xtls/xray-core/common/net" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -21,6 +22,10 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + // Type of domain value. type Domain_Type int32 @@ -957,7 +962,7 @@ var file_app_router_config_proto_rawDesc = []byte{ 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x22, 0x8e, 0x06, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x79, 0x22, 0xd8, 0x06, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x25, 0x0a, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, @@ -1006,39 +1011,40 @@ var file_app_router_config_proto_rawDesc = []byte{ 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x11, 0x20, 0x01, - 0x75, 0x74, 0x65, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, - 0x61, 0x67, 0x22, 0x4e, 0x0a, 0x0d, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x2b, 0x0a, 0x11, - 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, - 0x6f, 0x72, 0x22, 0x9b, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4f, 0x0a, - 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, - 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x30, - 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, - 0x12, 0x45, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, - 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, - 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x49, 0x70, 0x10, 0x01, 0x12, 0x10, - 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x02, - 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x70, 0x4f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x03, - 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, - 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0xaa, - 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, + 0x74, 0x61, 0x67, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x42, 0x0c, + 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x4e, 0x0a, 0x0d, + 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, + 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x9b, 0x02, 0x0a, + 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x30, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x22, 0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a, + 0x05, 0x55, 0x73, 0x65, 0x49, 0x70, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66, + 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x70, + 0x4f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x03, 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, + 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, + 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0xaa, 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, + 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/app/router/router_test.go b/app/router/router_test.go index 3cc4137b3605..269f9553df49 100644 --- a/app/router/router_test.go +++ b/app/router/router_test.go @@ -2,6 +2,7 @@ package router_test import ( "context" + "os" "testing" "github.com/golang/mock/gomock" @@ -379,6 +380,7 @@ func TestRouter_SetRules(t *testing.T) { } func TestRouter_GetRules(t *testing.T) { + _ = os.Setenv("XRAY_ROUTER_API_GETSET", "1") config := &Config{} mockCtl := gomock.NewController(t) @@ -420,6 +422,7 @@ func TestRouter_GetRules(t *testing.T) { } func TestRouter_GetRule(t *testing.T) { + _ = os.Setenv("XRAY_ROUTER_API_GETSET", "1") config := &Config{} mockCtl := gomock.NewController(t) diff --git a/common/strmatcher/RestoreDomain.go b/common/strmatcher/RestoreDomain.go deleted file mode 100644 index be49898f1834..000000000000 --- a/common/strmatcher/RestoreDomain.go +++ /dev/null @@ -1,15 +0,0 @@ -package strmatcher - -// RestoreDomainType of domain value. -type RestoreDomainType int32 - -const ( - // RestoreDomainTypePlain The value is used as is. - RestoreDomainTypePlain RestoreDomainType = 0 - // RestoreDomainTypeRegex The value is used as a regular expression. - RestoreDomainTypeRegex RestoreDomainType = 1 - // RestoreDomainTypeDomain The value is a root domain. - RestoreDomainTypeDomain RestoreDomainType = 2 - // RestoreDomainTypeFull The value is a domain. - RestoreDomainTypeFull RestoreDomainType = 3 -) diff --git a/common/strmatcher/domain_matcher.go b/common/strmatcher/domain_matcher.go index bf115a663486..ae8e65bc211e 100644 --- a/common/strmatcher/domain_matcher.go +++ b/common/strmatcher/domain_matcher.go @@ -96,33 +96,3 @@ func (g *DomainMatcherGroup) Match(domain string) []uint32 { return result } } - -func (g *DomainMatcherGroup) Restore() map[uint32]*RestoreDomain { - if g.root == nil { - return nil - } - domains := make(map[uint32]*RestoreDomain) - recursive(g.root, "", domains) - return domains -} - -func recursive(n *node, postfix string, domains map[uint32]*RestoreDomain) { - if len(n.values) > 0 { - domains[n.values[0]] = &RestoreDomain{ - Value: postfix, - DomainType: RestoreDomainTypeDomain, - } - - if len(n.sub) == 0 { - return - } - } - - for key, subNode := range n.sub { - subDomain := key - if postfix != "" { - subDomain = key + postfix - } - recursive(subNode, subDomain, domains) - } -} diff --git a/common/strmatcher/full_matcher.go b/common/strmatcher/full_matcher.go index 20531cda96aa..e00d02aa9c7d 100644 --- a/common/strmatcher/full_matcher.go +++ b/common/strmatcher/full_matcher.go @@ -23,17 +23,3 @@ func (g *FullMatcherGroup) Match(str string) []uint32 { return g.matchers[str] } - -func (g *FullMatcherGroup) Restore() map[uint32]*RestoreDomain { - if g.matchers == nil { - return nil - } - m := make(map[uint32]*RestoreDomain) - for domain, idx := range g.matchers { - m[idx[0]] = &RestoreDomain{ - Value: domain, - DomainType: RestoreDomainTypeFull, - } - } - return m -} diff --git a/common/strmatcher/matchers.go b/common/strmatcher/matchers.go index 3eb5e17b1bb3..b5ab09c4cb9f 100644 --- a/common/strmatcher/matchers.go +++ b/common/strmatcher/matchers.go @@ -15,13 +15,6 @@ func (m fullMatcher) String() string { return "full:" + string(m) } -func (m fullMatcher) Restore() *RestoreDomain { - return &RestoreDomain{ - Value: string(m), - DomainType: RestoreDomainTypePlain, - } -} - type substrMatcher string func (m substrMatcher) Match(s string) bool { @@ -32,13 +25,6 @@ func (m substrMatcher) String() string { return "keyword:" + string(m) } -func (m substrMatcher) Restore() *RestoreDomain { - return &RestoreDomain{ - Value: string(m), - DomainType: RestoreDomainTypePlain, - } -} - type domainMatcher string func (m domainMatcher) Match(s string) bool { @@ -53,13 +39,6 @@ func (m domainMatcher) String() string { return "domain:" + string(m) } -func (m domainMatcher) Restore() *RestoreDomain { - return &RestoreDomain{ - Value: string(m), - DomainType: RestoreDomainTypeDomain, - } -} - type regexMatcher struct { pattern *regexp.Regexp } @@ -71,10 +50,3 @@ func (m *regexMatcher) Match(s string) bool { func (m *regexMatcher) String() string { return "regexp:" + m.pattern.String() } - -func (m *regexMatcher) Restore() *RestoreDomain { - return &RestoreDomain{ - Value: m.pattern.String(), - DomainType: RestoreDomainTypeRegex, - } -} diff --git a/common/strmatcher/strmatcher.go b/common/strmatcher/strmatcher.go index c78ff244d5e3..294e6e73bd92 100644 --- a/common/strmatcher/strmatcher.go +++ b/common/strmatcher/strmatcher.go @@ -9,7 +9,6 @@ type Matcher interface { // Match returns true if the given string matches a predefined pattern. Match(string) bool String() string - Restore() *RestoreDomain } // Type is the type of the matcher. @@ -53,8 +52,6 @@ func (t Type) New(pattern string) (Matcher, error) { type IndexMatcher interface { // Match returns the index of a matcher that matches the input. It returns empty array if no such matcher exists. Match(input string) []uint32 - // Restore Returns the domain - Restore() map[uint32]*RestoreDomain } type matcherEntry struct { @@ -71,34 +68,6 @@ type MatcherGroup struct { otherMatchers []matcherEntry } -type RestoreDomain struct { - Value string - DomainType RestoreDomainType -} - -func (g *MatcherGroup) Restore() map[uint32]*RestoreDomain { - if g.count == 0 { - return nil - } - m := make(map[uint32]*RestoreDomain) - fullMatchers := g.fullMatcher.Restore() - mergeMap(m, fullMatchers) - domainMatchers := g.domainMatcher.Restore() - mergeMap(m, domainMatchers) - - for _, matcher := range g.otherMatchers { - m[matcher.id] = matcher.m.Restore() - } - - return m -} - -func mergeMap(dst, src map[uint32]*RestoreDomain) { - for idx, domain := range src { - dst[idx] = domain - } -} - // Add adds a new Matcher into the MatcherGroup, and returns its index. The index will never be 0. func (g *MatcherGroup) Add(m Matcher) uint32 { g.count++ From 2c10a8fe288937f7840a9dcbfba21e0ecf44594a Mon Sep 17 00:00:00 2001 From: tat5522 <81008809+tat5522@users.noreply.github.com> Date: Thu, 22 Apr 2021 11:26:07 +0800 Subject: [PATCH 8/9] rename variable. --- app/router/condition.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/router/condition.go b/app/router/condition.go index fd2098bd95a4..37fe42414071 100644 --- a/app/router/condition.go +++ b/app/router/condition.go @@ -416,7 +416,7 @@ func NewAttributeMatcher(code string) (*AttributeMatcher, error) { program: p, } // The routing API requires a backup content - if addr := os.Getenv("XRAY_ROUTER_API_GETSET"); addr != "" { + if enable := os.Getenv("XRAY_ROUTER_API_GETSET"); enable != "" { attr.code = code } return attr, nil From 330c7e83d3099aff77b21aa12710e0ae620ba70b Mon Sep 17 00:00:00 2001 From: tat5522 <81008809+tat5522@users.noreply.github.com> Date: Thu, 22 Apr 2021 11:50:55 +0800 Subject: [PATCH 9/9] modify TestDomainSniffing target github => apple .fix domain matcher test bug. --- common/strmatcher/domain_matcher_test.go | 15 --------------- testing/scenarios/feature_test.go | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/common/strmatcher/domain_matcher_test.go b/common/strmatcher/domain_matcher_test.go index 13fc5a2e8db0..5a8ca35b2460 100644 --- a/common/strmatcher/domain_matcher_test.go +++ b/common/strmatcher/domain_matcher_test.go @@ -2,7 +2,6 @@ package strmatcher_test import ( "reflect" - "strconv" "testing" . "github.com/xtls/xray-core/common/strmatcher" @@ -75,17 +74,3 @@ func TestEmptyDomainMatcherGroup(t *testing.T) { t.Error("Expect [], but ", r) } } - -func TestRestoreDomainMatcher(t *testing.T) { - g := new(DomainMatcherGroup) - - for i := 1; i <= 20; i++ { - g.Add(strconv.Itoa(i)+".example.com", uint32(i)) - } - - m := g.Restore() - - if len(m) != 10 { - t.Error("Restore Domain failed.") - } -} diff --git a/testing/scenarios/feature_test.go b/testing/scenarios/feature_test.go index 3c4d7582842c..f2845332a317 100644 --- a/testing/scenarios/feature_test.go +++ b/testing/scenarios/feature_test.go @@ -636,7 +636,7 @@ func TestDomainSniffing(t *testing.T) { Transport: transport, } - resp, err := client.Get("https://www.github.com/") + resp, err := client.Get("https://apple.com/") common.Must(err) if resp.StatusCode != 200 { t.Error("unexpected status code: ", resp.StatusCode)