diff --git a/app/commander/commander.go b/app/commander/commander.go index e63935ff..8b5deeee 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 dbb64bdf..0ba805e5 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 56a7b774..e6aaa7ec 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 00000000..fb9340db --- /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 8646918c..c0357579 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 63209bfd..eb2d3750 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()