Selaa lähdekoodia

Require Type() for Feature

Darien Raymond 7 vuotta sitten
vanhempi
commit
d730637239

+ 2 - 2
app/commander/commander.go

@@ -21,7 +21,7 @@ type Commander struct {
 	server *grpc.Server
 	config Config
 	v      *core.Instance
-	ohm    outbound.HandlerManager
+	ohm    outbound.Manager
 }
 
 // NewCommander creates a new Commander based on the given config.
@@ -32,7 +32,7 @@ func NewCommander(ctx context.Context, config *Config) (*Commander, error) {
 		ohm:    v.OutboundHandlerManager(),
 		v:      v,
 	}
-	if err := v.RegisterFeature((*Commander)(nil), c); err != nil {
+	if err := v.RegisterFeature(c); err != nil {
 		return nil, err
 	}
 	return c, nil

+ 6 - 2
app/dispatcher/default.go

@@ -84,7 +84,7 @@ func (r *cachedReader) CloseError() {
 
 // DefaultDispatcher is a default implementation of Dispatcher.
 type DefaultDispatcher struct {
-	ohm    outbound.HandlerManager
+	ohm    outbound.Manager
 	router routing.Router
 	policy policy.Manager
 	stats  feature_stats.Manager
@@ -100,12 +100,16 @@ func NewDefaultDispatcher(ctx context.Context, config *Config) (*DefaultDispatch
 		stats:  v.Stats(),
 	}
 
-	if err := v.RegisterFeature((*routing.Dispatcher)(nil), d); err != nil {
+	if err := v.RegisterFeature(d); err != nil {
 		return nil, newError("unable to register Dispatcher").Base(err)
 	}
 	return d, nil
 }
 
+func (*DefaultDispatcher) Type() interface{} {
+	return routing.DispatcherType()
+}
+
 // Start implements common.Runnable.
 func (*DefaultDispatcher) Start() error {
 	return nil

+ 5 - 1
app/dns/server.go

@@ -41,7 +41,7 @@ func New(ctx context.Context, config *Config) (*Server, error) {
 	server.hosts = hosts
 
 	v := core.MustFromContext(ctx)
-	if err := v.RegisterFeature((*dns.Client)(nil), server); err != nil {
+	if err := v.RegisterFeature(server); err != nil {
 		return nil, newError("unable to register DNSClient.").Base(err)
 	}
 
@@ -97,6 +97,10 @@ func New(ctx context.Context, config *Config) (*Server, error) {
 	return server, nil
 }
 
+func (*Server) Type() interface{} {
+	return dns.ClientType()
+}
+
 // Start implements common.Runnable.
 func (s *Server) Start() error {
 	return nil

+ 1 - 1
app/log/log.go

@@ -30,7 +30,7 @@ func New(ctx context.Context, config *Config) (*Instance, error) {
 
 	v := core.FromContext(ctx)
 	if v != nil {
-		common.Must(v.RegisterFeature((*log.Handler)(nil), g))
+		common.Must(v.RegisterFeature(g))
 	}
 
 	return g, nil

+ 6 - 1
app/policy/manager.go

@@ -30,7 +30,7 @@ func New(ctx context.Context, config *Config) (*Instance, error) {
 
 	v := core.FromContext(ctx)
 	if v != nil {
-		if err := v.RegisterFeature((*policy.Manager)(nil), m); err != nil {
+		if err := v.RegisterFeature(m); err != nil {
 			return nil, newError("unable to register PolicyManager in core").Base(err).AtError()
 		}
 	}
@@ -38,6 +38,11 @@ func New(ctx context.Context, config *Config) (*Instance, error) {
 	return m, nil
 }
 
+// Type implements common.HasType.
+func (*Instance) Type() interface{} {
+	return policy.ManagerType()
+}
+
 // ForLevel implements policy.Manager.
 func (m *Instance) ForLevel(level uint32) policy.Session {
 	if p, ok := m.levels[level]; ok {

+ 1 - 1
app/proxyman/command/command.go

@@ -64,7 +64,7 @@ func (op *RemoveUserOperation) ApplyInbound(ctx context.Context, handler inbound
 type handlerServer struct {
 	s   *core.Instance
 	ihm inbound.Manager
-	ohm outbound.HandlerManager
+	ohm outbound.Manager
 }
 
 func (s *handlerServer) AddInbound(ctx context.Context, request *AddInboundRequest) (*AddInboundResponse, error) {

+ 6 - 1
app/proxyman/inbound/inbound.go

@@ -28,12 +28,17 @@ func New(ctx context.Context, config *proxyman.InboundConfig) (*Manager, error)
 		taggedHandlers: make(map[string]inbound.Handler),
 	}
 	v := core.MustFromContext(ctx)
-	if err := v.RegisterFeature((*inbound.Manager)(nil), m); err != nil {
+	if err := v.RegisterFeature(m); err != nil {
 		return nil, newError("unable to register InboundHandlerManager").Base(err)
 	}
 	return m, nil
 }
 
+// Type implements common.HasType.
+func (*Manager) Type() interface{} {
+	return inbound.ManagerType()
+}
+
 // AddHandler implements inbound.Manager.
 func (m *Manager) AddHandler(ctx context.Context, handler inbound.Handler) error {
 	m.access.Lock()

+ 4 - 0
app/proxyman/mux/mux.go

@@ -310,6 +310,10 @@ func NewServer(ctx context.Context) *Server {
 	return s
 }
 
+func (s *Server) Type() interface{} {
+	return s.dispatcher.Type()
+}
+
 func (s *Server) Dispatch(ctx context.Context, dest net.Destination) (*vio.Link, error) {
 	if dest.Address != muxCoolAddress {
 		return s.dispatcher.Dispatch(ctx, dest)

+ 1 - 1
app/proxyman/outbound/handler.go

@@ -21,7 +21,7 @@ type Handler struct {
 	senderSettings  *proxyman.SenderConfig
 	streamSettings  *internet.MemoryStreamConfig
 	proxy           proxy.Outbound
-	outboundManager outbound.HandlerManager
+	outboundManager outbound.Manager
 	mux             *mux.ClientManager
 }
 

+ 1 - 1
app/proxyman/outbound/handler_test.go

@@ -12,5 +12,5 @@ func TestInterfaces(t *testing.T) {
 	assert := With(t)
 
 	assert((*Handler)(nil), Implements, (*outbound.Handler)(nil))
-	assert((*Manager)(nil), Implements, (*outbound.HandlerManager)(nil))
+	assert((*Manager)(nil), Implements, (*outbound.Manager)(nil))
 }

+ 10 - 6
app/proxyman/outbound/outbound.go

@@ -27,12 +27,16 @@ func New(ctx context.Context, config *proxyman.OutboundConfig) (*Manager, error)
 		taggedHandler: make(map[string]outbound.Handler),
 	}
 	v := core.MustFromContext(ctx)
-	if err := v.RegisterFeature((*outbound.HandlerManager)(nil), m); err != nil {
-		return nil, newError("unable to register OutboundHandlerManager").Base(err)
+	if err := v.RegisterFeature(m); err != nil {
+		return nil, newError("unable to register outbound.Manager").Base(err)
 	}
 	return m, nil
 }
 
+func (m *Manager) Type() interface{} {
+	return outbound.ManagerType()
+}
+
 // Start implements core.Feature
 func (m *Manager) Start() error {
 	m.access.Lock()
@@ -73,7 +77,7 @@ func (m *Manager) Close() error {
 	return nil
 }
 
-// GetDefaultHandler implements outbound.HandlerManager.
+// GetDefaultHandler implements outbound.Manager.
 func (m *Manager) GetDefaultHandler() outbound.Handler {
 	m.access.RLock()
 	defer m.access.RUnlock()
@@ -84,7 +88,7 @@ func (m *Manager) GetDefaultHandler() outbound.Handler {
 	return m.defaultHandler
 }
 
-// GetHandler implements outbound.HandlerManager.
+// GetHandler implements outbound.Manager.
 func (m *Manager) GetHandler(tag string) outbound.Handler {
 	m.access.RLock()
 	defer m.access.RUnlock()
@@ -94,7 +98,7 @@ func (m *Manager) GetHandler(tag string) outbound.Handler {
 	return nil
 }
 
-// AddHandler implements outbound.HandlerManager.
+// AddHandler implements outbound.Manager.
 func (m *Manager) AddHandler(ctx context.Context, handler outbound.Handler) error {
 	m.access.Lock()
 	defer m.access.Unlock()
@@ -117,7 +121,7 @@ func (m *Manager) AddHandler(ctx context.Context, handler outbound.Handler) erro
 	return nil
 }
 
-// RemoveHandler implements outbound.HandlerManager.
+// RemoveHandler implements outbound.Manager.
 func (m *Manager) RemoveHandler(ctx context.Context, tag string) error {
 	if len(tag) == 0 {
 		return common.ErrNoClue

+ 6 - 1
app/router/router.go

@@ -39,7 +39,7 @@ func NewRouter(ctx context.Context, config *Config) (*Router, error) {
 		r.rules[idx].Condition = cond
 	}
 
-	if err := v.RegisterFeature((*routing.Router)(nil), r); err != nil {
+	if err := v.RegisterFeature(r); err != nil {
 		return nil, newError("unable to register Router").Base(err)
 	}
 	return r, nil
@@ -124,6 +124,11 @@ func (*Router) Close() error {
 	return nil
 }
 
+// Type implement common.HasType.
+func (*Router) Type() interface{} {
+	return routing.RouterType()
+}
+
 func init() {
 	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
 		return NewRouter(ctx, config.(*Config))

+ 5 - 1
app/stats/stats.go

@@ -44,7 +44,7 @@ func NewManager(ctx context.Context, config *Config) (*Manager, error) {
 
 	v := core.FromContext(ctx)
 	if v != nil {
-		if err := v.RegisterFeature((*stats.Manager)(nil), m); err != nil {
+		if err := v.RegisterFeature(m); err != nil {
 			return nil, newError("failed to register StatManager").Base(err)
 		}
 	}
@@ -52,6 +52,10 @@ func NewManager(ctx context.Context, config *Config) (*Manager, error) {
 	return m, nil
 }
 
+func (*Manager) Type() interface{} {
+	return stats.ManagerType()
+}
+
 func (m *Manager) RegisterCounter(name string) (stats.Counter, error) {
 	m.access.Lock()
 	defer m.access.Unlock()

+ 1 - 0
common/interfaces.go

@@ -25,6 +25,7 @@ type Runnable interface {
 // HasType is the interface for objects that knows its type.
 type HasType interface {
 	// Type returns the type of the object.
+	// Usually it returns (*Type)(nil) of the object.
 	Type() interface{}
 }
 

+ 4 - 0
dns.go

@@ -13,6 +13,10 @@ type syncDNSClient struct {
 	dns.Client
 }
 
+func (d *syncDNSClient) Type() interface{} {
+	return dns.ClientType()
+}
+
 func (d *syncDNSClient) LookupIP(host string) ([]net.IP, error) {
 	d.RLock()
 	defer d.RUnlock()

+ 4 - 0
features/dns/client.go

@@ -10,3 +10,7 @@ type Client interface {
 	features.Feature
 	LookupIP(host string) ([]net.IP, error)
 }
+
+func ClientType() interface{} {
+	return (*Client)(nil)
+}

+ 1 - 0
features/feature.go

@@ -5,5 +5,6 @@ import "v2ray.com/core/common"
 // Feature is the interface for V2Ray features. All features must implement this interface.
 // All existing features have an implementation in app directory. These features can be replaced by third-party ones.
 type Feature interface {
+	common.HasType
 	common.Runnable
 }

+ 6 - 2
features/inbound/inbound.go

@@ -23,9 +23,13 @@ type Manager interface {
 	features.Feature
 	// GetHandlers returns an InboundHandler for the given tag.
 	GetHandler(ctx context.Context, tag string) (Handler, error)
-	// AddHandler adds the given handler into this InboundHandlerManager.
+	// AddHandler adds the given handler into this Manager.
 	AddHandler(ctx context.Context, handler Handler) error
 
-	// RemoveHandler removes a handler from InboundHandlerManager.
+	// RemoveHandler removes a handler from Manager.
 	RemoveHandler(ctx context.Context, tag string) error
 }
+
+func ManagerType() interface{} {
+	return (*Manager)(nil)
+}

+ 8 - 4
features/outbound/outbound.go

@@ -15,16 +15,20 @@ type Handler interface {
 	Dispatch(ctx context.Context, link *vio.Link)
 }
 
-// HandlerManager is a feature that manages outbound.Handlers.
-type HandlerManager interface {
+// Manager is a feature that manages outbound.Handlers.
+type Manager interface {
 	features.Feature
 	// GetHandler returns an outbound.Handler for the given tag.
 	GetHandler(tag string) Handler
 	// GetDefaultHandler returns the default outbound.Handler. It is usually the first outbound.Handler specified in the configuration.
 	GetDefaultHandler() Handler
-	// AddHandler adds a handler into this outbound.HandlerManager.
+	// AddHandler adds a handler into this outbound.Manager.
 	AddHandler(ctx context.Context, handler Handler) error
 
-	// RemoveHandler removes a handler from outbound.HandlerManager.
+	// RemoveHandler removes a handler from outbound.Manager.
 	RemoveHandler(ctx context.Context, tag string) error
 }
+
+func ManagerType() interface{} {
+	return (*Manager)(nil)
+}

+ 4 - 0
features/policy/policy.go

@@ -67,6 +67,10 @@ type Manager interface {
 	ForSystem() System
 }
 
+func ManagerType() interface{} {
+	return (*Manager)(nil)
+}
+
 var defaultBufferSize int32
 
 func init() {

+ 4 - 0
features/routing/dispatcher.go

@@ -16,3 +16,7 @@ type Dispatcher interface {
 	// Dispatch returns a Ray for transporting data for the given request.
 	Dispatch(ctx context.Context, dest net.Destination) (*vio.Link, error)
 }
+
+func DispatcherType() interface{} {
+	return (*Dispatcher)(nil)
+}

+ 4 - 0
features/routing/router.go

@@ -13,3 +13,7 @@ type Router interface {
 	// PickRoute returns a tag of an OutboundHandler based on the given context.
 	PickRoute(ctx context.Context) (string, error)
 }
+
+func RouterType() interface{} {
+	return (*Router)(nil)
+}

+ 4 - 0
features/stats/stats.go

@@ -24,3 +24,7 @@ func GetOrRegisterCounter(m Manager, name string) (Counter, error) {
 
 	return m.RegisterCounter(name)
 }
+
+func ManagerType() interface{} {
+	return (*Manager)(nil)
+}

+ 21 - 13
network.go

@@ -14,6 +14,10 @@ type syncInboundHandlerManager struct {
 	inbound.Manager
 }
 
+func (*syncInboundHandlerManager) Type() interface{} {
+	return inbound.ManagerType()
+}
+
 func (m *syncInboundHandlerManager) GetHandler(ctx context.Context, tag string) (inbound.Handler, error) {
 	m.RLock()
 	defer m.RUnlock()
@@ -68,61 +72,65 @@ func (m *syncInboundHandlerManager) Set(manager inbound.Manager) {
 
 type syncOutboundHandlerManager struct {
 	sync.RWMutex
-	outbound.HandlerManager
+	outbound.Manager
+}
+
+func (*syncOutboundHandlerManager) Type() interface{} {
+	return outbound.ManagerType()
 }
 
 func (m *syncOutboundHandlerManager) GetHandler(tag string) outbound.Handler {
 	m.RLock()
 	defer m.RUnlock()
 
-	if m.HandlerManager == nil {
+	if m.Manager == nil {
 		return nil
 	}
 
-	return m.HandlerManager.GetHandler(tag)
+	return m.Manager.GetHandler(tag)
 }
 
 func (m *syncOutboundHandlerManager) GetDefaultHandler() outbound.Handler {
 	m.RLock()
 	defer m.RUnlock()
 
-	if m.HandlerManager == nil {
+	if m.Manager == nil {
 		return nil
 	}
 
-	return m.HandlerManager.GetDefaultHandler()
+	return m.Manager.GetDefaultHandler()
 }
 
 func (m *syncOutboundHandlerManager) AddHandler(ctx context.Context, handler outbound.Handler) error {
 	m.RLock()
 	defer m.RUnlock()
 
-	if m.HandlerManager == nil {
+	if m.Manager == nil {
 		return newError("OutboundHandlerManager not set.").AtError()
 	}
 
-	return m.HandlerManager.AddHandler(ctx, handler)
+	return m.Manager.AddHandler(ctx, handler)
 }
 
 func (m *syncOutboundHandlerManager) Start() error {
 	m.RLock()
 	defer m.RUnlock()
 
-	if m.HandlerManager == nil {
+	if m.Manager == nil {
 		return newError("OutboundHandlerManager not set.").AtError()
 	}
 
-	return m.HandlerManager.Start()
+	return m.Manager.Start()
 }
 
 func (m *syncOutboundHandlerManager) Close() error {
 	m.RLock()
 	defer m.RUnlock()
 
-	return common.Close(m.HandlerManager)
+	return common.Close(m.Manager)
 }
 
-func (m *syncOutboundHandlerManager) Set(manager outbound.HandlerManager) {
+func (m *syncOutboundHandlerManager) Set(manager outbound.Manager) {
 	if manager == nil {
 		return
 	}
@@ -130,6 +138,6 @@ func (m *syncOutboundHandlerManager) Set(manager outbound.HandlerManager) {
 	m.Lock()
 	defer m.Unlock()
 
-	common.Close(m.HandlerManager) // nolint: errcheck
-	m.HandlerManager = manager
+	common.Close(m.Manager) // nolint: errcheck
+	m.Manager = manager
 }

+ 4 - 0
policy.go

@@ -13,6 +13,10 @@ type syncPolicyManager struct {
 	policy.Manager
 }
 
+func (*syncPolicyManager) Type() interface{} {
+	return policy.ManagerType()
+}
+
 func (m *syncPolicyManager) ForLevel(level uint32) policy.Session {
 	m.RLock()
 	defer m.RUnlock()

+ 8 - 0
router.go

@@ -15,6 +15,10 @@ type syncDispatcher struct {
 	routing.Dispatcher
 }
 
+func (*syncDispatcher) Type() interface{} {
+	return routing.DispatcherType()
+}
+
 func (d *syncDispatcher) Dispatch(ctx context.Context, dest net.Destination) (*vio.Link, error) {
 	d.RLock()
 	defer d.RUnlock()
@@ -61,6 +65,10 @@ type syncRouter struct {
 	routing.Router
 }
 
+func (*syncRouter) Type() interface{} {
+	return routing.RouterType()
+}
+
 func (r *syncRouter) PickRoute(ctx context.Context) (string, error) {
 	r.RLock()
 	defer r.RUnlock()

+ 4 - 0
stats.go

@@ -11,6 +11,10 @@ type syncStatManager struct {
 	stats.Manager
 }
 
+func (*syncStatManager) Type() interface{} {
+	return stats.ManagerType()
+}
+
 func (s *syncStatManager) Start() error {
 	s.RLock()
 	defer s.RUnlock()

+ 2 - 2
testing/scenarios/socks_test.go

@@ -3,12 +3,12 @@ package scenarios
 import (
 	"testing"
 
-	"v2ray.com/core/app/router"
-
 	xproxy "golang.org/x/net/proxy"
 	socks4 "h12.io/socks"
+
 	"v2ray.com/core"
 	"v2ray.com/core/app/proxyman"
+	"v2ray.com/core/app/router"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/serial"

+ 5 - 0
transport/internet/udp/dispatcher_test.go

@@ -9,6 +9,7 @@ import (
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/vio"
+	"v2ray.com/core/features/routing"
 	. "v2ray.com/core/transport/internet/udp"
 	"v2ray.com/core/transport/pipe"
 	. "v2ray.com/ext/assert"
@@ -30,6 +31,10 @@ func (d *TestDispatcher) Close() error {
 	return nil
 }
 
+func (*TestDispatcher) Type() interface{} {
+	return routing.DispatcherType()
+}
+
 func TestSameDestinationDispatching(t *testing.T) {
 	assert := With(t)
 

+ 24 - 9
v2ray.go

@@ -140,10 +140,10 @@ func (s *Instance) Start() error {
 // RegisterFeature registers the given feature into V2Ray.
 // If feature is one of the following types, the corresponding feature in this Instance
 // will be replaced: DNSClient, PolicyManager, Router, Dispatcher, InboundHandlerManager, OutboundHandlerManager.
-func (s *Instance) RegisterFeature(feature interface{}, instance features.Feature) error {
+func (s *Instance) RegisterFeature(instance features.Feature) error {
 	running := false
 
-	switch feature.(type) {
+	switch instance.Type().(type) {
 	case dns.Client, *dns.Client:
 		s.dnsClient.Set(instance.(dns.Client))
 	case policy.Manager, *policy.Manager:
@@ -154,8 +154,8 @@ func (s *Instance) RegisterFeature(feature interface{}, instance features.Featur
 		s.dispatcher.Set(instance.(routing.Dispatcher))
 	case inbound.Manager, *inbound.Manager:
 		s.ihm.Set(instance.(inbound.Manager))
-	case outbound.HandlerManager, *outbound.HandlerManager:
-		s.ohm.Set(instance.(outbound.HandlerManager))
+	case outbound.Manager, *outbound.Manager:
+		s.ohm.Set(instance.(outbound.Manager))
 	case stats.Manager, *stats.Manager:
 		s.stats.Set(instance.(stats.Manager))
 	default:
@@ -178,14 +178,29 @@ func (s *Instance) allFeatures() []features.Feature {
 // GetFeature returns a feature that was registered in this Instance. Nil if not found.
 // The returned Feature must implement common.HasType and whose type equals to the given feature type.
 func (s *Instance) GetFeature(featureType interface{}) features.Feature {
-	for _, f := range s.features {
-		if hasType, ok := f.(common.HasType); ok {
-			if hasType.Type() == featureType {
+	switch featureType.(type) {
+	case dns.Client, *dns.Client:
+		return s.DNSClient()
+	case policy.Manager, *policy.Manager:
+		return s.PolicyManager()
+	case routing.Router, *routing.Router:
+		return s.Router()
+	case routing.Dispatcher, *routing.Dispatcher:
+		return s.Dispatcher()
+	case inbound.Manager, *inbound.Manager:
+		return s.InboundHandlerManager()
+	case outbound.Manager, *outbound.Manager:
+		return s.OutboundHandlerManager()
+	case stats.Manager, *stats.Manager:
+		return s.Stats()
+	default:
+		for _, f := range s.features {
+			if f.Type() == featureType {
 				return f
 			}
 		}
+		return nil
 	}
-	return nil
 }
 
 // DNSClient returns the dns.Client used by this Instance. The returned dns.Client is always functional.
@@ -214,7 +229,7 @@ func (s *Instance) InboundHandlerManager() inbound.Manager {
 }
 
 // OutboundHandlerManager returns the OutboundHandlerManager used by this Instance. If OutboundHandlerManager was not registered before, the returned value doesn't work.
-func (s *Instance) OutboundHandlerManager() outbound.HandlerManager {
+func (s *Instance) OutboundHandlerManager() outbound.Manager {
 	return &(s.ohm)
 }