diff --git a/app/commander/commander.go b/app/commander/commander.go index e63935ff3..8b5deeee6 100644 --- a/app/commander/commander.go +++ b/app/commander/commander.go @@ -14,10 +14,10 @@ import ( type Commander struct { sync.Mutex - server *grpc.Server - config Config - ohm core.OutboundHandlerManager - callbacks []core.ServiceRegistryCallback + server *grpc.Server + config Config + v *core.Instance + ohm core.OutboundHandlerManager } func NewCommander(ctx context.Context, config *Config) (*Commander, error) { @@ -28,6 +28,7 @@ func NewCommander(ctx context.Context, config *Config) (*Commander, error) { c := &Commander{ config: *config, ohm: v.OutboundHandlerManager(), + v: v, } if err := v.RegisterFeature((*core.Commander)(nil), c); err != nil { return nil, err @@ -35,22 +36,23 @@ func NewCommander(ctx context.Context, config *Config) (*Commander, error) { return c, nil } -func (c *Commander) RegisterService(callback core.ServiceRegistryCallback) { - c.Lock() - defer c.Unlock() - - if callback == nil { - return - } - - c.callbacks = append(c.callbacks, callback) -} - func (c *Commander) Start() error { c.Lock() c.server = grpc.NewServer() - for _, callback := range c.callbacks { - callback(c.server) + for _, rawConfig := range c.config.Service { + config, err := rawConfig.GetInstance() + if err != nil { + return err + } + rawService, err := c.v.CreateObject(config) + if err != nil { + return err + } + service, ok := rawService.(Service) + if !ok { + return newError("not a Service.") + } + service.Register(c.server) } c.Unlock() diff --git a/app/commander/config.pb.go b/app/commander/config.pb.go index dbb64bdf8..0ba805e57 100644 --- a/app/commander/config.pb.go +++ b/app/commander/config.pb.go @@ -3,6 +3,7 @@ package commander import proto "github.com/golang/protobuf/proto" import fmt "fmt" import math "math" +import v2ray_core_common_serial "v2ray.com/core/common/serial" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -15,8 +16,12 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +// Config is the settings for Commander. type Config struct { + // Tag of the outbound handler that handles grpc connections. Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"` + // Services that supported by this server. All services must implement Service interface. + Service []*v2ray_core_common_serial.TypedMessage `protobuf:"bytes,2,rep,name=service" json:"service,omitempty"` } func (m *Config) Reset() { *m = Config{} } @@ -31,6 +36,13 @@ func (m *Config) GetTag() string { return "" } +func (m *Config) GetService() []*v2ray_core_common_serial.TypedMessage { + if m != nil { + return m.Service + } + return nil +} + func init() { proto.RegisterType((*Config)(nil), "v2ray.core.app.commander.Config") } @@ -38,14 +50,19 @@ func init() { func init() { proto.RegisterFile("v2ray.com/core/app/commander/config.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 143 bytes of a gzipped FileDescriptorProto + // 212 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2c, 0x33, 0x2a, 0x4a, 0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0xd0, 0x4f, 0xce, 0xcf, 0xcd, 0x4d, 0xcc, 0x4b, 0x49, 0x2d, 0xd2, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x4c, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x80, 0x29, 0x2d, 0x4a, 0xd5, 0x4b, 0x2c, 0x28, 0xd0, - 0x83, 0x2b, 0x53, 0x92, 0xe2, 0x62, 0x73, 0x06, 0xab, 0x14, 0x12, 0xe0, 0x62, 0x2e, 0x49, 0x4c, - 0x97, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x02, 0x31, 0x9d, 0xdc, 0xb8, 0x64, 0x92, 0xf3, 0x73, - 0xf5, 0x70, 0xe9, 0x0d, 0x60, 0x8c, 0xe2, 0x84, 0x73, 0x56, 0x31, 0x49, 0x84, 0x19, 0x05, 0x25, - 0x56, 0xea, 0x39, 0x83, 0xd4, 0x39, 0x16, 0x14, 0xe8, 0x39, 0xc3, 0xa4, 0x92, 0xd8, 0xc0, 0x8e, - 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x36, 0x74, 0x98, 0x19, 0xb1, 0x00, 0x00, 0x00, + 0x83, 0x2b, 0x93, 0x32, 0x40, 0x33, 0x04, 0x24, 0x93, 0x9f, 0xa7, 0x5f, 0x9c, 0x5a, 0x94, 0x99, + 0x98, 0xa3, 0x5f, 0x52, 0x59, 0x90, 0x9a, 0x12, 0x9f, 0x9b, 0x5a, 0x5c, 0x9c, 0x98, 0x9e, 0x0a, + 0x31, 0x4b, 0x29, 0x86, 0x8b, 0xcd, 0x19, 0x6c, 0xb6, 0x90, 0x00, 0x17, 0x73, 0x49, 0x62, 0xba, + 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x88, 0x29, 0xe4, 0xc0, 0xc5, 0x5e, 0x9c, 0x5a, 0x54, + 0x96, 0x99, 0x9c, 0x2a, 0xc1, 0xa4, 0xc0, 0xac, 0xc1, 0x6d, 0xa4, 0xa6, 0x87, 0x64, 0x33, 0xc4, + 0x6c, 0x3d, 0x88, 0xd9, 0x7a, 0x21, 0x20, 0xb3, 0x7d, 0x21, 0x46, 0x07, 0xc1, 0xb4, 0x39, 0xb9, + 0x71, 0xc9, 0x24, 0xe7, 0xe7, 0xea, 0xe1, 0x72, 0x6f, 0x00, 0x63, 0x14, 0x27, 0x9c, 0xb3, 0x8a, + 0x49, 0x22, 0xcc, 0x28, 0x28, 0xb1, 0x52, 0xcf, 0x19, 0xa4, 0xce, 0xb1, 0xa0, 0x40, 0xcf, 0x19, + 0x26, 0x95, 0xc4, 0x06, 0x76, 0xac, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x29, 0x02, 0xa6, 0x19, + 0x25, 0x01, 0x00, 0x00, } diff --git a/app/commander/config.proto b/app/commander/config.proto index 56a7b7745..e6aaa7ec6 100644 --- a/app/commander/config.proto +++ b/app/commander/config.proto @@ -6,6 +6,12 @@ option go_package = "commander"; option java_package = "com.v2ray.core.app.commander"; option java_multiple_files = true; +import "v2ray.com/core/common/serial/typed_message.proto"; + +// Config is the settings for Commander. message Config { + // Tag of the outbound handler that handles grpc connections. string tag = 1; + // Services that supported by this server. All services must implement Service interface. + repeated v2ray.core.common.serial.TypedMessage service = 2; } diff --git a/app/commander/service.go b/app/commander/service.go new file mode 100644 index 000000000..fb9340db4 --- /dev/null +++ b/app/commander/service.go @@ -0,0 +1,9 @@ +package commander + +import ( + "google.golang.org/grpc" +) + +type Service interface { + Register(*grpc.Server) +} diff --git a/app/proxyman/command/command.go b/app/proxyman/command/command.go index 8646918c7..c0357579d 100644 --- a/app/proxyman/command/command.go +++ b/app/proxyman/command/command.go @@ -125,14 +125,16 @@ func (s *handlerServer) AlterOutbound(ctx context.Context, request *AlterOutboun return &AlterOutboundResponse{}, operation.ApplyOutbound(ctx, handler) } -type feature struct{} - -func (*feature) Start() error { - return nil +type service struct { + v *core.Instance } -func (*feature) Close() error { - return nil +func (s *service) Register(server *grpc.Server) { + RegisterHandlerServiceServer(server, &handlerServer{ + s: s.v, + ihm: s.v.InboundHandlerManager(), + ohm: s.v.OutboundHandlerManager(), + }) } func init() { @@ -141,13 +143,6 @@ func init() { if s == nil { return nil, newError("V is not in context.") } - s.Commander().RegisterService(func(server *grpc.Server) { - RegisterHandlerServiceServer(server, &handlerServer{ - s: s, - ihm: s.InboundHandlerManager(), - ohm: s.OutboundHandlerManager(), - }) - }) - return &feature{}, nil + return &service{v: s}, nil })) } diff --git a/commander.go b/commander.go index 63209bfdf..eb2d3750d 100644 --- a/commander.go +++ b/commander.go @@ -2,19 +2,11 @@ package core import ( "sync" - - "google.golang.org/grpc" ) -// ServiceRegistryCallback is a callback function for registering services. -type ServiceRegistryCallback func(s *grpc.Server) - // Commander is a feature that accepts commands from external source. type Commander interface { Feature - - // RegisterService registers a service into this Commander. - RegisterService(ServiceRegistryCallback) } type syncCommander struct { @@ -22,17 +14,6 @@ type syncCommander struct { Commander } -func (c *syncCommander) RegisterService(callback ServiceRegistryCallback) { - c.RLock() - defer c.RUnlock() - - if c.Commander == nil { - return - } - - c.Commander.RegisterService(callback) -} - func (c *syncCommander) Start() error { c.RLock() defer c.RUnlock()