1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-22 01:57:12 -05:00

context'ize apps

This commit is contained in:
Darien Raymond 2017-01-13 13:41:40 +01:00
parent 148e4832eb
commit 17504d2aac
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
15 changed files with 171 additions and 152 deletions

View File

@ -2,7 +2,6 @@ package dispatcher
import ( import (
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
"v2ray.com/core/transport/ray" "v2ray.com/core/transport/ray"
) )
@ -13,7 +12,7 @@ type PacketDispatcher interface {
} }
func FromSpace(space app.Space) PacketDispatcher { 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 app.(PacketDispatcher)
} }
return nil return nil

View File

@ -1,6 +1,7 @@
package impl package impl
import ( import (
"context"
"time" "time"
"v2ray.com/core/app" "v2ray.com/core/app"
@ -21,7 +22,11 @@ type DefaultDispatcher struct {
router *router.Router 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{} d := &DefaultDispatcher{}
space.OnInitialize(func() error { space.OnInitialize(func() error {
d.ohm = proxyman.OutboundHandlerManagerFromSpace(space) d.ohm = proxyman.OutboundHandlerManagerFromSpace(space)
@ -31,7 +36,11 @@ func NewDefaultDispatcher(space app.Space) *DefaultDispatcher {
d.router = router.FromSpace(space) d.router = router.FromSpace(space)
return nil return nil
}) })
return d return d, nil
}
func (DefaultDispatcher) Interface() interface{} {
return (*dispatcher.PacketDispatcher)(nil)
} }
func (v *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay { 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) 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() { 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 { type waitDataInspector struct {

View File

@ -4,7 +4,6 @@ import (
"net" "net"
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/common/serial"
) )
// A DnsCache is an internal cache of DNS resolutions. // A DnsCache is an internal cache of DNS resolutions.
@ -13,7 +12,7 @@ type Server interface {
} }
func FromSpace(space app.Space) Server { func FromSpace(space app.Space) Server {
app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil))) app := space.GetApplication((*Server)(nil))
if app == nil { if app == nil {
return nil return nil
} }

View File

@ -1,10 +1,12 @@
package server package server
import ( import (
"context"
"net" "net"
"sync" "sync"
"time" "time"
dnsmsg "github.com/miekg/dns"
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/dns" "v2ray.com/core/app/dns"
@ -12,8 +14,6 @@ import (
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
dnsmsg "github.com/miekg/dns"
) )
const ( const (
@ -32,7 +32,11 @@ type CacheServer struct {
servers []NameServer 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{ server := &CacheServer{
records: make(map[string]*DomainRecord), records: make(map[string]*DomainRecord),
servers: make([]NameServer, len(config.NameServers)), servers: make([]NameServer, len(config.NameServers)),
@ -62,7 +66,11 @@ func NewCacheServer(space app.Space, config *dns.Config) *CacheServer {
} }
return nil return nil
}) })
return server return server, nil
}
func (CacheServer) Interface() interface{} {
return (*dns.Server)(nil)
} }
// Private: Visible for testing. // Private: Visible for testing.
@ -109,13 +117,8 @@ func (v *CacheServer) Get(domain string) []net.IP {
return nil 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() { 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))
}))
} }

View File

@ -5,6 +5,8 @@ import (
"net" "net"
"time" "time"
"context"
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/common" "v2ray.com/core/common"
@ -12,7 +14,6 @@ import (
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/serial"
"v2ray.com/core/transport/internet" "v2ray.com/core/transport/internet"
"v2ray.com/core/transport/ray" "v2ray.com/core/transport/ray"
) )
@ -21,7 +22,11 @@ type OutboundProxy struct {
outboundManager proxyman.OutboundHandlerManager 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) proxy := new(OutboundProxy)
space.OnInitialize(func() error { space.OnInitialize(func() error {
proxy.outboundManager = proxyman.OutboundHandlerManagerFromSpace(space) proxy.outboundManager = proxyman.OutboundHandlerManagerFromSpace(space)
@ -30,7 +35,11 @@ func NewOutboundProxy(space app.Space) *OutboundProxy {
} }
return nil return nil
}) })
return proxy return proxy, nil
}
func (OutboundProxy) Interface() interface{} {
return (*OutboundProxy)(nil)
} }
func (v *OutboundProxy) RegisterDialer() { 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 { func OutboundProxyFromSpace(space app.Space) *OutboundProxy {
app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil))) app := space.GetApplication((*OutboundProxy)(nil))
if app == nil { if app == nil {
return nil return nil
} }
@ -147,5 +150,7 @@ func OutboundProxyFromSpace(space app.Space) *OutboundProxy {
} }
func init() { 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))
}))
} }

View File

@ -23,7 +23,7 @@ func TestProxyDial(t *testing.T) {
space := app.NewSpace() space := app.NewSpace()
ctx := app.ContextWithSpace(context.Background(), space) 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) outboundManager := proxyman.OutboundHandlerManagerFromSpace(space)
freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{ freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{
Tag: "tag", Tag: "tag",
@ -34,9 +34,8 @@ func TestProxyDial(t *testing.T) {
assert.Error(err).IsNil() assert.Error(err).IsNil()
common.Must(outboundManager.SetHandler("tag", freedom)) common.Must(outboundManager.SetHandler("tag", freedom))
assert.Error(space.AddApp(new(Config))).IsNil() assert.Error(app.AddApplicationToSpace(ctx, new(Config))).IsNil()
proxy := OutboundProxyFromSpace(space) proxy := OutboundProxyFromSpace(space)
assert.Error(space.Initialize()).IsNil() assert.Error(space.Initialize()).IsNil()
xor := func(b []byte) []byte { xor := func(b []byte) []byte {

View File

@ -3,7 +3,8 @@ package outbound
import ( import (
"sync" "sync"
"v2ray.com/core/app" "context"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
@ -15,10 +16,14 @@ type DefaultOutboundHandlerManager struct {
taggedHandler map[string]proxy.OutboundHandler taggedHandler map[string]proxy.OutboundHandler
} }
func New() *DefaultOutboundHandlerManager { func New(ctx context.Context, config *proxyman.OutboundConfig) (*DefaultOutboundHandlerManager, error) {
return &DefaultOutboundHandlerManager{ return &DefaultOutboundHandlerManager{
taggedHandler: make(map[string]proxy.OutboundHandler), taggedHandler: make(map[string]proxy.OutboundHandler),
} }, nil
}
func (DefaultOutboundHandlerManager) Interface() interface{} {
return (*proxyman.OutboundHandlerManager)(nil)
} }
func (v *DefaultOutboundHandlerManager) GetDefaultHandler() proxy.OutboundHandler { func (v *DefaultOutboundHandlerManager) GetDefaultHandler() proxy.OutboundHandler {
@ -54,12 +59,8 @@ func (v *DefaultOutboundHandlerManager) SetHandler(tag string, handler proxy.Out
return nil return nil
} }
type OutboundHandlerManagerFactory struct{}
func (v OutboundHandlerManagerFactory) Create(space app.Space, config interface{}) (app.Application, error) {
return New(), nil
}
func init() { 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))
}))
} }

View File

@ -3,7 +3,6 @@ package proxyman
import ( import (
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
) )
@ -19,7 +18,7 @@ type OutboundHandlerManager interface {
} }
func InboundHandlerManagerFromSpace(space app.Space) InboundHandlerManager { func InboundHandlerManagerFromSpace(space app.Space) InboundHandlerManager {
app := space.(app.AppGetter).GetApp(serial.GetMessageType((*InboundConfig)(nil))) app := space.GetApplication((*InboundHandlerManager)(nil))
if app == nil { if app == nil {
return nil return nil
} }
@ -27,7 +26,7 @@ func InboundHandlerManagerFromSpace(space app.Space) InboundHandlerManager {
} }
func OutboundHandlerManagerFromSpace(space app.Space) OutboundHandlerManager { func OutboundHandlerManagerFromSpace(space app.Space) OutboundHandlerManager {
app := space.(app.AppGetter).GetApp(serial.GetMessageType((*OutboundConfig)(nil))) app := space.GetApplication((*OutboundHandlerManager)(nil))
if app == nil { if app == nil {
return nil return nil
} }

View File

@ -1,13 +1,14 @@
package router package router
import ( import (
"context"
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/app/dns" "v2ray.com/core/app/dns"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
) )
@ -23,7 +24,11 @@ type Router struct {
dnsServer dns.Server 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{ r := &Router{
domainStrategy: config.DomainStrategy, domainStrategy: config.DomainStrategy,
//cache: NewRoutingTable(), //cache: NewRoutingTable(),
@ -46,7 +51,7 @@ func NewRouter(config *Config, space app.Space) *Router {
} }
return nil return nil
}) })
return r return r, nil
} }
// Private: Visible for testing. // Private: Visible for testing.
@ -106,15 +111,14 @@ func (v *Router) TakeDetour(session *proxy.SessionInfo) (string, error) {
//return tag, err //return tag, err
} }
type RouterFactory struct{} func (Router) Interface() interface{} {
return (*Router)(nil)
func (RouterFactory) Create(space app.Space, config interface{}) (app.Application, error) {
router := NewRouter(config.(*Config), space)
return router, nil
} }
type RouterFactory struct{}
func FromSpace(space app.Space) *Router { func FromSpace(space app.Space) *Router {
app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil))) app := space.GetApplication((*Router)(nil))
if app == nil { if app == nil {
return nil return nil
} }
@ -122,5 +126,7 @@ func FromSpace(space app.Space) *Router {
} }
func init() { 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))
}))
} }

View File

@ -1,6 +1,7 @@
package router_test package router_test
import ( import (
"context"
"testing" "testing"
"v2ray.com/core/app" "v2ray.com/core/app"
@ -31,10 +32,11 @@ func TestSimpleRouter(t *testing.T) {
} }
space := app.NewSpace() space := app.NewSpace()
assert.Error(space.AddApp(new(dns.Config))).IsNil() ctx := app.ContextWithSpace(context.Background(), space)
assert.Error(space.AddApp(new(dispatcher.Config))).IsNil() assert.Error(app.AddApplicationToSpace(ctx, new(dns.Config))).IsNil()
assert.Error(space.AddApp(new(proxyman.OutboundConfig))).IsNil() assert.Error(app.AddApplicationToSpace(ctx, new(dispatcher.Config))).IsNil()
assert.Error(space.AddApp(config)).IsNil() assert.Error(app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig))).IsNil()
assert.Error(app.AddApplicationToSpace(ctx, config)).IsNil()
assert.Error(space.Initialize()).IsNil() assert.Error(space.Initialize()).IsNil()
r := FromSpace(space) r := FromSpace(space)

View File

@ -1,10 +1,11 @@
package sender package sender
import ( import (
"context"
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/serial"
"v2ray.com/core/transport/internet" "v2ray.com/core/transport/internet"
) )
@ -15,18 +16,16 @@ type Sender interface {
type SenderManager struct { type SenderManager struct {
} }
func New(space app.Space, config *Config) (*SenderManager, error) { func New(ctx context.Context, config *Config) (*SenderManager, error) {
return &SenderManager{}, nil return &SenderManager{}, nil
} }
type SenderManagerFactory struct{} func (SenderManager) Interface() interface{} {
return (*SenderManager)(nil)
func (SenderManagerFactory) Create(space app.Space, config interface{}) (app.Application, error) {
return New(space, config.(*Config))
} }
func FromSpace(space app.Space) *SenderManager { func FromSpace(space app.Space) *SenderManager {
app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil))) app := space.GetApplication((*SenderManager)(nil))
if app == nil { if app == nil {
return nil return nil
} }
@ -34,5 +33,7 @@ func FromSpace(space app.Space) *SenderManager {
} }
func init() { 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))
}))
} }

View File

@ -2,60 +2,50 @@ package app
import ( import (
"context" "context"
"reflect"
"github.com/golang/protobuf/proto" "v2ray.com/core/common"
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
"v2ray.com/core/common/serial"
) )
type Application interface { type Application interface {
Interface() interface{}
} }
type InitializationCallback func() error type InitializationCallback func() error
type ApplicationFactory interface { func CreateAppFromConfig(ctx context.Context, config interface{}) (Application, error) {
Create(space Space, config interface{}) (Application, error) application, err := common.CreateObject(ctx, config)
} if err != nil {
return nil, err
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.")
} }
name := serial.GetMessageType(defaultConfig) switch a := application.(type) {
if len(name) == 0 { case Application:
return errors.New("Space: cannot get config type.") 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. // 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. // Caller must check the availability of an app by calling HasXXX before getting its instance.
type Space interface { type Space interface {
AddApp(config proto.Message) error GetApplication(appInterface interface{}) Application
AddAppLegacy(name string, app Application) AddApplication(application Application) error
Initialize() error Initialize() error
OnInitialize(InitializationCallback) OnInitialize(InitializationCallback)
} }
type spaceImpl struct { type spaceImpl struct {
initialized bool initialized bool
cache map[string]Application cache map[reflect.Type]Application
appInit []InitializationCallback appInit []InitializationCallback
} }
func NewSpace() Space { func NewSpace() Space {
return &spaceImpl{ return &spaceImpl{
cache: make(map[string]Application), cache: make(map[reflect.Type]Application),
appInit: make([]InitializationCallback, 0, 32), appInit: make([]InitializationCallback, 0, 32),
} }
} }
@ -81,38 +71,35 @@ func (v *spaceImpl) Initialize() error {
return nil return nil
} }
func (v *spaceImpl) GetApp(configType string) Application { func (v *spaceImpl) GetApplication(appInterface interface{}) Application {
obj, found := v.cache[configType] appType := reflect.TypeOf(appInterface)
if !found { return v.cache[appType]
return nil
}
return obj
} }
func (v *spaceImpl) AddApp(config proto.Message) error { func (v *spaceImpl) AddApplication(app Application) error {
configName := serial.GetMessageType(config) appType := reflect.TypeOf(app.Interface())
factory, found := applicationFactoryCache[configName] v.cache[appType] = app
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
return nil return nil
} }
func (v *spaceImpl) AddAppLegacy(name string, application Application) {
v.cache[name] = application
}
type contextKey int type contextKey int
const ( const (
spaceKey = contextKey(0) 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 { func SpaceFromContext(ctx context.Context) Space {
return ctx.Value(spaceKey).(Space) return ctx.Value(spaceKey).(Space)
} }

View File

@ -40,13 +40,11 @@ func TestDokodemoTCP(t *testing.T) {
defer tcpServer.Close() defer tcpServer.Close()
space := app.NewSpace() space := app.NewSpace()
space.AddApp(new(dispatcher.Config)) ctx := app.ContextWithSpace(context.Background(), space)
space.AddApp(new(proxyman.OutboundConfig)) app.AddApplicationToSpace(ctx, new(dispatcher.Config))
app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig))
ohm := proxyman.OutboundHandlerManagerFromSpace(space) ohm := proxyman.OutboundHandlerManagerFromSpace(space)
ctx := context.Background()
ctx = app.ContextWithSpace(ctx, space)
freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{ freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{
Address: v2net.LocalHostIP, Address: v2net.LocalHostIP,
StreamSettings: &internet.StreamConfig{ StreamSettings: &internet.StreamConfig{
@ -117,13 +115,11 @@ func TestDokodemoUDP(t *testing.T) {
defer udpServer.Close() defer udpServer.Close()
space := app.NewSpace() space := app.NewSpace()
space.AddApp(new(dispatcher.Config)) ctx := app.ContextWithSpace(context.Background(), space)
space.AddApp(new(proxyman.OutboundConfig)) app.AddApplicationToSpace(ctx, new(dispatcher.Config))
app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig))
ohm := proxyman.OutboundHandlerManagerFromSpace(space) ohm := proxyman.OutboundHandlerManagerFromSpace(space)
ctx := context.Background()
ctx = app.ContextWithSpace(ctx, space)
freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{ freedom, err := freedom.New(proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{
Address: v2net.AnyIP, Address: v2net.AnyIP,
StreamSettings: &internet.StreamConfig{ StreamSettings: &internet.StreamConfig{

View File

@ -70,16 +70,16 @@ func TestIPResolution(t *testing.T) {
assert := assert.On(t) assert := assert.On(t)
space := app.NewSpace() space := app.NewSpace()
assert.Error(space.AddApp(new(proxyman.OutboundConfig))).IsNil() ctx := app.ContextWithSpace(context.Background(), space)
assert.Error(space.AddApp(new(dispatcher.Config))).IsNil() assert.Error(app.AddApplicationToSpace(ctx, new(proxyman.OutboundConfig))).IsNil()
assert.Error(space.AddApp(new(router.Config))).IsNil() assert.Error(app.AddApplicationToSpace(ctx, new(dispatcher.Config))).IsNil()
assert.Error(space.AddApp(&dns.Config{ assert.Error(app.AddApplicationToSpace(ctx, new(router.Config))).IsNil()
assert.Error(app.AddApplicationToSpace(ctx, &dns.Config{
Hosts: map[string]*v2net.IPOrDomain{ Hosts: map[string]*v2net.IPOrDomain{
"v2ray.com": v2net.NewIPOrDomain(v2net.LocalHostIP), "v2ray.com": v2net.NewIPOrDomain(v2net.LocalHostIP),
}, },
})).IsNil() })).IsNil()
ctx := app.ContextWithSpace(context.Background(), space)
ctx = proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{ ctx = proxy.ContextWithOutboundMeta(ctx, &proxy.OutboundHandlerMeta{
Address: v2net.AnyIP, Address: v2net.AnyIP,
StreamSettings: &internet.StreamConfig{ StreamSettings: &internet.StreamConfig{

View File

@ -11,7 +11,6 @@ import (
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
) )
@ -43,29 +42,39 @@ func NewPoint(pConfig *Config) (*Point, error) {
ctx := app.ContextWithSpace(context.Background(), space) ctx := app.ContextWithSpace(context.Background(), space)
vpoint.space = space vpoint.space = space
vpoint.space.AddAppLegacy(serial.GetMessageType((*proxyman.InboundConfig)(nil)), vpoint) vpoint.space.AddApplication(vpoint)
outboundHandlerManager := proxyman.OutboundHandlerManagerFromSpace(space) outboundHandlerManager := proxyman.OutboundHandlerManagerFromSpace(space)
if outboundHandlerManager == nil { 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 return nil, err
} }
outboundHandlerManager = proxyman.OutboundHandlerManagerFromSpace(space) space.AddApplication(o)
outboundHandlerManager = o.(proxyman.OutboundHandlerManager)
} }
proxyDialer := proxydialer.OutboundProxyFromSpace(space) proxyDialer := proxydialer.OutboundProxyFromSpace(space)
if proxyDialer == nil { if proxyDialer == nil {
space.AddApp(new(proxydialer.Config)) p, err := app.CreateAppFromConfig(ctx, new(proxydialer.Config))
proxyDialer = proxydialer.OutboundProxyFromSpace(space)
}
proxyDialer.RegisterDialer()
for _, app := range pConfig.App {
settings, err := app.GetInstance()
if err != nil { if err != nil {
return nil, err 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 return nil, err
} }
} }
@ -77,18 +86,22 @@ func NewPoint(pConfig *Config) (*Point, error) {
Address: v2net.NewIPOrDomain(v2net.LocalHostDomain), Address: v2net.NewIPOrDomain(v2net.LocalHostDomain),
}}, }},
} }
if err := space.AddApp(dnsConfig); err != nil { d, err := app.CreateAppFromConfig(ctx, dnsConfig)
if err != nil {
return nil, err return nil, err
} }
space.AddApplication(d)
dnsServer = d.(dns.Server)
} }
disp := dispatcher.FromSpace(space) disp := dispatcher.FromSpace(space)
if disp == nil { if disp == nil {
dispatcherConfig := new(dispatcher.Config) d, err := app.CreateAppFromConfig(ctx, new(dispatcher.Config))
if err := vpoint.space.AddApp(dispatcherConfig); err != nil { if err != nil {
return nil, err return nil, err
} }
disp = dispatcher.FromSpace(space) space.AddApplication(d)
disp = d.(dispatcher.PacketDispatcher)
} }
vpoint.inboundHandlers = make([]InboundDetourHandler, 0, 8) vpoint.inboundHandlers = make([]InboundDetourHandler, 0, 8)
@ -156,6 +169,10 @@ func NewPoint(pConfig *Config) (*Point, error) {
return vpoint, nil return vpoint, nil
} }
func (Point) Interface() interface{} {
return (*proxyman.InboundHandlerManager)(nil)
}
func (v *Point) Close() { func (v *Point) Close() {
for _, inbound := range v.inboundHandlers { for _, inbound := range v.inboundHandlers {
inbound.Close() inbound.Close()