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

refactor app.Space

This commit is contained in:
v2ray 2016-01-31 17:01:28 +01:00
parent fcf8a74a3a
commit 2031c13a7f
40 changed files with 487 additions and 480 deletions

View File

@ -1,41 +0,0 @@
package controller
import (
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/internal"
)
// A SpaceController is supposed to be used by a shell to create Spaces. It should not be used
// directly by proxies.
type SpaceController struct {
packetDispatcher internal.PacketDispatcherWithContext
dnsCache internal.DnsCacheWithContext
pubsub internal.PubsubWithContext
inboundHandlerManager internal.InboundHandlerManagerWithContext
}
func New() *SpaceController {
return new(SpaceController)
}
func (this *SpaceController) Bind(object interface{}) {
if packetDispatcher, ok := object.(internal.PacketDispatcherWithContext); ok {
this.packetDispatcher = packetDispatcher
}
if dnsCache, ok := object.(internal.DnsCacheWithContext); ok {
this.dnsCache = dnsCache
}
if pubsub, ok := object.(internal.PubsubWithContext); ok {
this.pubsub = pubsub
}
if inboundHandlerManager, ok := object.(internal.InboundHandlerManagerWithContext); ok {
this.inboundHandlerManager = inboundHandlerManager
}
}
func (this *SpaceController) ForContext(tag string) app.Space {
return internal.NewSpace(tag, this.packetDispatcher, this.dnsCache, this.pubsub, this.inboundHandlerManager)
}

View File

@ -0,0 +1,39 @@
package dispatcher
import (
"github.com/v2ray/v2ray-core/app"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-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(packet v2net.Packet) ray.InboundRay
}
type packetDispatcherWithContext interface {
DispatchToOutbound(context app.Context, packet v2net.Packet) ray.InboundRay
}
type contextedPacketDispatcher struct {
context app.Context
packetDispatcher packetDispatcherWithContext
}
func (this *contextedPacketDispatcher) DispatchToOutbound(packet v2net.Packet) ray.InboundRay {
return this.packetDispatcher.DispatchToOutbound(this.context, packet)
}
func init() {
app.RegisterApp(APP_ID, func(context app.Context, obj interface{}) interface{} {
packetDispatcher := obj.(packetDispatcherWithContext)
return &contextedPacketDispatcher{
context: context,
packetDispatcher: packetDispatcher,
}
})
}

View File

@ -1,11 +0,0 @@
package app
import (
"net"
)
// A DnsCache is an internal cache of DNS resolutions.
type DnsCache interface {
Get(domain string) net.IP
Add(domain string, ip net.IP)
}

View File

@ -2,61 +2,44 @@ package dns
import (
"net"
"time"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/common/collect"
"github.com/v2ray/v2ray-core/common/serial"
)
type entry struct {
domain string
ip net.IP
validUntil time.Time
const (
APP_ID = app.ID(2)
)
// A DnsCache is an internal cache of DNS resolutions.
type DnsCache interface {
Get(domain string) net.IP
Add(domain string, ip net.IP)
}
func newEntry(domain string, ip net.IP) *entry {
this := &entry{
domain: domain,
ip: ip,
}
this.Extend()
return this
type dnsCacheWithContext interface {
Get(context app.Context, domain string) net.IP
Add(contaxt app.Context, domain string, ip net.IP)
}
func (this *entry) IsValid() bool {
return this.validUntil.After(time.Now())
type contextedDnsCache struct {
context app.Context
dnsCache dnsCacheWithContext
}
func (this *entry) Extend() {
this.validUntil = time.Now().Add(time.Hour)
func (this *contextedDnsCache) Get(domain string) net.IP {
return this.dnsCache.Get(this.context, domain)
}
type DnsCache struct {
cache *collect.ValidityMap
config *CacheConfig
func (this *contextedDnsCache) Add(domain string, ip net.IP) {
this.dnsCache.Add(this.context, domain, ip)
}
func NewCache(config *CacheConfig) *DnsCache {
cache := &DnsCache{
cache: collect.NewValidityMap(3600),
config: config,
func init() {
app.RegisterApp(APP_ID, func(context app.Context, obj interface{}) interface{} {
dcContext := obj.(dnsCacheWithContext)
return &contextedDnsCache{
context: context,
dnsCache: dcContext,
}
return cache
}
func (this *DnsCache) Add(context app.Context, domain string, ip net.IP) {
callerTag := context.CallerTag()
if !this.config.IsTrustedSource(serial.StringLiteral(callerTag)) {
return
}
this.cache.Set(serial.StringLiteral(domain), newEntry(domain, ip))
}
func (this *DnsCache) Get(context app.Context, domain string) net.IP {
if value := this.cache.Get(serial.StringLiteral(domain)); value != nil {
return value.(*entry).ip
}
return nil
})
}

View File

@ -1,4 +1,4 @@
package dns
package internal
import (
"github.com/v2ray/v2ray-core/common/serial"

View File

@ -1,6 +1,6 @@
// +build json
package dns
package internal
import (
"encoding/json"

62
app/dns/internal/dns.go Normal file
View File

@ -0,0 +1,62 @@
package internal
import (
"net"
"time"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/common/collect"
"github.com/v2ray/v2ray-core/common/serial"
)
type entry struct {
domain string
ip net.IP
validUntil time.Time
}
func newEntry(domain string, ip net.IP) *entry {
this := &entry{
domain: domain,
ip: ip,
}
this.Extend()
return this
}
func (this *entry) IsValid() bool {
return this.validUntil.After(time.Now())
}
func (this *entry) Extend() {
this.validUntil = time.Now().Add(time.Hour)
}
type DnsCache struct {
cache *collect.ValidityMap
config *CacheConfig
}
func NewCache(config *CacheConfig) *DnsCache {
cache := &DnsCache{
cache: collect.NewValidityMap(3600),
config: config,
}
return cache
}
func (this *DnsCache) Add(context app.Context, domain string, ip net.IP) {
callerTag := context.CallerTag()
if !this.config.IsTrustedSource(serial.StringLiteral(callerTag)) {
return
}
this.cache.Set(serial.StringLiteral(domain), newEntry(domain, ip))
}
func (this *DnsCache) Get(context app.Context, domain string) net.IP {
if value := this.cache.Get(serial.StringLiteral(domain)); value != nil {
return value.(*entry).ip
}
return nil
}

View File

@ -1,10 +1,10 @@
package dns_test
package internal_test
import (
"net"
"testing"
"github.com/v2ray/v2ray-core/app/dns"
. "github.com/v2ray/v2ray-core/app/dns/internal"
apptesting "github.com/v2ray/v2ray-core/app/testing"
netassert "github.com/v2ray/v2ray-core/common/net/testing/assert"
"github.com/v2ray/v2ray-core/common/serial"
@ -15,7 +15,7 @@ func TestDnsAdd(t *testing.T) {
v2testing.Current(t)
domain := "v2ray.com"
cache := dns.NewCache(&dns.CacheConfig{
cache := NewCache(&CacheConfig{
TrustedTags: map[serial.StringLiteral]bool{
serial.StringLiteral("testtag"): true,
},

View File

@ -1,9 +0,0 @@
package app
import (
"github.com/v2ray/v2ray-core/proxy"
)
type InboundHandlerManager interface {
GetHandler(tag string) (proxy.InboundHandler, int)
}

View File

@ -1,9 +0,0 @@
package internal
type contextImpl struct {
callerTag string
}
func (this *contextImpl) CallerTag() string {
return this.callerTag
}

View File

@ -1,25 +0,0 @@
package internal
import (
"net"
"github.com/v2ray/v2ray-core/app"
)
type DnsCacheWithContext interface {
Get(context app.Context, domain string) net.IP
Add(contaxt app.Context, domain string, ip net.IP)
}
type contextedDnsCache struct {
context app.Context
dnsCache DnsCacheWithContext
}
func (this *contextedDnsCache) Get(domain string) net.IP {
return this.dnsCache.Get(this.context, domain)
}
func (this *contextedDnsCache) Add(domain string, ip net.IP) {
this.dnsCache.Add(this.context, domain, ip)
}

View File

@ -1,19 +0,0 @@
package internal
import (
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/proxy"
)
type InboundHandlerManagerWithContext interface {
GetHandler(context app.Context, tag string) (proxy.InboundHandler, int)
}
type inboundHandlerManagerWithContext struct {
context app.Context
manager InboundHandlerManagerWithContext
}
func (this *inboundHandlerManagerWithContext) GetHandler(tag string) (proxy.InboundHandler, int) {
return this.manager.GetHandler(this.context, tag)
}

View File

@ -1,20 +0,0 @@
package internal
import (
"github.com/v2ray/v2ray-core/app"
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/transport/ray"
)
type PacketDispatcherWithContext interface {
DispatchToOutbound(context app.Context, packet v2net.Packet) ray.InboundRay
}
type contextedPacketDispatcher struct {
context app.Context
packetDispatcher PacketDispatcherWithContext
}
func (this *contextedPacketDispatcher) DispatchToOutbound(packet v2net.Packet) ray.InboundRay {
return this.packetDispatcher.DispatchToOutbound(this.context, packet)
}

View File

@ -1,23 +0,0 @@
package internal
import (
"github.com/v2ray/v2ray-core/app"
)
type PubsubWithContext interface {
Publish(context app.Context, topic string, message app.PubsubMessage)
Subscribe(context app.Context, topic string, handler app.TopicHandler)
}
type contextedPubsub struct {
context app.Context
pubsub PubsubWithContext
}
func (this *contextedPubsub) Publish(topic string, message app.PubsubMessage) {
this.pubsub.Publish(this.context, topic, message)
}
func (this *contextedPubsub) Subscribe(topic string, handler app.TopicHandler) {
this.pubsub.Subscribe(this.context, topic, handler)
}

View File

@ -1,75 +0,0 @@
package internal
import (
"github.com/v2ray/v2ray-core/app"
)
type Space struct {
packetDispatcher PacketDispatcherWithContext
dnsCache DnsCacheWithContext
pubsub PubsubWithContext
inboundHandlerManager InboundHandlerManagerWithContext
tag string
}
func NewSpace(tag string, packetDispatcher PacketDispatcherWithContext, dnsCache DnsCacheWithContext, pubsub PubsubWithContext, inboundHandlerManager InboundHandlerManagerWithContext) *Space {
return &Space{
tag: tag,
packetDispatcher: packetDispatcher,
dnsCache: dnsCache,
pubsub: pubsub,
inboundHandlerManager: inboundHandlerManager,
}
}
func (this *Space) HasPacketDispatcher() bool {
return this.packetDispatcher != nil
}
func (this *Space) PacketDispatcher() app.PacketDispatcher {
return &contextedPacketDispatcher{
packetDispatcher: this.packetDispatcher,
context: &contextImpl{
callerTag: this.tag,
},
}
}
func (this *Space) HasDnsCache() bool {
return this.dnsCache != nil
}
func (this *Space) DnsCache() app.DnsCache {
return &contextedDnsCache{
dnsCache: this.dnsCache,
context: &contextImpl{
callerTag: this.tag,
},
}
}
func (this *Space) HasPubsub() bool {
return this.pubsub != nil
}
func (this *Space) Pubsub() app.Pubsub {
return &contextedPubsub{
pubsub: this.pubsub,
context: &contextImpl{
callerTag: this.tag,
},
}
}
func (this *Space) HasInboundHandlerManager() bool {
return this.inboundHandlerManager != nil
}
func (this *Space) InboundHandlerManager() app.InboundHandlerManager {
return &inboundHandlerManagerWithContext{
manager: this.inboundHandlerManager,
context: &contextImpl{
callerTag: this.tag,
},
}
}

View File

@ -1,11 +0,0 @@
package app
import (
v2net "github.com/v2ray/v2ray-core/common/net"
"github.com/v2ray/v2ray-core/transport/ray"
)
// PacketDispatcher dispatch a packet and possibly further network payload to its destination.
type PacketDispatcher interface {
DispatchToOutbound(packet v2net.Packet) ray.InboundRay
}

37
app/proxyman/proxyman.go Normal file
View File

@ -0,0 +1,37 @@
package proxyman
import (
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/proxy"
)
const (
APP_ID_INBOUND_MANAGER = app.ID(4)
)
type InboundHandlerManager interface {
GetHandler(tag string) (proxy.InboundHandler, int)
}
type inboundHandlerManagerWithContext interface {
GetHandler(context app.Context, tag string) (proxy.InboundHandler, int)
}
type inboundHandlerManagerWithContextImpl struct {
context app.Context
manager inboundHandlerManagerWithContext
}
func (this *inboundHandlerManagerWithContextImpl) GetHandler(tag string) (proxy.InboundHandler, int) {
return this.manager.GetHandler(this.context, tag)
}
func init() {
app.RegisterApp(APP_ID_INBOUND_MANAGER, func(context app.Context, obj interface{}) interface{} {
manager := obj.(inboundHandlerManagerWithContext)
return &inboundHandlerManagerWithContextImpl{
context: context,
manager: manager,
}
})
}

View File

@ -1,9 +0,0 @@
package app
type PubsubMessage []byte
type TopicHandler func(PubsubMessage)
type Pubsub interface {
Publish(topic string, message PubsubMessage)
Subscribe(topic string, handler TopicHandler)
}

View File

@ -0,0 +1,64 @@
package internal
import (
"sync"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/pubsub"
)
type TopicHandlerList struct {
sync.RWMutex
handlers []pubsub.TopicHandler
}
func NewTopicHandlerList(handlers ...pubsub.TopicHandler) *TopicHandlerList {
return &TopicHandlerList{
handlers: handlers,
}
}
func (this *TopicHandlerList) Add(handler pubsub.TopicHandler) {
this.Lock()
this.handlers = append(this.handlers, handler)
this.Unlock()
}
func (this *TopicHandlerList) Dispatch(message pubsub.PubsubMessage) {
this.RLock()
for _, handler := range this.handlers {
go handler(message)
}
this.RUnlock()
}
type Pubsub struct {
topics map[string]*TopicHandlerList
sync.RWMutex
}
func New() *Pubsub {
return &Pubsub{
topics: make(map[string]*TopicHandlerList),
}
}
func (this *Pubsub) Publish(context app.Context, topic string, message pubsub.PubsubMessage) {
this.RLock()
list, found := this.topics[topic]
this.RUnlock()
if found {
list.Dispatch(message)
}
}
func (this *Pubsub) Subscribe(context app.Context, topic string, handler pubsub.TopicHandler) {
this.Lock()
defer this.Unlock()
if list, found := this.topics[topic]; found {
list.Add(handler)
} else {
this.topics[topic] = NewTopicHandlerList(handler)
}
}

View File

@ -1,11 +1,11 @@
package pubsub_test
package internal_test
import (
"testing"
"time"
"github.com/v2ray/v2ray-core/app"
. "github.com/v2ray/v2ray-core/app/pubsub"
"github.com/v2ray/v2ray-core/app/pubsub"
. "github.com/v2ray/v2ray-core/app/pubsub/internal"
apptesting "github.com/v2ray/v2ray-core/app/testing"
v2testing "github.com/v2ray/v2ray-core/testing"
"github.com/v2ray/v2ray-core/testing/assert"
@ -14,19 +14,19 @@ import (
func TestPubsub(t *testing.T) {
v2testing.Current(t)
messages := make(map[string]app.PubsubMessage)
messages := make(map[string]pubsub.PubsubMessage)
pubsub := New()
pubsub.Subscribe(&apptesting.Context{}, "t1", func(message app.PubsubMessage) {
ps := New()
ps.Subscribe(&apptesting.Context{}, "t1", func(message pubsub.PubsubMessage) {
messages["t1"] = message
})
pubsub.Subscribe(&apptesting.Context{}, "t2", func(message app.PubsubMessage) {
ps.Subscribe(&apptesting.Context{}, "t2", func(message pubsub.PubsubMessage) {
messages["t2"] = message
})
message := app.PubsubMessage([]byte("This is a pubsub message."))
pubsub.Publish(&apptesting.Context{}, "t2", message)
message := pubsub.PubsubMessage([]byte("This is a pubsub message."))
ps.Publish(&apptesting.Context{}, "t2", message)
<-time.Tick(time.Second)
_, found := messages["t1"]

View File

@ -1,64 +1,45 @@
package pubsub
import (
"sync"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/internal"
)
type TopicHandlerList struct {
sync.RWMutex
handlers []app.TopicHandler
const (
APP_ID = app.ID(3)
)
type PubsubMessage []byte
type TopicHandler func(PubsubMessage)
type Pubsub interface {
Publish(topic string, message PubsubMessage)
Subscribe(topic string, handler TopicHandler)
}
func NewTopicHandlerList(handlers ...app.TopicHandler) *TopicHandlerList {
return &TopicHandlerList{
handlers: handlers,
}
type pubsubWithContext interface {
Publish(context app.Context, topic string, message PubsubMessage)
Subscribe(context app.Context, topic string, handler TopicHandler)
}
func (this *TopicHandlerList) Add(handler app.TopicHandler) {
this.Lock()
this.handlers = append(this.handlers, handler)
this.Unlock()
type contextedPubsub struct {
context app.Context
pubsub pubsubWithContext
}
func (this *TopicHandlerList) Dispatch(message app.PubsubMessage) {
this.RLock()
for _, handler := range this.handlers {
go handler(message)
}
this.RUnlock()
func (this *contextedPubsub) Publish(topic string, message PubsubMessage) {
this.pubsub.Publish(this.context, topic, message)
}
type Pubsub struct {
topics map[string]*TopicHandlerList
sync.RWMutex
func (this *contextedPubsub) Subscribe(topic string, handler TopicHandler) {
this.pubsub.Subscribe(this.context, topic, handler)
}
func New() internal.PubsubWithContext {
return &Pubsub{
topics: make(map[string]*TopicHandlerList),
}
}
func (this *Pubsub) Publish(context app.Context, topic string, message app.PubsubMessage) {
this.RLock()
list, found := this.topics[topic]
this.RUnlock()
if found {
list.Dispatch(message)
}
}
func (this *Pubsub) Subscribe(context app.Context, topic string, handler app.TopicHandler) {
this.Lock()
defer this.Unlock()
if list, found := this.topics[topic]; found {
list.Add(handler)
} else {
this.topics[topic] = NewTopicHandlerList(handler)
func init() {
app.RegisterApp(APP_ID, func(context app.Context, obj interface{}) interface{} {
pubsub := obj.(pubsubWithContext)
return &contextedPubsub{
context: context,
pubsub: pubsub,
}
})
}

View File

@ -1,5 +1,14 @@
package app
type ID int
const (
PACKET_DISPATCHER = ID(1)
DNS_CACHE = ID(2)
PUBSUB = ID(3)
INBOUND_HANDLER_MANAGER = ID(4)
)
// Context of a function call from proxy to app.
type Context interface {
CallerTag() string
@ -8,15 +17,80 @@ type Context interface {
// 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 {
HasPacketDispatcher() bool
PacketDispatcher() PacketDispatcher
HasDnsCache() bool
DnsCache() DnsCache
HasPubsub() bool
Pubsub() Pubsub
HasInboundHandlerManager() bool
InboundHandlerManager() InboundHandlerManager
HasApp(ID) bool
GetApp(ID) interface{}
}
type ForContextCreator func(Context, interface{}) interface{}
var (
metadataCache = make(map[ID]ForContextCreator)
)
func RegisterApp(id ID, creator ForContextCreator) {
// TODO: check id
metadataCache[id] = creator
}
type contextImpl struct {
callerTag string
}
func (this *contextImpl) CallerTag() string {
return this.callerTag
}
type spaceImpl struct {
cache map[ID]interface{}
tag string
}
func newSpaceImpl(tag string, cache map[ID]interface{}) *spaceImpl {
space := &spaceImpl{
tag: tag,
cache: make(map[ID]interface{}),
}
context := &contextImpl{
callerTag: tag,
}
for id, object := range cache {
creator, found := metadataCache[id]
if found {
space.cache[id] = creator(context, object)
}
}
return space
}
func (this *spaceImpl) HasApp(id ID) bool {
_, found := this.cache[id]
return found
}
func (this *spaceImpl) GetApp(id ID) interface{} {
obj, found := this.cache[id]
if !found {
return nil
}
return obj
}
// A SpaceController is supposed to be used by a shell to create Spaces. It should not be used
// directly by proxies.
type SpaceController struct {
objectCache map[ID]interface{}
}
func NewController() *SpaceController {
return &SpaceController{
objectCache: make(map[ID]interface{}),
}
}
func (this *SpaceController) Bind(id ID, object interface{}) {
this.objectCache[id] = object
}
func (this *SpaceController) ForContext(tag string) Space {
return newSpaceImpl(tag, this.objectCache)
}

View File

@ -4,7 +4,7 @@ import (
"io"
"sync"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/common/alloc"
v2io "github.com/v2ray/v2ray-core/common/io"
"github.com/v2ray/v2ray-core/common/log"
@ -20,16 +20,16 @@ type DokodemoDoor struct {
accepting bool
address v2net.Address
port v2net.Port
space app.Space
packetDispatcher dispatcher.PacketDispatcher
tcpListener *hub.TCPHub
udpHub *hub.UDPHub
listeningPort v2net.Port
}
func NewDokodemoDoor(space app.Space, config *Config) *DokodemoDoor {
func NewDokodemoDoor(config *Config, packetDispatcher dispatcher.PacketDispatcher) *DokodemoDoor {
return &DokodemoDoor{
config: config,
space: space,
packetDispatcher: packetDispatcher,
address: config.Address,
port: config.Port,
}
@ -95,7 +95,7 @@ func (this *DokodemoDoor) ListenUDP(port v2net.Port) error {
func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, dest v2net.Destination) {
packet := v2net.NewPacket(v2net.UDPDestination(this.address, this.port), payload, false)
ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
ray := this.packetDispatcher.DispatchToOutbound(packet)
close(ray.InboundInput())
for resp := range ray.InboundOutput() {
@ -127,7 +127,7 @@ func (this *DokodemoDoor) HandleTCPConnection(conn *hub.TCPConn) {
defer conn.Close()
packet := v2net.NewPacket(v2net.TCPDestination(this.address, this.port), nil, true)
ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
ray := this.packetDispatcher.DispatchToOutbound(packet)
var inputFinish, outputFinish sync.Mutex
inputFinish.Lock()

View File

@ -2,6 +2,7 @@ package dokodemo
import (
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/proxy"
"github.com/v2ray/v2ray-core/proxy/internal"
)
@ -10,6 +11,11 @@ func init() {
internal.MustRegisterInboundHandlerCreator("dokodemo-door",
func(space app.Space, rawConfig interface{}) (proxy.InboundHandler, error) {
config := rawConfig.(*Config)
return NewDokodemoDoor(space, config), nil
if !space.HasApp(dispatcher.APP_ID) {
return nil, internal.ErrorBadConfiguration
}
return NewDokodemoDoor(
config,
space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)), nil
})
}

View File

@ -4,7 +4,6 @@ import (
"net"
"sync"
"github.com/v2ray/v2ray-core/app"
v2io "github.com/v2ray/v2ray-core/common/io"
"github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net"
@ -14,7 +13,6 @@ import (
)
type FreedomConnection struct {
space app.Space
}
func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error {
@ -77,19 +75,6 @@ func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.Outbou
v2io.RawReaderToChan(output, conn)
}()
if this.space.HasDnsCache() {
if firstPacket.Destination().Address().IsDomain() {
domain := firstPacket.Destination().Address().Domain()
addr := conn.RemoteAddr()
switch typedAddr := addr.(type) {
case *net.TCPAddr:
this.space.DnsCache().Add(domain, typedAddr.IP)
case *net.UDPAddr:
this.space.DnsCache().Add(domain, typedAddr.IP)
}
}
}
writeMutex.Lock()
if tcpConn, ok := conn.(*net.TCPConn); ok {
tcpConn.CloseWrite()

View File

@ -9,6 +9,7 @@ import (
"golang.org/x/net/proxy"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/common/alloc"
v2io "github.com/v2ray/v2ray-core/common/io"
v2net "github.com/v2ray/v2ray-core/common/net"
@ -50,7 +51,7 @@ func TestUDPSend(t *testing.T) {
protocol, err := proxytesting.RegisterInboundConnectionHandlerCreator("mock_ich",
func(space app.Space, config interface{}) (v2proxy.InboundHandler, error) {
ich.Space = space
ich.PacketDispatcher = space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
return ich, nil
})
assert.Error(err).IsNil()

View File

@ -9,6 +9,6 @@ import (
func init() {
internal.MustRegisterOutboundHandlerCreator("freedom",
func(space app.Space, config interface{}) (proxy.OutboundHandler, error) {
return &FreedomConnection{space: space}, nil
return &FreedomConnection{}, nil
})
}

View File

@ -9,7 +9,7 @@ import (
"strings"
"sync"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/common/alloc"
v2io "github.com/v2ray/v2ray-core/common/io"
"github.com/v2ray/v2ray-core/common/log"
@ -23,15 +23,15 @@ import (
type HttpProxyServer struct {
sync.Mutex
accepting bool
space app.Space
packetDispatcher dispatcher.PacketDispatcher
config *Config
tcpListener *hub.TCPHub
listeningPort v2net.Port
}
func NewHttpProxyServer(space app.Space, config *Config) *HttpProxyServer {
func NewHttpProxyServer(config *Config, packetDispatcher dispatcher.PacketDispatcher) *HttpProxyServer {
return &HttpProxyServer{
space: space,
packetDispatcher: packetDispatcher,
config: config,
}
}
@ -144,7 +144,7 @@ func (this *HttpProxyServer) handleConnect(request *http.Request, destination v2
buffer.Release()
packet := v2net.NewPacket(destination, nil, true)
ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
ray := this.packetDispatcher.DispatchToOutbound(packet)
this.transport(reader, writer, ray)
}
@ -220,7 +220,7 @@ func (this *HttpProxyServer) handlePlainHTTP(request *http.Request, dest v2net.D
log.Debug("Request to remote:\n", serial.BytesLiteral(requestBuffer.Value))
packet := v2net.NewPacket(dest, requestBuffer, true)
ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
ray := this.packetDispatcher.DispatchToOutbound(packet)
defer close(ray.InboundInput())
var wg sync.WaitGroup

View File

@ -2,6 +2,7 @@ package http
import (
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/proxy"
"github.com/v2ray/v2ray-core/proxy/internal"
)
@ -9,6 +10,11 @@ import (
func init() {
internal.MustRegisterInboundHandlerCreator("http",
func(space app.Space, rawConfig interface{}) (proxy.InboundHandler, error) {
return NewHttpProxyServer(space, rawConfig.(*Config)), nil
if !space.HasApp(dispatcher.APP_ID) {
return nil, internal.ErrorBadConfiguration
}
return NewHttpProxyServer(
rawConfig.(*Config),
space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)), nil
})
}

View File

@ -8,6 +8,7 @@ import (
"sync"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/common/alloc"
v2io "github.com/v2ray/v2ray-core/common/io"
"github.com/v2ray/v2ray-core/common/log"
@ -19,7 +20,7 @@ import (
)
type Shadowsocks struct {
space app.Space
packetDispatcher dispatcher.PacketDispatcher
config *Config
port v2net.Port
accepting bool
@ -27,6 +28,13 @@ type Shadowsocks struct {
udpHub *hub.UDPHub
}
func NewShadowsocks(config *Config, packetDispatcher dispatcher.PacketDispatcher) *Shadowsocks {
return &Shadowsocks{
config: config,
packetDispatcher: packetDispatcher,
}
}
func (this *Shadowsocks) Port() v2net.Port {
return this.port
}
@ -99,7 +107,7 @@ func (this *Shadowsocks) handlerUDPPayload(payload *alloc.Buffer, source v2net.D
log.Info("Shadowsocks: Tunnelling request to ", dest)
packet := v2net.NewPacket(dest, request.UDPPayload, false)
ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
ray := this.packetDispatcher.DispatchToOutbound(packet)
close(ray.InboundInput())
for respChunk := range ray.InboundOutput() {
@ -174,7 +182,7 @@ func (this *Shadowsocks) handleConnection(conn *hub.TCPConn) {
log.Info("Shadowsocks: Tunnelling request to ", dest)
packet := v2net.NewPacket(dest, nil, true)
ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
ray := this.packetDispatcher.DispatchToOutbound(packet)
var writeFinish sync.Mutex
writeFinish.Lock()
@ -215,10 +223,11 @@ func (this *Shadowsocks) handleConnection(conn *hub.TCPConn) {
func init() {
internal.MustRegisterInboundHandlerCreator("shadowsocks",
func(space app.Space, rawConfig interface{}) (proxy.InboundHandler, error) {
config := rawConfig.(*Config)
return &Shadowsocks{
space: space,
config: config,
}, nil
if !space.HasApp(dispatcher.APP_ID) {
return nil, internal.ErrorBadConfiguration
}
return NewShadowsocks(
rawConfig.(*Config),
space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)), nil
})
}

View File

@ -7,7 +7,7 @@ import (
"sync"
"time"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/common/alloc"
v2io "github.com/v2ray/v2ray-core/common/io"
"github.com/v2ray/v2ray-core/common/log"
@ -27,7 +27,7 @@ type SocksServer struct {
tcpMutex sync.RWMutex
udpMutex sync.RWMutex
accepting bool
space app.Space
packetDispatcher dispatcher.PacketDispatcher
config *Config
tcpListener *hub.TCPHub
udpConn *net.UDPConn
@ -35,10 +35,10 @@ type SocksServer struct {
listeningPort v2net.Port
}
func NewSocksServer(space app.Space, config *Config) *SocksServer {
func NewSocksServer(config *Config, packetDispatcher dispatcher.PacketDispatcher) *SocksServer {
return &SocksServer{
space: space,
config: config,
packetDispatcher: packetDispatcher,
}
}
@ -262,7 +262,7 @@ func (this *SocksServer) handleSocks4(reader io.Reader, writer io.Writer, auth p
}
func (this *SocksServer) transport(reader io.Reader, writer io.Writer, firstPacket v2net.Packet) {
ray := this.space.PacketDispatcher().DispatchToOutbound(firstPacket)
ray := this.packetDispatcher.DispatchToOutbound(firstPacket)
input := ray.InboundInput()
output := ray.InboundOutput()

View File

@ -2,6 +2,7 @@ package socks
import (
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/proxy"
"github.com/v2ray/v2ray-core/proxy/internal"
)
@ -9,6 +10,11 @@ import (
func init() {
internal.MustRegisterInboundHandlerCreator("socks",
func(space app.Space, rawConfig interface{}) (proxy.InboundHandler, error) {
return NewSocksServer(space, rawConfig.(*Config)), nil
if !space.HasApp(dispatcher.APP_ID) {
return nil, internal.ErrorBadConfiguration
}
return NewSocksServer(
rawConfig.(*Config),
space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)), nil
})
}

View File

@ -69,7 +69,7 @@ func (this *SocksServer) AcceptPackets() error {
}
func (this *SocksServer) handlePacket(packet v2net.Packet, clientAddr *net.UDPAddr, targetAddr v2net.Address, port v2net.Port) {
ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
ray := this.packetDispatcher.DispatchToOutbound(packet)
close(ray.InboundInput())
for data := range ray.InboundOutput() {

View File

@ -4,14 +4,14 @@ import (
"io"
"sync"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
v2io "github.com/v2ray/v2ray-core/common/io"
v2net "github.com/v2ray/v2ray-core/common/net"
)
type InboundConnectionHandler struct {
port v2net.Port
Space app.Space
PacketDispatcher dispatcher.PacketDispatcher
ConnInput io.Reader
ConnOutput io.Writer
}
@ -30,7 +30,7 @@ func (this *InboundConnectionHandler) Close() {
}
func (this *InboundConnectionHandler) Communicate(packet v2net.Packet) error {
ray := this.Space.PacketDispatcher().DispatchToOutbound(packet)
ray := this.PacketDispatcher.DispatchToOutbound(packet)
input := ray.InboundInput()
output := ray.InboundOutput()

View File

@ -17,9 +17,8 @@ func (this *VMessInboundHandler) generateCommand(buffer *alloc.Buffer) {
if this.features != nil && this.features.Detour != nil {
tag := this.features.Detour.ToTag
if this.space.HasInboundHandlerManager() {
handlerManager := this.space.InboundHandlerManager()
handler, availableMin := handlerManager.GetHandler(tag)
if this.inboundHandlerManager != nil {
handler, availableMin := this.inboundHandlerManager.GetHandler(tag)
inboundHandler, ok := handler.(*VMessInboundHandler)
if ok {
if availableMin > 255 {

View File

@ -6,6 +6,8 @@ import (
"sync"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/app/proxyman"
"github.com/v2ray/v2ray-core/common/alloc"
v2crypto "github.com/v2ray/v2ray-core/common/crypto"
v2io "github.com/v2ray/v2ray-core/common/io"
@ -22,7 +24,8 @@ import (
// Inbound connection handler that handles messages in VMess format.
type VMessInboundHandler struct {
sync.Mutex
space app.Space
packetDispatcher dispatcher.PacketDispatcher
inboundHandlerManager proxyman.InboundHandlerManager
clients protocol.UserSet
user *vmess.User
accepting bool
@ -86,7 +89,7 @@ func (this *VMessInboundHandler) HandleConnection(connection *hub.TCPConn) {
log.Access(connection.RemoteAddr(), request.Address, log.AccessAccepted, serial.StringLiteral(""))
log.Debug("VMessIn: Received request for ", request.Address)
ray := this.space.PacketDispatcher().DispatchToOutbound(v2net.NewPacket(request.Destination(), nil, true))
ray := this.packetDispatcher.DispatchToOutbound(v2net.NewPacket(request.Destination(), nil, true))
input := ray.InboundInput()
output := ray.InboundOutput()
var readFinish, writeFinish sync.Mutex
@ -148,6 +151,9 @@ func handleOutput(request *protocol.VMessRequest, writer io.Writer, output <-cha
func init() {
internal.MustRegisterInboundHandlerCreator("vmess",
func(space app.Space, rawConfig interface{}) (proxy.InboundHandler, error) {
if !space.HasApp(dispatcher.APP_ID) {
return nil, internal.ErrorBadConfiguration
}
config := rawConfig.(*Config)
allowedClients := protocol.NewTimedUserSet()
@ -155,11 +161,17 @@ func init() {
allowedClients.AddUser(user)
}
return &VMessInboundHandler{
space: space,
handler := &VMessInboundHandler{
packetDispatcher: space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher),
clients: allowedClients,
features: config.Features,
user: config.AllowedUsers[0],
}, nil
}
if space.HasApp(proxyman.APP_ID_INBOUND_MANAGER) {
handler.inboundHandlerManager = space.GetApp(proxyman.APP_ID_INBOUND_MANAGER).(proxyman.InboundHandlerManager)
}
return handler, nil
})
}

View File

@ -22,7 +22,6 @@ import (
type VMessOutboundHandler struct {
receiverManager *ReceiverManager
space app.Space
}
func (this *VMessOutboundHandler) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error {
@ -196,7 +195,6 @@ func init() {
func(space app.Space, rawConfig interface{}) (proxy.OutboundHandler, error) {
vOutConfig := rawConfig.(*Config)
return &VMessOutboundHandler{
space: space,
receiverManager: NewReceiverManager(vOutConfig.Receivers),
}, nil
})

View File

@ -5,6 +5,7 @@ import (
"testing"
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/dispatcher"
v2net "github.com/v2ray/v2ray-core/common/net"
v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
"github.com/v2ray/v2ray-core/common/uuid"
@ -38,7 +39,7 @@ func TestVMessInAndOut(t *testing.T) {
}
protocol, err := proxytesting.RegisterInboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (proxy.InboundHandler, error) {
ich.Space = space
ich.PacketDispatcher = space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
return ich, nil
})
assert.Error(err).IsNil()

View File

@ -1,7 +1,6 @@
package point
import (
"github.com/v2ray/v2ray-core/app/dns"
"github.com/v2ray/v2ray-core/app/router"
"github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net"
@ -18,11 +17,6 @@ type LogConfig struct {
LogLevel log.LogLevel
}
type DnsConfig struct {
Enabled bool
Settings *dns.CacheConfig
}
const (
AllocationStrategyAlways = "always"
AllocationStrategyRandom = "random"

View File

@ -6,7 +6,8 @@ package point
import (
"github.com/v2ray/v2ray-core/app"
"github.com/v2ray/v2ray-core/app/controller"
"github.com/v2ray/v2ray-core/app/dispatcher"
"github.com/v2ray/v2ray-core/app/proxyman"
"github.com/v2ray/v2ray-core/app/router"
"github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net"
@ -25,7 +26,7 @@ type Point struct {
taggedIdh map[string]InboundDetourHandler
odh map[string]proxy.OutboundHandler
router router.Router
space *controller.SpaceController
space *app.SpaceController
}
// NewPoint returns a new Point server based on given configuration.
@ -53,8 +54,9 @@ func NewPoint(pConfig *Config) (*Point, error) {
log.SetLogLevel(logConfig.LogLevel)
}
vpoint.space = controller.New()
vpoint.space.Bind(vpoint)
vpoint.space = app.NewController()
vpoint.space.Bind(dispatcher.APP_ID, vpoint)
vpoint.space.Bind(proxyman.APP_ID_INBOUND_MANAGER, vpoint)
ichConfig := pConfig.InboundConfig.Settings
ich, err := proxyrepo.CreateInboundHandler(pConfig.InboundConfig.Protocol, vpoint.space.ForContext("vpoint-default-inbound"), ichConfig)