simplify app design

This commit is contained in:
Darien Raymond 2017-01-06 15:32:36 +01:00
parent 13e4506781
commit b11d48d73f
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
27 changed files with 286 additions and 283 deletions

View File

@ -1,12 +1,4 @@
package api
import (
"v2ray.com/core/app"
)
const (
APP_ID = app.ID(5)
)
type ApiServer struct {
}

View File

@ -2,15 +2,19 @@ package dispatcher
import (
"v2ray.com/core/app"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy"
"v2ray.com/core/transport/ray"
)
const (
APP_ID = app.ID(1)
)
// PacketDispatcher dispatch a packet and possibly further network payload to its destination.
type PacketDispatcher interface {
DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay
}
func FromSpace(space app.Space) PacketDispatcher {
if app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil))); app != nil {
return app.(PacketDispatcher)
}
return nil
}

View File

@ -7,11 +7,11 @@ import (
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/app/router"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"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"
"v2ray.com/core/transport/ray"
)
@ -23,27 +23,17 @@ type DefaultDispatcher struct {
func NewDefaultDispatcher(space app.Space) *DefaultDispatcher {
d := &DefaultDispatcher{}
space.InitializeApplication(func() error {
return d.Initialize(space)
space.OnInitialize(func() error {
d.ohm = proxyman.OutboundHandlerManagerFromSpace(space)
if d.ohm == nil {
return errors.New("DefaultDispatcher: OutboundHandlerManager is not found in the space.")
}
d.router = router.FromSpace(space)
return nil
})
return d
}
// Initialize initializes the dispatcher.
// Private: Used by app.Space only.
func (v *DefaultDispatcher) Initialize(space app.Space) error {
if !space.HasApp(proxyman.APP_ID_OUTBOUND_MANAGER) {
return errors.New("DefaultDispatcher: OutboundHandlerManager is not found in the space.")
}
v.ohm = space.GetApp(proxyman.APP_ID_OUTBOUND_MANAGER).(proxyman.OutboundHandlerManager)
if space.HasApp(router.APP_ID) {
v.router = space.GetApp(router.APP_ID).(*router.Router)
}
return nil
}
func (v *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
dispatcher := v.ohm.GetDefaultHandler()
destination := session.Destination
@ -95,12 +85,8 @@ func (v DefaultDispatcherFactory) Create(space app.Space, config interface{}) (a
return NewDefaultDispatcher(space), nil
}
func (v DefaultDispatcherFactory) AppId() app.ID {
return dispatcher.APP_ID
}
func init() {
app.RegisterApplicationFactory(serial.GetMessageType(new(dispatcher.Config)), DefaultDispatcherFactory{})
common.Must(app.RegisterApplicationFactory((*dispatcher.Config)(nil), DefaultDispatcherFactory{}))
}
type waitDataInspector struct {

View File

@ -1,44 +0,0 @@
package testing
import (
"v2ray.com/core/common/buf"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
"v2ray.com/core/transport/ray"
)
type TestPacketDispatcher struct {
Destination chan v2net.Destination
Handler func(destination v2net.Destination, traffic ray.OutboundRay)
}
func NewTestPacketDispatcher(handler func(destination v2net.Destination, traffic ray.OutboundRay)) *TestPacketDispatcher {
if handler == nil {
handler = func(destination v2net.Destination, traffic ray.OutboundRay) {
for {
payload, err := traffic.OutboundInput().Read()
if err != nil {
break
}
output := buf.New()
output.Append([]byte("Processed: "))
output.Append(payload.Bytes())
payload.Release()
traffic.OutboundOutput().Write(output)
}
traffic.OutboundOutput().Close()
}
}
return &TestPacketDispatcher{
Destination: make(chan v2net.Destination),
Handler: handler,
}
}
func (v *TestPacketDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
traffic := ray.NewRay()
v.Destination <- session.Destination
go v.Handler(session.Destination, traffic)
return traffic
}

View File

@ -4,13 +4,18 @@ import (
"net"
"v2ray.com/core/app"
)
const (
APP_ID = app.ID(2)
"v2ray.com/core/common/serial"
)
// A DnsCache is an internal cache of DNS resolutions.
type Server interface {
Get(domain string) []net.IP
}
func FromSpace(space app.Space) Server {
app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil)))
if app == nil {
return nil
}
return app.(Server)
}

View File

@ -8,10 +8,10 @@ import (
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"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"
dnsmsg "github.com/miekg/dns"
)
@ -38,12 +38,11 @@ func NewCacheServer(space app.Space, config *dns.Config) *CacheServer {
servers: make([]NameServer, len(config.NameServers)),
hosts: config.GetInternalHosts(),
}
space.InitializeApplication(func() error {
if !space.HasApp(dispatcher.APP_ID) {
space.OnInitialize(func() error {
disp := dispatcher.FromSpace(space)
if disp == nil {
return errors.New("DNS: Dispatcher is not found in the space.")
}
dispatcher := space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
for idx, destPB := range config.NameServers {
address := destPB.Address.AsAddress()
if address.Family().IsDomain() && address.Domain() == "localhost" {
@ -54,7 +53,7 @@ func NewCacheServer(space app.Space, config *dns.Config) *CacheServer {
dest.Network = v2net.Network_UDP
}
if dest.Network == v2net.Network_UDP {
server.servers[idx] = NewUDPNameServer(dest, dispatcher)
server.servers[idx] = NewUDPNameServer(dest, disp)
}
}
}
@ -117,10 +116,6 @@ func (v CacheServerFactory) Create(space app.Space, config interface{}) (app.App
return server, nil
}
func (v CacheServerFactory) AppId() app.ID {
return dns.APP_ID
}
func init() {
app.RegisterApplicationFactory(serial.GetMessageType(new(dns.Config)), CacheServerFactory{})
common.Must(app.RegisterApplicationFactory((*dns.Config)(nil), CacheServerFactory{}))
}

42
app/proxy/config.pb.go Normal file
View File

@ -0,0 +1,42 @@
package proxy
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Config struct {
}
func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func init() {
proto.RegisterType((*Config)(nil), "v2ray.core.app.proxy.Config")
}
func init() { proto.RegisterFile("v2ray.com/core/app/proxy/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 128 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x52, 0x2d, 0x33, 0x2a, 0x4a,
0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0xd0, 0x2f,
0x28, 0xca, 0xaf, 0xa8, 0xd4, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x4c, 0xd7, 0x2b, 0x28, 0xca, 0x2f,
0xc9, 0x17, 0x12, 0x81, 0x29, 0x2b, 0x4a, 0xd5, 0x4b, 0x2c, 0x28, 0xd0, 0x03, 0x2b, 0x51, 0xe2,
0xe0, 0x62, 0x73, 0x06, 0xab, 0x72, 0x72, 0xe5, 0x92, 0x48, 0xce, 0xcf, 0xd5, 0xc3, 0xa6, 0xca,
0x89, 0x1b, 0xa2, 0x26, 0x00, 0x64, 0x50, 0x14, 0x2b, 0x58, 0x6c, 0x15, 0x93, 0x48, 0x98, 0x51,
0x50, 0x62, 0xa5, 0x9e, 0x33, 0x48, 0xa9, 0x63, 0x41, 0x81, 0x5e, 0x00, 0x48, 0x38, 0x89, 0x0d,
0x6c, 0x9b, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x16, 0xbe, 0x54, 0x50, 0x96, 0x00, 0x00, 0x00,
}

10
app/proxy/config.proto Normal file
View File

@ -0,0 +1,10 @@
syntax = "proto3";
package v2ray.core.app.proxy;
option csharp_namespace = "V2Ray.Core.App.Proxy";
option go_package = "proxy";
option java_package = "com.v2ray.core.app.proxy";
option java_outer_classname = "ConfigProto";
message Config {
}

View File

@ -7,29 +7,27 @@ import (
"v2ray.com/core/app"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"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"
)
const (
APP_ID = 7
)
type OutboundProxy struct {
outboundManager proxyman.OutboundHandlerManager
}
func NewOutboundProxy(space app.Space) *OutboundProxy {
proxy := new(OutboundProxy)
space.InitializeApplication(func() error {
if !space.HasApp(proxyman.APP_ID_OUTBOUND_MANAGER) {
return errors.New("Proxy: Outbound handler manager not found.")
space.OnInitialize(func() error {
proxy.outboundManager = proxyman.OutboundHandlerManagerFromSpace(space)
if proxy.outboundManager == nil {
return errors.New("Proxy: Outbound handler manager not found in space.")
}
proxy.outboundManager = space.GetApp(proxyman.APP_ID_OUTBOUND_MANAGER).(proxyman.OutboundHandlerManager)
return nil
})
return proxy
@ -133,3 +131,21 @@ func (v *Connection) Reusable() bool {
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)))
if app == nil {
return nil
}
return app.(*OutboundProxy)
}
func init() {
common.Must(app.RegisterApplicationFactory((*Config)(nil), OutboundProxyFactory{}))
}

View File

@ -6,7 +6,7 @@ import (
"v2ray.com/core/app"
. "v2ray.com/core/app/proxy"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/app/proxyman/outbound"
_ "v2ray.com/core/app/proxyman/outbound"
"v2ray.com/core/common"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
@ -21,17 +21,17 @@ func TestProxyDial(t *testing.T) {
assert := assert.On(t)
space := app.NewSpace()
outboundManager := outbound.New()
assert.Error(space.AddApp(new(proxyman.OutboundConfig)))
outboundManager := proxyman.OutboundHandlerManagerFromSpace(space)
common.Must(outboundManager.SetHandler("tag", freedom.New(&freedom.Config{}, space, &proxy.OutboundHandlerMeta{
Tag: "tag",
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_TCP,
},
})))
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outboundManager)
proxy := NewOutboundProxy(space)
space.BindApp(APP_ID, proxy)
assert.Error(space.AddApp(new(Config))).IsNil()
proxy := OutboundProxyFromSpace(space)
assert.Error(space.Initialize()).IsNil()

View File

@ -5,7 +5,7 @@ import (
"v2ray.com/core/app"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common/serial"
"v2ray.com/core/common"
"v2ray.com/core/proxy"
)
@ -60,10 +60,6 @@ func (v OutboundHandlerManagerFactory) Create(space app.Space, config interface{
return New(), nil
}
func (v OutboundHandlerManagerFactory) AppId() app.ID {
return proxyman.APP_ID_OUTBOUND_MANAGER
}
func init() {
app.RegisterApplicationFactory(serial.GetMessageType(new(proxyman.OutboundConfig)), OutboundHandlerManagerFactory{})
common.Must(app.RegisterApplicationFactory((*proxyman.OutboundConfig)(nil), OutboundHandlerManagerFactory{}))
}

View File

@ -3,14 +3,10 @@ package proxyman
import (
"v2ray.com/core/app"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy"
)
const (
APP_ID_INBOUND_MANAGER = app.ID(4)
APP_ID_OUTBOUND_MANAGER = app.ID(6)
)
type InboundHandlerManager interface {
GetHandler(tag string) (proxy.InboundHandler, int)
}
@ -21,3 +17,19 @@ type OutboundHandlerManager interface {
SetDefaultHandler(handler proxy.OutboundHandler) error
SetHandler(tag string, handler proxy.OutboundHandler) error
}
func InboundHandlerManagerFromSpace(space app.Space) InboundHandlerManager {
app := space.(app.AppGetter).GetApp(serial.GetMessageType((*InboundConfig)(nil)))
if app == nil {
return nil
}
return app.(InboundHandlerManager)
}
func OutboundHandlerManagerFromSpace(space app.Space) OutboundHandlerManager {
app := space.(app.AppGetter).GetApp(serial.GetMessageType((*OutboundConfig)(nil)))
if app == nil {
return nil
}
return app.(OutboundHandlerManager)
}

View File

@ -3,6 +3,7 @@ package router
import (
"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"
@ -10,10 +11,6 @@ import (
"v2ray.com/core/proxy"
)
const (
APP_ID = app.ID(3)
)
var (
ErrInvalidRule = errors.New("Invalid Rule")
ErrNoRuleApplicable = errors.New("No rule applicable")
@ -33,7 +30,7 @@ func NewRouter(config *Config, space app.Space) *Router {
rules: make([]Rule, len(config.Rule)),
}
space.InitializeApplication(func() error {
space.OnInitialize(func() error {
for idx, rule := range config.Rule {
r.rules[idx].Tag = rule.Tag
cond, err := rule.BuildCondition()
@ -43,10 +40,10 @@ func NewRouter(config *Config, space app.Space) *Router {
r.rules[idx].Condition = cond
}
if !space.HasApp(dns.APP_ID) {
r.dnsServer = dns.FromSpace(space)
if r.dnsServer == nil {
return errors.New("Router: DNS is not found in the space.")
}
r.dnsServer = space.GetApp(dns.APP_ID).(dns.Server)
return nil
})
return r
@ -116,10 +113,14 @@ func (RouterFactory) Create(space app.Space, config interface{}) (app.Applicatio
return router, nil
}
func (RouterFactory) AppId() app.ID {
return APP_ID
func FromSpace(space app.Space) *Router {
app := space.(app.AppGetter).GetApp(serial.GetMessageType((*Config)(nil)))
if app == nil {
return nil
}
return app.(*Router)
}
func init() {
app.RegisterApplicationFactory(serial.GetMessageType(new(Config)), RouterFactory{})
common.Must(app.RegisterApplicationFactory((*Config)(nil), RouterFactory{}))
}

View File

@ -5,11 +5,11 @@ import (
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
dispatchers "v2ray.com/core/app/dispatcher/impl"
_ "v2ray.com/core/app/dispatcher/impl"
"v2ray.com/core/app/dns"
dnsserver "v2ray.com/core/app/dns/server"
_ "v2ray.com/core/app/dns/server"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/app/proxyman/outbound"
_ "v2ray.com/core/app/proxyman/outbound"
. "v2ray.com/core/app/router"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
@ -31,13 +31,14 @@ func TestSimpleRouter(t *testing.T) {
}
space := app.NewSpace()
space.BindApp(dns.APP_ID, dnsserver.NewCacheServer(space, &dns.Config{}))
space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(space))
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outbound.New())
r := NewRouter(config, space)
space.BindApp(APP_ID, r)
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()
assert.Error(space.Initialize()).IsNil()
r := FromSpace(space)
tag, err := r.TakeDetour(&proxy.SessionInfo{Destination: v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80)})
assert.Error(err).IsNil()
assert.String(tag).Equals("test")

View File

@ -1,23 +1,37 @@
package app
import "v2ray.com/core/common/errors"
type ID int
import (
"github.com/golang/protobuf/proto"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/log"
"v2ray.com/core/common/serial"
)
type Application interface {
}
type ApplicationInitializer func() error
type InitializationCallback func() error
type ApplicationFactory interface {
Create(space Space, config interface{}) (Application, error)
AppId() ID
}
type AppGetter interface {
GetApp(name string) Application
}
var (
applicationFactoryCache = make(map[string]ApplicationFactory)
)
func RegisterApplicationFactory(name string, factory ApplicationFactory) error {
func RegisterApplicationFactory(defaultConfig proto.Message, factory ApplicationFactory) error {
if defaultConfig == nil {
return errors.New("Space: config is nil.")
}
name := serial.GetMessageType(defaultConfig)
if len(name) == 0 {
return errors.New("Space: cannot get config type.")
}
applicationFactoryCache[name] = factory
return nil
}
@ -25,67 +39,67 @@ func RegisterApplicationFactory(name string, factory ApplicationFactory) error {
// 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)
Initialize() error
InitializeApplication(ApplicationInitializer)
HasApp(ID) bool
GetApp(ID) Application
BindApp(ID, Application)
BindFromConfig(name string, config interface{}) error
OnInitialize(InitializationCallback)
}
type spaceImpl struct {
cache map[ID]Application
appInit []ApplicationInitializer
initialized bool
cache map[string]Application
appInit []InitializationCallback
}
func NewSpace() Space {
return &spaceImpl{
cache: make(map[ID]Application),
appInit: make([]ApplicationInitializer, 0, 32),
cache: make(map[string]Application),
appInit: make([]InitializationCallback, 0, 32),
}
}
func (v *spaceImpl) InitializeApplication(f ApplicationInitializer) {
v.appInit = append(v.appInit, f)
func (v *spaceImpl) OnInitialize(f InitializationCallback) {
if v.initialized {
if err := f(); err != nil {
log.Error("Space: error after space initialization: ", err)
}
} else {
v.appInit = append(v.appInit, f)
}
}
func (v *spaceImpl) Initialize() error {
for _, f := range v.appInit {
err := f()
if err != nil {
if err := f(); err != nil {
return err
}
}
v.initialized = true
return nil
}
func (v *spaceImpl) HasApp(id ID) bool {
_, found := v.cache[id]
return found
}
func (v *spaceImpl) GetApp(id ID) Application {
obj, found := v.cache[id]
func (v *spaceImpl) GetApp(configType string) Application {
obj, found := v.cache[configType]
if !found {
return nil
}
return obj
}
func (v *spaceImpl) BindApp(id ID, application Application) {
v.cache[id] = application
}
func (v *spaceImpl) BindFromConfig(name string, config interface{}) error {
factory, found := applicationFactoryCache[name]
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: ", name)
return errors.New("Space: app not registered: ", configName)
}
app, err := factory.Create(v, config)
if err != nil {
return err
}
v.BindApp(factory.AppId(), app)
v.cache[configName] = app
return nil
}
func (v *spaceImpl) AddAppLegacy(name string, application Application) {
v.cache[name] = application
}

View File

@ -1,11 +1,5 @@
package web
import "v2ray.com/core/app"
const (
APP_ID = app.ID(8)
)
type WebServer interface {
Handle()
}

View File

@ -30,13 +30,14 @@ func GetInstance(messageType string) (interface{}, error) {
return reflect.New(mType.Elem()).Interface(), nil
}
func (v *TypedMessage) GetInstance() (interface{}, error) {
func (v *TypedMessage) GetInstance() (proto.Message, error) {
instance, err := GetInstance(v.Type)
if err != nil {
return nil, err
}
if err := proto.Unmarshal(v.Value, instance.(proto.Message)); err != nil {
protoMessage := instance.(proto.Message)
if err := proto.Unmarshal(v.Value, protoMessage); err != nil {
return nil, err
}
return instance, nil
return protoMessage, nil
}

View File

@ -38,11 +38,11 @@ func NewDokodemoDoor(config *Config, space app.Space, meta *proxy.InboundHandler
port: v2net.Port(config.Port),
meta: meta,
}
space.InitializeApplication(func() error {
if !space.HasApp(dispatcher.APP_ID) {
space.OnInitialize(func() error {
d.packetDispatcher = dispatcher.FromSpace(space)
if d.packetDispatcher == nil {
return errors.New("Dokodemo: Dispatcher is not found in the space.")
}
d.packetDispatcher = space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
return nil
})
return d

View File

@ -6,9 +6,9 @@ import (
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
dispatchers "v2ray.com/core/app/dispatcher/impl"
_ "v2ray.com/core/app/dispatcher/impl"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/app/proxyman/outbound"
_ "v2ray.com/core/app/proxyman/outbound"
"v2ray.com/core/common/dice"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
@ -38,8 +38,10 @@ func TestDokodemoTCP(t *testing.T) {
defer tcpServer.Close()
space := app.NewSpace()
space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(space))
ohm := outbound.New()
space.AddApp(new(dispatcher.Config))
space.AddApp(new(proxyman.OutboundConfig))
ohm := proxyman.OutboundHandlerManagerFromSpace(space)
ohm.SetDefaultHandler(
freedom.New(
&freedom.Config{},
@ -50,7 +52,6 @@ func TestDokodemoTCP(t *testing.T) {
Network: v2net.Network_TCP,
},
}))
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, ohm)
data2Send := "Data to be sent to remote."
@ -109,8 +110,10 @@ func TestDokodemoUDP(t *testing.T) {
defer udpServer.Close()
space := app.NewSpace()
space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(space))
ohm := outbound.New()
space.AddApp(new(dispatcher.Config))
space.AddApp(new(proxyman.OutboundConfig))
ohm := proxyman.OutboundHandlerManagerFromSpace(space)
ohm.SetDefaultHandler(
freedom.New(
&freedom.Config{},
@ -120,7 +123,6 @@ func TestDokodemoUDP(t *testing.T) {
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_TCP,
}}))
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, ohm)
data2Send := "Data to be sent to remote."

View File

@ -32,12 +32,12 @@ func New(config *Config, space app.Space, meta *proxy.OutboundHandlerMeta) *Hand
timeout: config.Timeout,
meta: meta,
}
space.InitializeApplication(func() error {
space.OnInitialize(func() error {
if config.DomainStrategy == Config_USE_IP {
if !space.HasApp(dns.APP_ID) {
f.dns = dns.FromSpace(space)
if f.dns == nil {
return errors.New("Freedom: DNS server is not found in the space.")
}
f.dns = space.GetApp(dns.APP_ID).(dns.Server)
}
return nil
})

View File

@ -6,11 +6,11 @@ import (
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
dispatchers "v2ray.com/core/app/dispatcher/impl"
_ "v2ray.com/core/app/dispatcher/impl"
"v2ray.com/core/app/dns"
dnsserver "v2ray.com/core/app/dns/server"
_ "v2ray.com/core/app/dns/server"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/app/proxyman/outbound"
_ "v2ray.com/core/app/proxyman/outbound"
"v2ray.com/core/app/router"
"v2ray.com/core/common/buf"
v2net "v2ray.com/core/common/net"
@ -70,16 +70,14 @@ func TestIPResolution(t *testing.T) {
assert := assert.On(t)
space := app.NewSpace()
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outbound.New())
space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(space))
r := router.NewRouter(&router.Config{}, space)
space.BindApp(router.APP_ID, r)
dnsServer := dnsserver.NewCacheServer(space, &dns.Config{
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{
Hosts: map[string]*v2net.IPOrDomain{
"v2ray.com": v2net.NewIPOrDomain(v2net.LocalHostIP),
},
})
space.BindApp(dns.APP_ID, dnsServer)
})).IsNil()
freedom := New(
&Config{DomainStrategy: Config_USE_IP},

View File

@ -33,12 +33,19 @@ type Server struct {
}
// NewServer creates a new HTTP inbound handler.
func NewServer(config *ServerConfig, packetDispatcher dispatcher.PacketDispatcher, meta *proxy.InboundHandlerMeta) *Server {
return &Server{
packetDispatcher: packetDispatcher,
config: config,
meta: meta,
func NewServer(config *ServerConfig, space app.Space, meta *proxy.InboundHandlerMeta) *Server {
s := &Server{
config: config,
meta: meta,
}
space.OnInitialize(func() error {
s.packetDispatcher = dispatcher.FromSpace(space)
if s.packetDispatcher == nil {
return errors.New("HTTP|Server: Dispatcher not found in space.")
}
return nil
})
return s
}
// Port implements InboundHandler.Port().
@ -291,13 +298,7 @@ func (v *ServerFactory) StreamCapability() v2net.NetworkList {
// Create implements InboundHandlerFactory.Create().
func (v *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
if !space.HasApp(dispatcher.APP_ID) {
return nil, common.ErrBadConfiguration
}
return NewServer(
rawConfig.(*ServerConfig),
space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher),
meta), nil
return NewServer(rawConfig.(*ServerConfig), space, meta), nil
}
func init() {

View File

@ -6,13 +6,8 @@ import (
"strings"
"testing"
testdispatcher "v2ray.com/core/app/dispatcher/testing"
"v2ray.com/core/common/dice"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
. "v2ray.com/core/proxy/http"
"v2ray.com/core/testing/assert"
"v2ray.com/core/transport/internet"
_ "v2ray.com/core/transport/internet/tcp"
)
@ -50,30 +45,3 @@ Accept-Language: de,en;q=0.7,en-us;q=0.3
assert.String(req.Header.Get("Proxy-Connection")).Equals("")
assert.String(req.Header.Get("Proxy-Authenticate")).Equals("")
}
func TestNormalGetRequest(t *testing.T) {
assert := assert.On(t)
testPacketDispatcher := testdispatcher.NewTestPacketDispatcher(nil)
port := v2net.Port(dice.Roll(20000) + 10000)
httpProxy := NewServer(
&ServerConfig{},
testPacketDispatcher,
&proxy.InboundHandlerMeta{
Address: v2net.LocalHostIP,
Port: port,
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_TCP,
}})
defer httpProxy.Close()
err := httpProxy.Start()
assert.Error(err).IsNil()
assert.Port(port).Equals(httpProxy.Port())
httpClient := &http.Client{}
resp, err := httpClient.Get("http://127.0.0.1:" + port.String() + "/")
assert.Error(err).IsNil()
assert.Int(resp.StatusCode).Equals(400)
}

View File

@ -3,7 +3,6 @@ package shadowsocks
import (
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/bufio"
"v2ray.com/core/common/errors"
@ -46,11 +45,11 @@ func NewServer(config *ServerConfig, space app.Space, meta *proxy.InboundHandler
account: account,
}
space.InitializeApplication(func() error {
if !space.HasApp(dispatcher.APP_ID) {
space.OnInitialize(func() error {
s.packetDispatcher = dispatcher.FromSpace(space)
if s.packetDispatcher == nil {
return errors.New("Shadowsocks|Server: Dispatcher is not found in space.")
}
s.packetDispatcher = space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
return nil
})
@ -228,8 +227,5 @@ func (v *ServerFactory) StreamCapability() v2net.NetworkList {
}
func (v *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
if !space.HasApp(dispatcher.APP_ID) {
return nil, common.ErrBadConfiguration
}
return NewServer(rawConfig.(*ServerConfig), space, meta)
}

View File

@ -41,11 +41,11 @@ func NewServer(config *ServerConfig, space app.Space, meta *proxy.InboundHandler
config: config,
meta: meta,
}
space.InitializeApplication(func() error {
if !space.HasApp(dispatcher.APP_ID) {
space.OnInitialize(func() error {
s.packetDispatcher = dispatcher.FromSpace(space)
if s.packetDispatcher == nil {
return errors.New("Socks|Server: Dispatcher is not found in the space.")
}
s.packetDispatcher = space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
return nil
})
return s

View File

@ -261,9 +261,6 @@ func (v *Factory) StreamCapability() v2net.NetworkList {
}
func (v *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
if !space.HasApp(dispatcher.APP_ID) {
return nil, common.ErrBadConfiguration
}
config := rawConfig.(*Config)
allowedClients := vmess.NewTimedUserValidator(protocol.DefaultIDHash)
@ -272,16 +269,23 @@ func (v *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.Inb
}
handler := &VMessInboundHandler{
packetDispatcher: space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher),
clients: allowedClients,
detours: config.Detour,
usersByEmail: NewUserByEmail(config.User, config.GetDefaultValue()),
meta: meta,
clients: allowedClients,
detours: config.Detour,
usersByEmail: NewUserByEmail(config.User, config.GetDefaultValue()),
meta: meta,
}
if space.HasApp(proxyman.APP_ID_INBOUND_MANAGER) {
handler.inboundHandlerManager = space.GetApp(proxyman.APP_ID_INBOUND_MANAGER).(proxyman.InboundHandlerManager)
}
space.OnInitialize(func() error {
handler.packetDispatcher = dispatcher.FromSpace(space)
if handler.packetDispatcher == nil {
return errors.New("VMess|Inbound: Dispatcher is not found in space.")
}
handler.inboundHandlerManager = proxyman.InboundHandlerManagerFromSpace(space)
if handler.inboundHandlerManager == nil {
return errors.New("VMess|Inbound: InboundHandlerManager is not found is space.")
}
return nil
})
return handler, nil
}

View File

@ -39,43 +39,52 @@ func NewPoint(pConfig *Config) (*Point, error) {
space := app.NewSpace()
vpoint.space = space
vpoint.space.BindApp(proxyman.APP_ID_INBOUND_MANAGER, vpoint)
vpoint.space.AddAppLegacy(serial.GetMessageType((*proxyman.InboundConfig)(nil)), vpoint)
outboundManagerConfig := new(proxyman.OutboundConfig)
if err := space.BindFromConfig(serial.GetMessageType(outboundManagerConfig), outboundManagerConfig); err != nil {
return nil, err
outboundHandlerManager := proxyman.OutboundHandlerManagerFromSpace(space)
if outboundHandlerManager == nil {
if err := space.AddApp(new(proxyman.OutboundConfig)); err != nil {
return nil, err
}
outboundHandlerManager = proxyman.OutboundHandlerManagerFromSpace(space)
}
outboundHandlerManager := space.GetApp(proxyman.APP_ID_OUTBOUND_MANAGER).(proxyman.OutboundHandlerManager)
proxyDialer := proxydialer.NewOutboundProxy(space)
proxyDialer := proxydialer.OutboundProxyFromSpace(space)
if proxyDialer == nil {
space.AddApp(new(proxydialer.Config))
proxyDialer = proxydialer.OutboundProxyFromSpace(space)
}
proxyDialer.RegisterDialer()
space.BindApp(proxydialer.APP_ID, proxyDialer)
for _, app := range pConfig.App {
settings, err := app.GetInstance()
if err != nil {
return nil, err
}
if err := space.BindFromConfig(app.Type, settings); err != nil {
if err := space.AddApp(settings); err != nil {
return nil, err
}
}
if !space.HasApp(dns.APP_ID) {
dnsServer := dns.FromSpace(space)
if dnsServer == nil {
dnsConfig := &dns.Config{
NameServers: []*v2net.Endpoint{{
Address: v2net.NewIPOrDomain(v2net.LocalHostDomain),
}},
}
if err := space.BindFromConfig(serial.GetMessageType(dnsConfig), dnsConfig); err != nil {
if err := space.AddApp(dnsConfig); err != nil {
return nil, err
}
}
dispatcherConfig := new(dispatcher.Config)
if err := vpoint.space.BindFromConfig(serial.GetMessageType(dispatcherConfig), dispatcherConfig); err != nil {
return nil, err
disp := dispatcher.FromSpace(space)
if disp == nil {
dispatcherConfig := new(dispatcher.Config)
if err := vpoint.space.AddApp(dispatcherConfig); err != nil {
return nil, err
}
disp = dispatcher.FromSpace(space)
}
vpoint.inboundHandlers = make([]InboundDetourHandler, 0, 8)