diff --git a/app/controller/controller.go b/app/controller/controller.go index 8dbdd9df9..5479e220c 100644 --- a/app/controller/controller.go +++ b/app/controller/controller.go @@ -8,9 +8,10 @@ import ( // A SpaceController is supposed to be used by a shell to create Spaces. It should not be used // directly by proxies. type SpaceController struct { - packetDispatcher internal.PacketDispatcherWithContext - dnsCache internal.DnsCacheWithContext - pubsub internal.PubsubWithContext + packetDispatcher internal.PacketDispatcherWithContext + dnsCache internal.DnsCacheWithContext + pubsub internal.PubsubWithContext + inboundHandlerManager internal.InboundHandlerManagerWithContext } func New() *SpaceController { @@ -29,8 +30,12 @@ func (this *SpaceController) Bind(object interface{}) { if pubsub, ok := object.(internal.PubsubWithContext); ok { this.pubsub = pubsub } + + if inboundHandlerManager, ok := object.(internal.InboundHandlerManagerWithContext); ok { + this.inboundHandlerManager = inboundHandlerManager + } } func (this *SpaceController) ForContext(tag string) app.Space { - return internal.NewSpace(tag, this.packetDispatcher, this.dnsCache, this.pubsub) + return internal.NewSpace(tag, this.packetDispatcher, this.dnsCache, this.pubsub, this.inboundHandlerManager) } diff --git a/app/handlers.go b/app/handlers.go new file mode 100644 index 000000000..e6baa4a9d --- /dev/null +++ b/app/handlers.go @@ -0,0 +1,9 @@ +package app + +import ( + "github.com/v2ray/v2ray-core/proxy/common/connhandler" +) + +type InboundHandlerManager interface { + GetHandler(tag string) (connhandler.InboundConnectionHandler, int) +} diff --git a/app/internal/handlers.go b/app/internal/handlers.go new file mode 100644 index 000000000..c1e60e5e5 --- /dev/null +++ b/app/internal/handlers.go @@ -0,0 +1,19 @@ +package internal + +import ( + "github.com/v2ray/v2ray-core/app" + "github.com/v2ray/v2ray-core/proxy/common/connhandler" +) + +type InboundHandlerManagerWithContext interface { + GetHandler(context app.Context, tag string) (connhandler.InboundConnectionHandler, int) +} + +type inboundHandlerManagerWithContext struct { + context app.Context + manager InboundHandlerManagerWithContext +} + +func (this *inboundHandlerManagerWithContext) GetHandler(tag string) (connhandler.InboundConnectionHandler, int) { + return this.manager.GetHandler(this.context, tag) +} diff --git a/app/internal/space.go b/app/internal/space.go index 184a5c08a..e75ba9f6c 100644 --- a/app/internal/space.go +++ b/app/internal/space.go @@ -5,18 +5,20 @@ import ( ) type Space struct { - packetDispatcher PacketDispatcherWithContext - dnsCache DnsCacheWithContext - pubsub PubsubWithContext - tag string + packetDispatcher PacketDispatcherWithContext + dnsCache DnsCacheWithContext + pubsub PubsubWithContext + inboundHandlerManager InboundHandlerManagerWithContext + tag string } -func NewSpace(tag string, packetDispatcher PacketDispatcherWithContext, dnsCache DnsCacheWithContext, pubsub PubsubWithContext) *Space { +func NewSpace(tag string, packetDispatcher PacketDispatcherWithContext, dnsCache DnsCacheWithContext, pubsub PubsubWithContext, inboundHandlerManager InboundHandlerManagerWithContext) *Space { return &Space{ - tag: tag, - packetDispatcher: packetDispatcher, - dnsCache: dnsCache, - pubsub: pubsub, + tag: tag, + packetDispatcher: packetDispatcher, + dnsCache: dnsCache, + pubsub: pubsub, + inboundHandlerManager: inboundHandlerManager, } } @@ -58,3 +60,16 @@ func (this *Space) Pubsub() app.Pubsub { }, } } + +func (this *Space) HasInboundHandlerManager() bool { + return this.inboundHandlerManager != nil +} + +func (this *Space) InboundHandlerManager() app.InboundHandlerManager { + return &inboundHandlerManagerWithContext{ + manager: this.inboundHandlerManager, + context: &contextImpl{ + callerTag: this.tag, + }, + } +} diff --git a/app/space.go b/app/space.go index f01354a85..e10a669f2 100644 --- a/app/space.go +++ b/app/space.go @@ -16,4 +16,7 @@ type Space interface { HasPubsub() bool Pubsub() Pubsub + + HasInboundHandlerManager() bool + InboundHandlerManager() InboundHandlerManager } diff --git a/proxy/blackhole/blackhole.go b/proxy/blackhole/blackhole.go index 2dedbc0ba..d8cbf031e 100644 --- a/proxy/blackhole/blackhole.go +++ b/proxy/blackhole/blackhole.go @@ -5,6 +5,7 @@ import ( "github.com/v2ray/v2ray-core/app" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/proxy/common/connhandler" "github.com/v2ray/v2ray-core/transport/ray" ) @@ -29,13 +30,10 @@ func (this *BlackHole) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) e return nil } -type BlackHoleFactory struct { -} - -func (this BlackHoleFactory) Create(space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) { - return NewBlackHole(), nil -} - func init() { - connhandler.RegisterOutboundConnectionHandlerFactory("blackhole", BlackHoleFactory{}) + if err := proxy.RegisterOutboundConnectionHandlerFactory("blackhole", func(space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) { + return NewBlackHole(), nil + }); err != nil { + panic(err) + } } diff --git a/proxy/common/connhandler/inbound_connection.go b/proxy/common/connhandler/inbound_connection.go index 245e13d94..99ffc0fe4 100644 --- a/proxy/common/connhandler/inbound_connection.go +++ b/proxy/common/connhandler/inbound_connection.go @@ -1,16 +1,9 @@ package connhandler import ( - "github.com/v2ray/v2ray-core/app" v2net "github.com/v2ray/v2ray-core/common/net" ) -// A InboundConnectionHandlerFactory creates InboundConnectionHandler on demand. -type InboundConnectionHandlerFactory interface { - // Create creates a new InboundConnectionHandler with given configuration. - Create(space app.Space, config interface{}) (InboundConnectionHandler, error) -} - // A InboundConnectionHandler handles inbound network connections to V2Ray. type InboundConnectionHandler interface { // Listen starts a InboundConnectionHandler by listen on a specific port. This method is called diff --git a/proxy/common/connhandler/outbound_connection.go b/proxy/common/connhandler/outbound_connection.go index ac7aa5cb8..88ca5eff0 100644 --- a/proxy/common/connhandler/outbound_connection.go +++ b/proxy/common/connhandler/outbound_connection.go @@ -1,17 +1,10 @@ package connhandler import ( - "github.com/v2ray/v2ray-core/app" v2net "github.com/v2ray/v2ray-core/common/net" "github.com/v2ray/v2ray-core/transport/ray" ) -// An OutboundConnectionHandlerFactory creates OutboundConnectionHandler on demand. -type OutboundConnectionHandlerFactory interface { - // Create creates a new OutboundConnectionHandler with given config. - Create(space app.Space, config interface{}) (OutboundConnectionHandler, error) -} - // An OutboundConnectionHandler handles outbound network connection for V2Ray. type OutboundConnectionHandler interface { // Dispatch sends one or more Packets to its destination. diff --git a/proxy/common/connhandler/proxy_cache.go b/proxy/common/connhandler/proxy_cache.go deleted file mode 100644 index 40957a834..000000000 --- a/proxy/common/connhandler/proxy_cache.go +++ /dev/null @@ -1,34 +0,0 @@ -package connhandler - -var ( - inboundFactories = make(map[string]InboundConnectionHandlerFactory) - outboundFactories = make(map[string]OutboundConnectionHandlerFactory) -) - -func RegisterInboundConnectionHandlerFactory(name string, factory InboundConnectionHandlerFactory) error { - // TODO check name - inboundFactories[name] = factory - return nil -} - -func RegisterOutboundConnectionHandlerFactory(name string, factory OutboundConnectionHandlerFactory) error { - // TODO check name - outboundFactories[name] = factory - return nil -} - -func GetInboundConnectionHandlerFactory(name string) InboundConnectionHandlerFactory { - factory, found := inboundFactories[name] - if !found { - return nil - } - return factory -} - -func GetOutboundConnectionHandlerFactory(name string) OutboundConnectionHandlerFactory { - factory, found := outboundFactories[name] - if !found { - return nil - } - return factory -} diff --git a/proxy/dokodemo/dokodemo_factory.go b/proxy/dokodemo/dokodemo_factory.go index 6e21345ce..43f1ef78c 100644 --- a/proxy/dokodemo/dokodemo_factory.go +++ b/proxy/dokodemo/dokodemo_factory.go @@ -2,17 +2,15 @@ package dokodemo import ( "github.com/v2ray/v2ray-core/app" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/proxy/common/connhandler" ) -type DokodemoDoorFactory struct { -} - -func (this DokodemoDoorFactory) Create(space app.Space, rawConfig interface{}) (connhandler.InboundConnectionHandler, error) { - config := rawConfig.(Config) - return NewDokodemoDoor(space, config), nil -} - func init() { - connhandler.RegisterInboundConnectionHandlerFactory("dokodemo-door", DokodemoDoorFactory{}) + if err := proxy.RegisterInboundConnectionHandlerFactory("dokodemo-door", func(space app.Space, rawConfig interface{}) (connhandler.InboundConnectionHandler, error) { + config := rawConfig.(Config) + return NewDokodemoDoor(space, config), nil + }); err != nil { + panic(err) + } } diff --git a/proxy/freedom/freedom_test.go b/proxy/freedom/freedom_test.go index 862c4216a..264f5154d 100644 --- a/proxy/freedom/freedom_test.go +++ b/proxy/freedom/freedom_test.go @@ -8,12 +8,14 @@ import ( "golang.org/x/net/proxy" + "github.com/v2ray/v2ray-core/app" "github.com/v2ray/v2ray-core/common/alloc" v2net "github.com/v2ray/v2ray-core/common/net" v2nettesting "github.com/v2ray/v2ray-core/common/net/testing" "github.com/v2ray/v2ray-core/proxy/common/connhandler" _ "github.com/v2ray/v2ray-core/proxy/socks" "github.com/v2ray/v2ray-core/proxy/socks/json" + proxytesting "github.com/v2ray/v2ray-core/proxy/testing" proxymocks "github.com/v2ray/v2ray-core/proxy/testing/mocks" "github.com/v2ray/v2ray-core/shell/point" "github.com/v2ray/v2ray-core/shell/point/testing/mocks" @@ -47,13 +49,17 @@ func TestUDPSend(t *testing.T) { ConnOutput: connOutput, } - connhandler.RegisterInboundConnectionHandlerFactory("mock_ich", ich) + protocol, err := proxytesting.RegisterInboundConnectionHandlerCreator("mock_ich", func(space app.Space, config interface{}) (connhandler.InboundConnectionHandler, error) { + ich.Space = space + return ich, nil + }) + assert.Error(err).IsNil() pointPort := v2nettesting.PickPort() config := mocks.Config{ PortValue: pointPort, InboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "mock_ich", + ProtocolValue: protocol, SettingsValue: nil, }, OutboundConfigValue: &mocks.ConnectionConfig{ diff --git a/proxy/freedom/freedomfactory.go b/proxy/freedom/freedomfactory.go index 92aebb45e..dd061afef 100644 --- a/proxy/freedom/freedomfactory.go +++ b/proxy/freedom/freedomfactory.go @@ -2,16 +2,14 @@ package freedom import ( "github.com/v2ray/v2ray-core/app" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/proxy/common/connhandler" ) -type FreedomFactory struct { -} - -func (this FreedomFactory) Create(space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) { - return &FreedomConnection{space: space}, nil -} - func init() { - connhandler.RegisterOutboundConnectionHandlerFactory("freedom", FreedomFactory{}) + if err := proxy.RegisterOutboundConnectionHandlerFactory("freedom", func(space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) { + return &FreedomConnection{space: space}, nil + }); err != nil { + panic(err) + } } diff --git a/proxy/http/http_factory.go b/proxy/http/http_factory.go index 6853933e9..4c3f679bb 100644 --- a/proxy/http/http_factory.go +++ b/proxy/http/http_factory.go @@ -2,16 +2,14 @@ package http import ( "github.com/v2ray/v2ray-core/app" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/proxy/common/connhandler" ) -type HttpProxyServerFactory struct { -} - -func (this HttpProxyServerFactory) Create(space app.Space, rawConfig interface{}) (connhandler.InboundConnectionHandler, error) { - return NewHttpProxyServer(space, rawConfig.(Config)), nil -} - func init() { - connhandler.RegisterInboundConnectionHandlerFactory("http", HttpProxyServerFactory{}) + if err := proxy.RegisterInboundConnectionHandlerFactory("http", func(space app.Space, rawConfig interface{}) (connhandler.InboundConnectionHandler, error) { + return NewHttpProxyServer(space, rawConfig.(Config)), nil + }); err != nil { + panic(err) + } } diff --git a/proxy/internal/creator.go b/proxy/internal/creator.go new file mode 100644 index 000000000..cf56eca88 --- /dev/null +++ b/proxy/internal/creator.go @@ -0,0 +1,9 @@ +package internal + +import ( + "github.com/v2ray/v2ray-core/app" + "github.com/v2ray/v2ray-core/proxy/common/connhandler" +) + +type InboundConnectionHandlerCreator func(space app.Space, config interface{}) (connhandler.InboundConnectionHandler, error) +type OutboundConnectionHandlerCreator func(space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) diff --git a/proxy/proxy.go b/proxy/proxy.go new file mode 100644 index 000000000..3bed2c357 --- /dev/null +++ b/proxy/proxy.go @@ -0,0 +1,51 @@ +// Package proxy contains all proxies used by V2Ray. + +package proxy + +import ( + "errors" + + "github.com/v2ray/v2ray-core/app" + "github.com/v2ray/v2ray-core/proxy/common/connhandler" + "github.com/v2ray/v2ray-core/proxy/internal" +) + +var ( + inboundFactories = make(map[string]internal.InboundConnectionHandlerCreator) + outboundFactories = make(map[string]internal.OutboundConnectionHandlerCreator) + + ErrorProxyNotFound = errors.New("Proxy not found.") + ErrorNameExists = errors.New("Proxy with the same name already exists.") +) + +func RegisterInboundConnectionHandlerFactory(name string, creator internal.InboundConnectionHandlerCreator) error { + if _, found := inboundFactories[name]; found { + return ErrorNameExists + } + inboundFactories[name] = creator + return nil +} + +func RegisterOutboundConnectionHandlerFactory(name string, creator internal.OutboundConnectionHandlerCreator) error { + if _, found := outboundFactories[name]; found { + return ErrorNameExists + } + outboundFactories[name] = creator + return nil +} + +func CreateInboundConnectionHandler(name string, space app.Space, config interface{}) (connhandler.InboundConnectionHandler, error) { + if creator, found := inboundFactories[name]; !found { + return nil, ErrorProxyNotFound + } else { + return creator(space, config) + } +} + +func CreateOutboundConnectionHandler(name string, space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) { + if creator, found := outboundFactories[name]; !found { + return nil, ErrorNameExists + } else { + return creator(space, config) + } +} diff --git a/proxy/socks/socks_test.go b/proxy/socks/socks_test.go index 7b31529a9..28fa88da7 100644 --- a/proxy/socks/socks_test.go +++ b/proxy/socks/socks_test.go @@ -9,9 +9,11 @@ import ( "golang.org/x/net/proxy" + "github.com/v2ray/v2ray-core/app" v2nettesting "github.com/v2ray/v2ray-core/common/net/testing" "github.com/v2ray/v2ray-core/proxy/common/connhandler" "github.com/v2ray/v2ray-core/proxy/socks/json" + proxytesting "github.com/v2ray/v2ray-core/proxy/testing" proxymocks "github.com/v2ray/v2ray-core/proxy/testing/mocks" "github.com/v2ray/v2ray-core/shell/point" "github.com/v2ray/v2ray-core/shell/point/testing/mocks" @@ -30,7 +32,10 @@ func TestSocksTcpConnect(t *testing.T) { ConnInput: bytes.NewReader(connInput), } - connhandler.RegisterOutboundConnectionHandlerFactory("mock_och", och) + protocol, err := proxytesting.RegisterOutboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) { + return och, nil + }) + assert.Error(err).IsNil() config := mocks.Config{ PortValue: port, @@ -41,7 +46,7 @@ func TestSocksTcpConnect(t *testing.T) { }, }, OutboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "mock_och", + ProtocolValue: protocol, SettingsValue: nil, }, } @@ -85,7 +90,10 @@ func TestSocksTcpConnectWithUserPass(t *testing.T) { ConnOutput: connOutput, } - connhandler.RegisterOutboundConnectionHandlerFactory("mock_och", och) + protocol, err := proxytesting.RegisterOutboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) { + return och, nil + }) + assert.Error(err).IsNil() config := mocks.Config{ PortValue: port, @@ -99,7 +107,7 @@ func TestSocksTcpConnectWithUserPass(t *testing.T) { }, }, OutboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "mock_och", + ProtocolValue: protocol, SettingsValue: nil, }, } @@ -143,7 +151,10 @@ func TestSocksTcpConnectWithWrongUserPass(t *testing.T) { ConnOutput: connOutput, } - connhandler.RegisterOutboundConnectionHandlerFactory("mock_och", och) + protocol, err := proxytesting.RegisterOutboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) { + return och, nil + }) + assert.Error(err).IsNil() config := mocks.Config{ PortValue: port, @@ -157,7 +168,7 @@ func TestSocksTcpConnectWithWrongUserPass(t *testing.T) { }, }, OutboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "mock_och", + ProtocolValue: protocol, SettingsValue: nil, }, } @@ -187,7 +198,10 @@ func TestSocksTcpConnectWithWrongAuthMethod(t *testing.T) { ConnOutput: connOutput, } - connhandler.RegisterOutboundConnectionHandlerFactory("mock_och", och) + protocol, err := proxytesting.RegisterOutboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) { + return och, nil + }) + assert.Error(err).IsNil() config := mocks.Config{ PortValue: port, @@ -201,7 +215,7 @@ func TestSocksTcpConnectWithWrongAuthMethod(t *testing.T) { }, }, OutboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "mock_och", + ProtocolValue: protocol, SettingsValue: nil, }, } @@ -231,7 +245,10 @@ func TestSocksUdpSend(t *testing.T) { ConnOutput: connOutput, } - connhandler.RegisterOutboundConnectionHandlerFactory("mock_och", och) + protocol, err := proxytesting.RegisterOutboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) { + return och, nil + }) + assert.Error(err).IsNil() config := mocks.Config{ PortValue: port, @@ -243,7 +260,7 @@ func TestSocksUdpSend(t *testing.T) { }, }, OutboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "mock_och", + ProtocolValue: protocol, SettingsValue: nil, }, } diff --git a/proxy/socks/socksfactory.go b/proxy/socks/socksfactory.go index 6f898f67c..213214688 100644 --- a/proxy/socks/socksfactory.go +++ b/proxy/socks/socksfactory.go @@ -2,16 +2,14 @@ package socks import ( "github.com/v2ray/v2ray-core/app" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/proxy/common/connhandler" ) -type SocksServerFactory struct { -} - -func (this SocksServerFactory) Create(space app.Space, rawConfig interface{}) (connhandler.InboundConnectionHandler, error) { - return NewSocksServer(space, rawConfig.(Config)), nil -} - func init() { - connhandler.RegisterInboundConnectionHandlerFactory("socks", SocksServerFactory{}) + if err := proxy.RegisterInboundConnectionHandlerFactory("socks", func(space app.Space, rawConfig interface{}) (connhandler.InboundConnectionHandler, error) { + return NewSocksServer(space, rawConfig.(Config)), nil + }); err != nil { + panic(err) + } } diff --git a/proxy/testing/mocks/inboundhandler.go b/proxy/testing/mocks/inboundhandler.go index 0e985ab0f..9c437704e 100644 --- a/proxy/testing/mocks/inboundhandler.go +++ b/proxy/testing/mocks/inboundhandler.go @@ -6,12 +6,11 @@ import ( "github.com/v2ray/v2ray-core/app" v2net "github.com/v2ray/v2ray-core/common/net" - "github.com/v2ray/v2ray-core/proxy/common/connhandler" ) type InboundConnectionHandler struct { Port v2net.Port - space app.Space + Space app.Space ConnInput io.Reader ConnOutput io.Writer } @@ -22,7 +21,7 @@ func (this *InboundConnectionHandler) Listen(port v2net.Port) error { } func (this *InboundConnectionHandler) Communicate(packet v2net.Packet) error { - ray := this.space.PacketDispatcher().DispatchToOutbound(packet) + ray := this.Space.PacketDispatcher().DispatchToOutbound(packet) input := ray.InboundInput() output := ray.InboundOutput() @@ -48,8 +47,3 @@ func (this *InboundConnectionHandler) Communicate(packet v2net.Packet) error { writeFinish.Lock() return nil } - -func (this *InboundConnectionHandler) Create(space app.Space, config interface{}) (connhandler.InboundConnectionHandler, error) { - this.space = space - return this, nil -} diff --git a/proxy/testing/proxy.go b/proxy/testing/proxy.go new file mode 100644 index 000000000..1333894a0 --- /dev/null +++ b/proxy/testing/proxy.go @@ -0,0 +1,35 @@ +package testing + +import ( + "fmt" + + "github.com/v2ray/v2ray-core/proxy" + "github.com/v2ray/v2ray-core/proxy/internal" +) + +var count = 0 + +func randomString() string { + count++ + return fmt.Sprintf("-%d", count) +} + +func RegisterInboundConnectionHandlerCreator(prefix string, creator internal.InboundConnectionHandlerCreator) (string, error) { + for { + name := prefix + randomString() + err := proxy.RegisterInboundConnectionHandlerFactory(name, creator) + if err != proxy.ErrorNameExists { + return name, err + } + } +} + +func RegisterOutboundConnectionHandlerCreator(prefix string, creator internal.OutboundConnectionHandlerCreator) (string, error) { + for { + name := prefix + randomString() + err := proxy.RegisterOutboundConnectionHandlerFactory(name, creator) + if err != proxy.ErrorNameExists { + return name, err + } + } +} diff --git a/proxy/vmess/inbound/inbound.go b/proxy/vmess/inbound/inbound.go index 0f5e77bff..ab07b2cb0 100644 --- a/proxy/vmess/inbound/inbound.go +++ b/proxy/vmess/inbound/inbound.go @@ -12,6 +12,7 @@ import ( "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" "github.com/v2ray/v2ray-core/common/retry" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/proxy/common/connhandler" "github.com/v2ray/v2ray-core/proxy/vmess" "github.com/v2ray/v2ray-core/proxy/vmess/protocol" @@ -139,20 +140,17 @@ func handleOutput(request *protocol.VMessRequest, writer io.Writer, output <-cha finish.Unlock() } -type VMessInboundHandlerFactory struct { -} - -func (this *VMessInboundHandlerFactory) Create(space app.Space, rawConfig interface{}) (connhandler.InboundConnectionHandler, error) { - config := rawConfig.(Config) - - allowedClients := user.NewTimedUserSet() - for _, user := range config.AllowedUsers() { - allowedClients.AddUser(user) - } - - return NewVMessInboundHandler(space, allowedClients), nil -} - func init() { - connhandler.RegisterInboundConnectionHandlerFactory("vmess", &VMessInboundHandlerFactory{}) + if err := proxy.RegisterInboundConnectionHandlerFactory("vmess", func(space app.Space, rawConfig interface{}) (connhandler.InboundConnectionHandler, error) { + config := rawConfig.(Config) + + allowedClients := user.NewTimedUserSet() + for _, user := range config.AllowedUsers() { + allowedClients.AddUser(user) + } + + return NewVMessInboundHandler(space, allowedClients), nil + }); err != nil { + panic(err) + } } diff --git a/proxy/vmess/outbound/outbound.go b/proxy/vmess/outbound/outbound.go index 22733ba09..495f8a155 100644 --- a/proxy/vmess/outbound/outbound.go +++ b/proxy/vmess/outbound/outbound.go @@ -11,6 +11,7 @@ import ( v2crypto "github.com/v2ray/v2ray-core/common/crypto" "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/proxy/common/connhandler" "github.com/v2ray/v2ray-core/proxy/vmess/protocol" "github.com/v2ray/v2ray-core/proxy/vmess/protocol/user" @@ -196,5 +197,13 @@ func (this *VMessOutboundHandlerFactory) Create(space app.Space, rawConfig inter } func init() { - connhandler.RegisterOutboundConnectionHandlerFactory("vmess", &VMessOutboundHandlerFactory{}) + if err := proxy.RegisterOutboundConnectionHandlerFactory("vmess", func(space app.Space, rawConfig interface{}) (connhandler.OutboundConnectionHandler, error) { + vOutConfig := rawConfig.(Config) + return &VMessOutboundHandler{ + space: space, + receiverManager: NewReceiverManager(vOutConfig.Receivers()), + }, nil + }); err != nil { + panic(err) + } } diff --git a/proxy/vmess/vmess_test.go b/proxy/vmess/vmess_test.go index 6865270bd..39d6d7b62 100644 --- a/proxy/vmess/vmess_test.go +++ b/proxy/vmess/vmess_test.go @@ -4,10 +4,12 @@ import ( "bytes" "testing" + "github.com/v2ray/v2ray-core/app" v2net "github.com/v2ray/v2ray-core/common/net" v2nettesting "github.com/v2ray/v2ray-core/common/net/testing" "github.com/v2ray/v2ray-core/common/uuid" "github.com/v2ray/v2ray-core/proxy/common/connhandler" + proxytesting "github.com/v2ray/v2ray-core/proxy/testing" proxymocks "github.com/v2ray/v2ray-core/proxy/testing/mocks" vmess "github.com/v2ray/v2ray-core/proxy/vmess" _ "github.com/v2ray/v2ray-core/proxy/vmess/inbound" @@ -39,12 +41,16 @@ func TestVMessInAndOut(t *testing.T) { ConnOutput: ichConnOutput, } - connhandler.RegisterInboundConnectionHandlerFactory("mock_ich", ich) + protocol, err := proxytesting.RegisterInboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (connhandler.InboundConnectionHandler, error) { + ich.Space = space + return ich, nil + }) + assert.Error(err).IsNil() configA := mocks.Config{ PortValue: portA, InboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "mock_ich", + ProtocolValue: protocol, SettingsValue: nil, }, OutboundConfigValue: &mocks.ConnectionConfig{ @@ -75,7 +81,10 @@ func TestVMessInAndOut(t *testing.T) { ConnOutput: ochConnOutput, } - connhandler.RegisterOutboundConnectionHandlerFactory("mock_och", och) + protocol, err = proxytesting.RegisterOutboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (connhandler.OutboundConnectionHandler, error) { + return och, nil + }) + assert.Error(err).IsNil() configB := mocks.Config{ PortValue: portB, @@ -88,7 +97,7 @@ func TestVMessInAndOut(t *testing.T) { }, }, OutboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "mock_och", + ProtocolValue: protocol, SettingsValue: nil, }, } diff --git a/shell/point/inbound_detour.go b/shell/point/inbound_detour.go index b81e9285e..87edd6be8 100644 --- a/shell/point/inbound_detour.go +++ b/shell/point/inbound_detour.go @@ -5,6 +5,7 @@ import ( "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" "github.com/v2ray/v2ray-core/common/retry" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/proxy/common/connhandler" ) @@ -21,17 +22,11 @@ type InboundDetourHandler struct { } func (this *InboundDetourHandler) Initialize() error { - ichFactory := connhandler.GetInboundConnectionHandlerFactory(this.config.Protocol()) - if ichFactory == nil { - log.Error("Unknown inbound connection handler factory %s", this.config.Protocol()) - return BadConfiguration - } - ports := this.config.PortRange() this.ich = make([]*InboundConnectionHandlerWithPort, 0, ports.To()-ports.From()+1) for i := ports.From(); i <= ports.To(); i++ { ichConfig := this.config.Settings() - ich, err := ichFactory.Create(this.space, ichConfig) + ich, err := proxy.CreateInboundConnectionHandler(this.config.Protocol(), this.space, ichConfig) if err != nil { log.Error("Failed to create inbound connection handler: %v", err) return err diff --git a/shell/point/point.go b/shell/point/point.go index 2cfa82777..4bc65320a 100644 --- a/shell/point/point.go +++ b/shell/point/point.go @@ -11,6 +11,7 @@ import ( "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" "github.com/v2ray/v2ray-core/common/retry" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/proxy/common/connhandler" "github.com/v2ray/v2ray-core/transport/ray" ) @@ -54,26 +55,16 @@ func NewPoint(pConfig PointConfig) (*Point, error) { vpoint.space = controller.New() vpoint.space.Bind(vpoint) - ichFactory := connhandler.GetInboundConnectionHandlerFactory(pConfig.InboundConfig().Protocol()) - if ichFactory == nil { - log.Error("Unknown inbound connection handler factory %s", pConfig.InboundConfig().Protocol()) - return nil, BadConfiguration - } ichConfig := pConfig.InboundConfig().Settings() - ich, err := ichFactory.Create(vpoint.space.ForContext("vpoint-default-inbound"), ichConfig) + ich, err := proxy.CreateInboundConnectionHandler(pConfig.InboundConfig().Protocol(), vpoint.space.ForContext("vpoint-default-inbound"), ichConfig) if err != nil { log.Error("Failed to create inbound connection handler: %v", err) return nil, err } vpoint.ich = ich - ochFactory := connhandler.GetOutboundConnectionHandlerFactory(pConfig.OutboundConfig().Protocol()) - if ochFactory == nil { - log.Error("Unknown outbound connection handler factory %s", pConfig.OutboundConfig().Protocol()) - return nil, BadConfiguration - } ochConfig := pConfig.OutboundConfig().Settings() - och, err := ochFactory.Create(vpoint.space.ForContext("vpoint-default-outbound"), ochConfig) + och, err := proxy.CreateOutboundConnectionHandler(pConfig.OutboundConfig().Protocol(), vpoint.space.ForContext("vpoint-default-outbound"), ochConfig) if err != nil { log.Error("Failed to create outbound connection handler: %v", err) return nil, err @@ -100,12 +91,7 @@ func NewPoint(pConfig PointConfig) (*Point, error) { if len(outboundDetours) > 0 { vpoint.odh = make(map[string]connhandler.OutboundConnectionHandler) for _, detourConfig := range outboundDetours { - detourFactory := connhandler.GetOutboundConnectionHandlerFactory(detourConfig.Protocol()) - if detourFactory == nil { - log.Error("Unknown detour outbound connection handler factory %s", detourConfig.Protocol()) - return nil, BadConfiguration - } - detourHandler, err := detourFactory.Create(vpoint.space.ForContext(detourConfig.Tag()), detourConfig.Settings()) + detourHandler, err := proxy.CreateOutboundConnectionHandler(detourConfig.Protocol(), vpoint.space.ForContext(detourConfig.Tag()), detourConfig.Settings()) if err != nil { log.Error("Failed to create detour outbound connection handler: %v", err) return nil, err