mirror of https://github.com/v2ray/v2ray-core
				
				
				
			simplify app design
							parent
							
								
									13e4506781
								
							
						
					
					
						commit
						b11d48d73f
					
				| 
						 | 
				
			
			@ -1,12 +1,4 @@
 | 
			
		|||
package api
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"v2ray.com/core/app"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	APP_ID = app.ID(5)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type ApiServer struct {
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,25 +23,15 @@ type DefaultDispatcher struct {
 | 
			
		|||
 | 
			
		||||
func NewDefaultDispatcher(space app.Space) *DefaultDispatcher {
 | 
			
		||||
	d := &DefaultDispatcher{}
 | 
			
		||||
	space.InitializeApplication(func() error {
 | 
			
		||||
		return d.Initialize(space)
 | 
			
		||||
	})
 | 
			
		||||
	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) {
 | 
			
		||||
	space.OnInitialize(func() error {
 | 
			
		||||
		d.ohm = proxyman.OutboundHandlerManagerFromSpace(space)
 | 
			
		||||
		if d.ohm == nil {
 | 
			
		||||
			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)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		d.router = router.FromSpace(space)
 | 
			
		||||
		return nil
 | 
			
		||||
	})
 | 
			
		||||
	return d
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
 | 
			
		||||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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{}))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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{}))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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{}))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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{}))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										82
									
								
								app/space.go
								
								
								
								
							
							
						
						
									
										82
									
								
								app/space.go
								
								
								
								
							| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,5 @@
 | 
			
		|||
package web
 | 
			
		||||
 | 
			
		||||
import "v2ray.com/core/app"
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	APP_ID = app.ID(8)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type WebServer interface {
 | 
			
		||||
	Handle()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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."
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
	})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
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() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										31
									
								
								v2ray.go
								
								
								
								
							
							
						
						
									
										31
									
								
								v2ray.go
								
								
								
								
							| 
						 | 
				
			
			@ -39,44 +39,53 @@ 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 {
 | 
			
		||||
	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
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	disp := dispatcher.FromSpace(space)
 | 
			
		||||
	if disp == nil {
 | 
			
		||||
		dispatcherConfig := new(dispatcher.Config)
 | 
			
		||||
	if err := vpoint.space.BindFromConfig(serial.GetMessageType(dispatcherConfig), dispatcherConfig); err != nil {
 | 
			
		||||
		if err := vpoint.space.AddApp(dispatcherConfig); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		disp = dispatcher.FromSpace(space)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vpoint.inboundHandlers = make([]InboundDetourHandler, 0, 8)
 | 
			
		||||
	vpoint.taggedInboundHandlers = make(map[string]InboundDetourHandler)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue