From 17504d2aacb3dabd5857b2019c23f3d63f8a6dae Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Fri, 13 Jan 2017 13:41:40 +0100 Subject: [PATCH] context'ize apps --- app/dispatcher/dispatcher.go | 3 +- app/dispatcher/impl/default.go | 23 +++++---- app/dns/dns.go | 3 +- app/dns/server/server.go | 27 ++++++----- app/proxy/proxy.go | 27 ++++++----- app/proxy/proxy_test.go | 5 +- app/proxyman/outbound/outbound.go | 21 ++++---- app/proxyman/proxyman.go | 5 +- app/router/router.go | 26 ++++++---- app/router/router_test.go | 10 ++-- app/sender/sender.go | 17 ++++--- app/space.go | 81 +++++++++++++------------------ proxy/dokodemo/dokodemo_test.go | 16 +++--- proxy/freedom/freedom_test.go | 10 ++-- v2ray.go | 49 +++++++++++++------ 15 files changed, 171 insertions(+), 152 deletions(-) diff --git a/app/dispatcher/dispatcher.go b/app/dispatcher/dispatcher.go index a73384ffc..e7a5ec03d 100644 --- a/app/dispatcher/dispatcher.go +++ b/app/dispatcher/dispatcher.go @@ -2,7 +2,6 @@ package dispatcher import ( "v2ray.com/core/app" - "v2ray.com/core/common/serial" "v2ray.com/core/proxy" "v2ray.com/core/transport/ray" ) @@ -13,7 +12,7 @@ type PacketDispatcher interface { } func FromSpace(space app.Space) PacketDispatcher { - if app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil))); app != nil { + if app := space.GetApplication((*PacketDispatcher)(nil)); app != nil { return app.(PacketDispatcher) } return nil diff --git a/app/dispatcher/impl/default.go b/app/dispatcher/impl/default.go index 1fc7763c4..fdaf4f258 100644 --- a/app/dispatcher/impl/default.go +++ b/app/dispatcher/impl/default.go @@ -1,6 +1,7 @@ package impl import ( + "context" "time" "v2ray.com/core/app" @@ -21,7 +22,11 @@ type DefaultDispatcher struct { router *router.Router } -func NewDefaultDispatcher(space app.Space) *DefaultDispatcher { +func NewDefaultDispatcher(ctx context.Context, config *dispatcher.Config) (*DefaultDispatcher, error) { + space := app.SpaceFromContext(ctx) + if space == nil { + return nil, errors.New("DefaultDispatcher: No space in context.") + } d := &DefaultDispatcher{} space.OnInitialize(func() error { d.ohm = proxyman.OutboundHandlerManagerFromSpace(space) @@ -31,7 +36,11 @@ func NewDefaultDispatcher(space app.Space) *DefaultDispatcher { d.router = router.FromSpace(space) return nil }) - return d + return d, nil +} + +func (DefaultDispatcher) Interface() interface{} { + return (*dispatcher.PacketDispatcher)(nil) } func (v *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay { @@ -79,14 +88,10 @@ func (v *DefaultDispatcher) waitAndDispatch(wait func() error, destination v2net dispatcher.Dispatch(destination, link) } -type DefaultDispatcherFactory struct{} - -func (v DefaultDispatcherFactory) Create(space app.Space, config interface{}) (app.Application, error) { - return NewDefaultDispatcher(space), nil -} - func init() { - common.Must(app.RegisterApplicationFactory((*dispatcher.Config)(nil), DefaultDispatcherFactory{})) + common.Must(common.RegisterConfig((*dispatcher.Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { + return NewDefaultDispatcher(ctx, config.(*dispatcher.Config)) + })) } type waitDataInspector struct { diff --git a/app/dns/dns.go b/app/dns/dns.go index 85f7f58b3..2963447bb 100644 --- a/app/dns/dns.go +++ b/app/dns/dns.go @@ -4,7 +4,6 @@ import ( "net" "v2ray.com/core/app" - "v2ray.com/core/common/serial" ) // A DnsCache is an internal cache of DNS resolutions. @@ -13,7 +12,7 @@ type Server interface { } func FromSpace(space app.Space) Server { - app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil))) + app := space.GetApplication((*Server)(nil)) if app == nil { return nil } diff --git a/app/dns/server/server.go b/app/dns/server/server.go index ef326cb5f..39e3e1bfd 100644 --- a/app/dns/server/server.go +++ b/app/dns/server/server.go @@ -1,10 +1,12 @@ package server import ( + "context" "net" "sync" "time" + dnsmsg "github.com/miekg/dns" "v2ray.com/core/app" "v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dns" @@ -12,8 +14,6 @@ import ( "v2ray.com/core/common/errors" "v2ray.com/core/common/log" v2net "v2ray.com/core/common/net" - - dnsmsg "github.com/miekg/dns" ) const ( @@ -32,7 +32,11 @@ type CacheServer struct { servers []NameServer } -func NewCacheServer(space app.Space, config *dns.Config) *CacheServer { +func NewCacheServer(ctx context.Context, config *dns.Config) (*CacheServer, error) { + space := app.SpaceFromContext(ctx) + if space == nil { + return nil, errors.New("DNSCacheServer: No space in context.") + } server := &CacheServer{ records: make(map[string]*DomainRecord), servers: make([]NameServer, len(config.NameServers)), @@ -62,7 +66,11 @@ func NewCacheServer(space app.Space, config *dns.Config) *CacheServer { } return nil }) - return server + return server, nil +} + +func (CacheServer) Interface() interface{} { + return (*dns.Server)(nil) } // Private: Visible for testing. @@ -109,13 +117,8 @@ func (v *CacheServer) Get(domain string) []net.IP { return nil } -type CacheServerFactory struct{} - -func (v CacheServerFactory) Create(space app.Space, config interface{}) (app.Application, error) { - server := NewCacheServer(space, config.(*dns.Config)) - return server, nil -} - func init() { - common.Must(app.RegisterApplicationFactory((*dns.Config)(nil), CacheServerFactory{})) + common.Must(common.RegisterConfig((*dns.Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { + return NewCacheServer(ctx, config.(*dns.Config)) + })) } diff --git a/app/proxy/proxy.go b/app/proxy/proxy.go index 981a46d44..667f7d99b 100644 --- a/app/proxy/proxy.go +++ b/app/proxy/proxy.go @@ -5,6 +5,8 @@ import ( "net" "time" + "context" + "v2ray.com/core/app" "v2ray.com/core/app/proxyman" "v2ray.com/core/common" @@ -12,7 +14,6 @@ import ( "v2ray.com/core/common/errors" "v2ray.com/core/common/log" v2net "v2ray.com/core/common/net" - "v2ray.com/core/common/serial" "v2ray.com/core/transport/internet" "v2ray.com/core/transport/ray" ) @@ -21,7 +22,11 @@ type OutboundProxy struct { outboundManager proxyman.OutboundHandlerManager } -func NewOutboundProxy(space app.Space) *OutboundProxy { +func NewOutboundProxy(ctx context.Context, config *Config) (*OutboundProxy, error) { + space := app.SpaceFromContext(ctx) + if space == nil { + return nil, errors.New("OutboundProxy: No space in context.") + } proxy := new(OutboundProxy) space.OnInitialize(func() error { proxy.outboundManager = proxyman.OutboundHandlerManagerFromSpace(space) @@ -30,7 +35,11 @@ func NewOutboundProxy(space app.Space) *OutboundProxy { } return nil }) - return proxy + return proxy, nil +} + +func (OutboundProxy) Interface() interface{} { + return (*OutboundProxy)(nil) } func (v *OutboundProxy) RegisterDialer() { @@ -132,14 +141,8 @@ func (v *Connection) SetReusable(bool) { } -type OutboundProxyFactory struct{} - -func (OutboundProxyFactory) Create(space app.Space, config interface{}) (app.Application, error) { - return NewOutboundProxy(space), nil -} - func OutboundProxyFromSpace(space app.Space) *OutboundProxy { - app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil))) + app := space.GetApplication((*OutboundProxy)(nil)) if app == nil { return nil } @@ -147,5 +150,7 @@ func OutboundProxyFromSpace(space app.Space) *OutboundProxy { } func init() { - common.Must(app.RegisterApplicationFactory((*Config)(nil), OutboundProxyFactory{})) + common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { + return NewOutboundProxy(ctx, config.(*Config)) + })) } diff --git a/app/proxy/proxy_test.go b/app/proxy/proxy_test.go index 14ded5686..79871a40d 100644 --- a/app/proxy/proxy_test.go +++ b/app/proxy/proxy_test.go @@ -23,7 +23,7 @@ func TestProxyDial(t *testing.T) { space := app.NewSpace() ctx := app.ContextWithSpace(context.Background(), space) - assert.Error(space.AddApp(new(proxyman.OutboundConfig))) + assert.Error(app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig))).IsNil() outboundManager := proxyman.OutboundHandlerManagerFromSpace(space) freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{ Tag: "tag", @@ -34,9 +34,8 @@ func TestProxyDial(t *testing.T) { assert.Error(err).IsNil() common.Must(outboundManager.SetHandler("tag", freedom)) - assert.Error(space.AddApp(new(Config))).IsNil() + assert.Error(app.AddApplicationToSpace(ctx, new(Config))).IsNil() proxy := OutboundProxyFromSpace(space) - assert.Error(space.Initialize()).IsNil() xor := func(b []byte) []byte { diff --git a/app/proxyman/outbound/outbound.go b/app/proxyman/outbound/outbound.go index e957baf81..8e4ad820f 100644 --- a/app/proxyman/outbound/outbound.go +++ b/app/proxyman/outbound/outbound.go @@ -3,7 +3,8 @@ package outbound import ( "sync" - "v2ray.com/core/app" + "context" + "v2ray.com/core/app/proxyman" "v2ray.com/core/common" "v2ray.com/core/proxy" @@ -15,10 +16,14 @@ type DefaultOutboundHandlerManager struct { taggedHandler map[string]proxy.OutboundHandler } -func New() *DefaultOutboundHandlerManager { +func New(ctx context.Context, config *proxyman.OutboundConfig) (*DefaultOutboundHandlerManager, error) { return &DefaultOutboundHandlerManager{ taggedHandler: make(map[string]proxy.OutboundHandler), - } + }, nil +} + +func (DefaultOutboundHandlerManager) Interface() interface{} { + return (*proxyman.OutboundHandlerManager)(nil) } func (v *DefaultOutboundHandlerManager) GetDefaultHandler() proxy.OutboundHandler { @@ -54,12 +59,8 @@ func (v *DefaultOutboundHandlerManager) SetHandler(tag string, handler proxy.Out return nil } -type OutboundHandlerManagerFactory struct{} - -func (v OutboundHandlerManagerFactory) Create(space app.Space, config interface{}) (app.Application, error) { - return New(), nil -} - func init() { - common.Must(app.RegisterApplicationFactory((*proxyman.OutboundConfig)(nil), OutboundHandlerManagerFactory{})) + common.Must(common.RegisterConfig((*proxyman.OutboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { + return New(ctx, config.(*proxyman.OutboundConfig)) + })) } diff --git a/app/proxyman/proxyman.go b/app/proxyman/proxyman.go index 1bff9a674..bc74f195a 100644 --- a/app/proxyman/proxyman.go +++ b/app/proxyman/proxyman.go @@ -3,7 +3,6 @@ package proxyman import ( "v2ray.com/core/app" - "v2ray.com/core/common/serial" "v2ray.com/core/proxy" ) @@ -19,7 +18,7 @@ type OutboundHandlerManager interface { } func InboundHandlerManagerFromSpace(space app.Space) InboundHandlerManager { - app := space.(app.AppGetter).GetApp(serial.GetMessageType((*InboundConfig)(nil))) + app := space.GetApplication((*InboundHandlerManager)(nil)) if app == nil { return nil } @@ -27,7 +26,7 @@ func InboundHandlerManagerFromSpace(space app.Space) InboundHandlerManager { } func OutboundHandlerManagerFromSpace(space app.Space) OutboundHandlerManager { - app := space.(app.AppGetter).GetApp(serial.GetMessageType((*OutboundConfig)(nil))) + app := space.GetApplication((*OutboundHandlerManager)(nil)) if app == nil { return nil } diff --git a/app/router/router.go b/app/router/router.go index 35c98efbd..9160c207c 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -1,13 +1,14 @@ package router import ( + "context" + "v2ray.com/core/app" "v2ray.com/core/app/dns" "v2ray.com/core/common" "v2ray.com/core/common/errors" "v2ray.com/core/common/log" v2net "v2ray.com/core/common/net" - "v2ray.com/core/common/serial" "v2ray.com/core/proxy" ) @@ -23,7 +24,11 @@ type Router struct { dnsServer dns.Server } -func NewRouter(config *Config, space app.Space) *Router { +func NewRouter(ctx context.Context, config *Config) (*Router, error) { + space := app.SpaceFromContext(ctx) + if space == nil { + return nil, errors.New("Router: No space in context.") + } r := &Router{ domainStrategy: config.DomainStrategy, //cache: NewRoutingTable(), @@ -46,7 +51,7 @@ func NewRouter(config *Config, space app.Space) *Router { } return nil }) - return r + return r, nil } // Private: Visible for testing. @@ -106,15 +111,14 @@ func (v *Router) TakeDetour(session *proxy.SessionInfo) (string, error) { //return tag, err } -type RouterFactory struct{} - -func (RouterFactory) Create(space app.Space, config interface{}) (app.Application, error) { - router := NewRouter(config.(*Config), space) - return router, nil +func (Router) Interface() interface{} { + return (*Router)(nil) } +type RouterFactory struct{} + func FromSpace(space app.Space) *Router { - app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil))) + app := space.GetApplication((*Router)(nil)) if app == nil { return nil } @@ -122,5 +126,7 @@ func FromSpace(space app.Space) *Router { } func init() { - common.Must(app.RegisterApplicationFactory((*Config)(nil), RouterFactory{})) + common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { + return NewRouter(ctx, config.(*Config)) + })) } diff --git a/app/router/router_test.go b/app/router/router_test.go index a298987e7..d2f2a9133 100644 --- a/app/router/router_test.go +++ b/app/router/router_test.go @@ -1,6 +1,7 @@ package router_test import ( + "context" "testing" "v2ray.com/core/app" @@ -31,10 +32,11 @@ func TestSimpleRouter(t *testing.T) { } space := app.NewSpace() - assert.Error(space.AddApp(new(dns.Config))).IsNil() - assert.Error(space.AddApp(new(dispatcher.Config))).IsNil() - assert.Error(space.AddApp(new(proxyman.OutboundConfig))).IsNil() - assert.Error(space.AddApp(config)).IsNil() + ctx := app.ContextWithSpace(context.Background(), space) + assert.Error(app.AddApplicationToSpace(ctx, new(dns.Config))).IsNil() + assert.Error(app.AddApplicationToSpace(ctx, new(dispatcher.Config))).IsNil() + assert.Error(app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig))).IsNil() + assert.Error(app.AddApplicationToSpace(ctx, config)).IsNil() assert.Error(space.Initialize()).IsNil() r := FromSpace(space) diff --git a/app/sender/sender.go b/app/sender/sender.go index a2413ccaa..a8877b9a7 100644 --- a/app/sender/sender.go +++ b/app/sender/sender.go @@ -1,10 +1,11 @@ package sender import ( + "context" + "v2ray.com/core/app" "v2ray.com/core/common" "v2ray.com/core/common/net" - "v2ray.com/core/common/serial" "v2ray.com/core/transport/internet" ) @@ -15,18 +16,16 @@ type Sender interface { type SenderManager struct { } -func New(space app.Space, config *Config) (*SenderManager, error) { +func New(ctx context.Context, config *Config) (*SenderManager, error) { return &SenderManager{}, nil } -type SenderManagerFactory struct{} - -func (SenderManagerFactory) Create(space app.Space, config interface{}) (app.Application, error) { - return New(space, config.(*Config)) +func (SenderManager) Interface() interface{} { + return (*SenderManager)(nil) } func FromSpace(space app.Space) *SenderManager { - app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil))) + app := space.GetApplication((*SenderManager)(nil)) if app == nil { return nil } @@ -34,5 +33,7 @@ func FromSpace(space app.Space) *SenderManager { } func init() { - common.Must(app.RegisterApplicationFactory((*Config)(nil), SenderManagerFactory{})) + common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { + return New(ctx, config.(*Config)) + })) } diff --git a/app/space.go b/app/space.go index ed095b5c2..d39282822 100644 --- a/app/space.go +++ b/app/space.go @@ -2,60 +2,50 @@ package app import ( "context" + "reflect" - "github.com/golang/protobuf/proto" + "v2ray.com/core/common" "v2ray.com/core/common/errors" "v2ray.com/core/common/log" - "v2ray.com/core/common/serial" ) type Application interface { + Interface() interface{} } type InitializationCallback func() error -type ApplicationFactory interface { - Create(space Space, config interface{}) (Application, error) -} - -type AppGetter interface { - GetApp(name string) Application -} - -var ( - applicationFactoryCache = make(map[string]ApplicationFactory) -) - -func RegisterApplicationFactory(defaultConfig proto.Message, factory ApplicationFactory) error { - if defaultConfig == nil { - return errors.New("Space: config is nil.") +func CreateAppFromConfig(ctx context.Context, config interface{}) (Application, error) { + application, err := common.CreateObject(ctx, config) + if err != nil { + return nil, err } - name := serial.GetMessageType(defaultConfig) - if len(name) == 0 { - return errors.New("Space: cannot get config type.") + switch a := application.(type) { + case Application: + return a, nil + default: + return nil, errors.New("App: Not an application.") } - applicationFactoryCache[name] = factory - return nil } // A Space contains all apps that may be available in a V2Ray runtime. // Caller must check the availability of an app by calling HasXXX before getting its instance. type Space interface { - AddApp(config proto.Message) error - AddAppLegacy(name string, app Application) + GetApplication(appInterface interface{}) Application + AddApplication(application Application) error Initialize() error OnInitialize(InitializationCallback) } type spaceImpl struct { initialized bool - cache map[string]Application + cache map[reflect.Type]Application appInit []InitializationCallback } func NewSpace() Space { return &spaceImpl{ - cache: make(map[string]Application), + cache: make(map[reflect.Type]Application), appInit: make([]InitializationCallback, 0, 32), } } @@ -81,38 +71,35 @@ func (v *spaceImpl) Initialize() error { return nil } -func (v *spaceImpl) GetApp(configType string) Application { - obj, found := v.cache[configType] - if !found { - return nil - } - return obj +func (v *spaceImpl) GetApplication(appInterface interface{}) Application { + appType := reflect.TypeOf(appInterface) + return v.cache[appType] } -func (v *spaceImpl) AddApp(config proto.Message) error { - configName := serial.GetMessageType(config) - factory, found := applicationFactoryCache[configName] - if !found { - return errors.New("Space: app not registered: ", configName) - } - app, err := factory.Create(v, config) - if err != nil { - return err - } - v.cache[configName] = app +func (v *spaceImpl) AddApplication(app Application) error { + appType := reflect.TypeOf(app.Interface()) + v.cache[appType] = app return nil } -func (v *spaceImpl) AddAppLegacy(name string, application Application) { - v.cache[name] = application -} - type contextKey int const ( spaceKey = contextKey(0) ) +func AddApplicationToSpace(ctx context.Context, appConfig interface{}) error { + space := SpaceFromContext(ctx) + if space == nil { + return errors.New("App: No space in context.") + } + application, err := CreateAppFromConfig(ctx, appConfig) + if err != nil { + return err + } + return space.AddApplication(application) +} + func SpaceFromContext(ctx context.Context) Space { return ctx.Value(spaceKey).(Space) } diff --git a/proxy/dokodemo/dokodemo_test.go b/proxy/dokodemo/dokodemo_test.go index 2047c0de9..aee4240f0 100644 --- a/proxy/dokodemo/dokodemo_test.go +++ b/proxy/dokodemo/dokodemo_test.go @@ -40,13 +40,11 @@ func TestDokodemoTCP(t *testing.T) { defer tcpServer.Close() space := app.NewSpace() - space.AddApp(new(dispatcher.Config)) - space.AddApp(new(proxyman.OutboundConfig)) + ctx := app.ContextWithSpace(context.Background(), space) + app.AddApplicationToSpace(ctx, new(dispatcher.Config)) + app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig)) ohm := proxyman.OutboundHandlerManagerFromSpace(space) - ctx := context.Background() - ctx = app.ContextWithSpace(ctx, space) - freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{ Address: v2net.LocalHostIP, StreamSettings: &internet.StreamConfig{ @@ -117,13 +115,11 @@ func TestDokodemoUDP(t *testing.T) { defer udpServer.Close() space := app.NewSpace() - space.AddApp(new(dispatcher.Config)) - space.AddApp(new(proxyman.OutboundConfig)) + ctx := app.ContextWithSpace(context.Background(), space) + app.AddApplicationToSpace(ctx, new(dispatcher.Config)) + app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig)) ohm := proxyman.OutboundHandlerManagerFromSpace(space) - - ctx := context.Background() - ctx = app.ContextWithSpace(ctx, space) freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{ Address: v2net.AnyIP, StreamSettings: &internet.StreamConfig{ diff --git a/proxy/freedom/freedom_test.go b/proxy/freedom/freedom_test.go index f32d485c0..5c349b23f 100644 --- a/proxy/freedom/freedom_test.go +++ b/proxy/freedom/freedom_test.go @@ -70,16 +70,16 @@ func TestIPResolution(t *testing.T) { assert := assert.On(t) space := app.NewSpace() - assert.Error(space.AddApp(new(proxyman.OutboundConfig))).IsNil() - assert.Error(space.AddApp(new(dispatcher.Config))).IsNil() - assert.Error(space.AddApp(new(router.Config))).IsNil() - assert.Error(space.AddApp(&dns.Config{ + ctx := app.ContextWithSpace(context.Background(), space) + assert.Error(app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig))).IsNil() + assert.Error(app.AddApplicationToSpace(ctx, new(dispatcher.Config))).IsNil() + assert.Error(app.AddApplicationToSpace(ctx, new(router.Config))).IsNil() + assert.Error(app.AddApplicationToSpace(ctx, &dns.Config{ Hosts: map[string]*v2net.IPOrDomain{ "v2ray.com": v2net.NewIPOrDomain(v2net.LocalHostIP), }, })).IsNil() - ctx := app.ContextWithSpace(context.Background(), space) ctx = proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{ Address: v2net.AnyIP, StreamSettings: &internet.StreamConfig{ diff --git a/v2ray.go b/v2ray.go index 14d9cd9f6..bc20affcf 100644 --- a/v2ray.go +++ b/v2ray.go @@ -11,7 +11,6 @@ import ( "v2ray.com/core/common" "v2ray.com/core/common/log" v2net "v2ray.com/core/common/net" - "v2ray.com/core/common/serial" "v2ray.com/core/proxy" ) @@ -43,29 +42,39 @@ func NewPoint(pConfig *Config) (*Point, error) { ctx := app.ContextWithSpace(context.Background(), space) vpoint.space = space - vpoint.space.AddAppLegacy(serial.GetMessageType((*proxyman.InboundConfig)(nil)), vpoint) + vpoint.space.AddApplication(vpoint) outboundHandlerManager := proxyman.OutboundHandlerManagerFromSpace(space) if outboundHandlerManager == nil { - if err := space.AddApp(new(proxyman.OutboundConfig)); err != nil { + o, err := app.CreateAppFromConfig(ctx, new(proxyman.OutboundConfig)) + if err != nil { return nil, err } - outboundHandlerManager = proxyman.OutboundHandlerManagerFromSpace(space) + space.AddApplication(o) + outboundHandlerManager = o.(proxyman.OutboundHandlerManager) } proxyDialer := proxydialer.OutboundProxyFromSpace(space) if proxyDialer == nil { - space.AddApp(new(proxydialer.Config)) - proxyDialer = proxydialer.OutboundProxyFromSpace(space) - } - proxyDialer.RegisterDialer() - - for _, app := range pConfig.App { - settings, err := app.GetInstance() + p, err := app.CreateAppFromConfig(ctx, new(proxydialer.Config)) if err != nil { return nil, err } - if err := space.AddApp(settings); err != nil { + space.AddApplication(p) + proxyDialer = p.(*proxydialer.OutboundProxy) + } + proxyDialer.RegisterDialer() + + for _, appSettings := range pConfig.App { + settings, err := appSettings.GetInstance() + if err != nil { + return nil, err + } + application, err := app.CreateAppFromConfig(ctx, settings) + if err != nil { + return nil, err + } + if err := space.AddApplication(application); err != nil { return nil, err } } @@ -77,18 +86,22 @@ func NewPoint(pConfig *Config) (*Point, error) { Address: v2net.NewIPOrDomain(v2net.LocalHostDomain), }}, } - if err := space.AddApp(dnsConfig); err != nil { + d, err := app.CreateAppFromConfig(ctx, dnsConfig) + if err != nil { return nil, err } + space.AddApplication(d) + dnsServer = d.(dns.Server) } disp := dispatcher.FromSpace(space) if disp == nil { - dispatcherConfig := new(dispatcher.Config) - if err := vpoint.space.AddApp(dispatcherConfig); err != nil { + d, err := app.CreateAppFromConfig(ctx, new(dispatcher.Config)) + if err != nil { return nil, err } - disp = dispatcher.FromSpace(space) + space.AddApplication(d) + disp = d.(dispatcher.PacketDispatcher) } vpoint.inboundHandlers = make([]InboundDetourHandler, 0, 8) @@ -156,6 +169,10 @@ func NewPoint(pConfig *Config) (*Point, error) { return vpoint, nil } +func (Point) Interface() interface{} { + return (*proxyman.InboundHandlerManager)(nil) +} + func (v *Point) Close() { for _, inbound := range v.inboundHandlers { inbound.Close()