From 46ab9c45ccc34fe6f8d4d6859ce6f0838577292c Mon Sep 17 00:00:00 2001 From: v2ray Date: Thu, 10 Dec 2015 23:55:39 +0100 Subject: [PATCH] space with context --- app/dns.go | 18 ++++++++++++++ app/dns/dns.go | 9 ++++--- app/dns/dns_test.go | 7 +++--- app/packet_dispatcher.go | 13 ++++++++++ app/space.go | 54 ++++++++++++++++++++++++++++++++++------ app/testing/space.go | 9 +++++++ shell/point/point.go | 14 +++++------ 7 files changed, 103 insertions(+), 21 deletions(-) create mode 100644 app/testing/space.go diff --git a/app/dns.go b/app/dns.go index 4bba0d1c0d..e0903e2a7d 100644 --- a/app/dns.go +++ b/app/dns.go @@ -8,3 +8,21 @@ type DnsCache interface { Get(domain string) net.IP Add(domain string, ip net.IP) } + +type DnsCacheWithContext interface { + Get(context Context, domain string) net.IP + Add(contaxt Context, domain string, ip net.IP) +} + +type contextedDnsCache struct { + context 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) +} diff --git a/app/dns/dns.go b/app/dns/dns.go index 247890b548..54191926be 100644 --- a/app/dns/dns.go +++ b/app/dns/dns.go @@ -4,6 +4,8 @@ import ( "net" "sync" "time" + + "github.com/v2ray/v2ray-core/app" ) type entry struct { @@ -37,7 +39,8 @@ type DnsCache struct { func NewCache(config CacheConfig) *DnsCache { cache := &DnsCache{ - cache: make(map[string]*entry), + cache: make(map[string]*entry), + config: config, } go cache.cleanup() return cache @@ -64,7 +67,7 @@ func (this *DnsCache) cleanup() { } } -func (this *DnsCache) Add(domain string, ip net.IP) { +func (this *DnsCache) Add(context app.Context, domain string, ip net.IP) { this.RLock() entry, found := this.cache[domain] this.RUnlock() @@ -78,7 +81,7 @@ func (this *DnsCache) Add(domain string, ip net.IP) { } } -func (this *DnsCache) Get(domain string) net.IP { +func (this *DnsCache) Get(context app.Context, domain string) net.IP { this.RLock() entry, found := this.cache[domain] this.RUnlock() diff --git a/app/dns/dns_test.go b/app/dns/dns_test.go index be27639150..f466a70dd8 100644 --- a/app/dns/dns_test.go +++ b/app/dns/dns_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/v2ray/v2ray-core/app/dns" + apptesting "github.com/v2ray/v2ray-core/app/testing" netassert "github.com/v2ray/v2ray-core/common/net/testing/assert" v2testing "github.com/v2ray/v2ray-core/testing" ) @@ -14,10 +15,10 @@ func TestDnsAdd(t *testing.T) { domain := "v2ray.com" cache := dns.NewCache(nil) - ip := cache.Get(domain) + ip := cache.Get(&apptesting.Context{}, domain) netassert.IP(ip).IsNil() - cache.Add(domain, []byte{1, 2, 3, 4}) - ip = cache.Get(domain) + cache.Add(&apptesting.Context{}, domain, []byte{1, 2, 3, 4}) + ip = cache.Get(&apptesting.Context{}, domain) netassert.IP(ip).Equals(net.IP([]byte{1, 2, 3, 4})) } diff --git a/app/packet_dispatcher.go b/app/packet_dispatcher.go index 62ed936c87..04548bc5bd 100644 --- a/app/packet_dispatcher.go +++ b/app/packet_dispatcher.go @@ -9,3 +9,16 @@ import ( type PacketDispatcher interface { DispatchToOutbound(packet v2net.Packet) ray.InboundRay } + +type PacketDispatcherWithContext interface { + DispatchToOutbound(context Context, packet v2net.Packet) ray.InboundRay +} + +type contextedPacketDispatcher struct { + context Context + packetDispatcher PacketDispatcherWithContext +} + +func (this *contextedPacketDispatcher) DispatchToOutbound(packet v2net.Packet) ray.InboundRay { + return this.packetDispatcher.DispatchToOutbound(this.context, packet) +} diff --git a/app/space.go b/app/space.go index 0ccdb0efdf..73b97d4520 100644 --- a/app/space.go +++ b/app/space.go @@ -1,24 +1,62 @@ package app -type Space struct { - packetDispatcher PacketDispatcher - dnsCache DnsCache +type Context interface { + CallerTag() string +} + +type contextImpl struct { + callerTag string } -func NewSpace() *Space { - return new(Space) +func (this *contextImpl) CallerTag() string { + return this.callerTag } -func (this *Space) Bind(object interface{}) { - if packetDispatcher, ok := object.(PacketDispatcher); ok { +type SpaceController struct { + packetDispatcher PacketDispatcherWithContext + dnsCache DnsCacheWithContext +} + +func NewSpaceController() *SpaceController { + return new(SpaceController) +} + +func (this *SpaceController) Bind(object interface{}) { + if packetDispatcher, ok := object.(PacketDispatcherWithContext); ok { this.packetDispatcher = packetDispatcher } - if dnsCache, ok := object.(DnsCache); ok { + if dnsCache, ok := object.(DnsCacheWithContext); ok { this.dnsCache = dnsCache } } +func (this *SpaceController) ForContext(tag string) *Space { + return newSpace(this, &contextImpl{callerTag: tag}) +} + +type Space struct { + packetDispatcher PacketDispatcher + dnsCache DnsCache +} + +func newSpace(controller *SpaceController, context Context) *Space { + space := new(Space) + if controller.packetDispatcher != nil { + space.packetDispatcher = &contextedPacketDispatcher{ + context: context, + packetDispatcher: controller.packetDispatcher, + } + } + if controller.dnsCache != nil { + space.dnsCache = &contextedDnsCache{ + context: context, + dnsCache: controller.dnsCache, + } + } + return space +} + func (this *Space) HasPacketDispatcher() bool { return this.packetDispatcher != nil } diff --git a/app/testing/space.go b/app/testing/space.go new file mode 100644 index 0000000000..288e9c2abe --- /dev/null +++ b/app/testing/space.go @@ -0,0 +1,9 @@ +package testing + +type Context struct { + CallerTagValue string +} + +func (this *Context) CallerTag() string { + return this.CallerTagValue +} diff --git a/shell/point/point.go b/shell/point/point.go index 0775d4d959..6d07ed4c06 100644 --- a/shell/point/point.go +++ b/shell/point/point.go @@ -22,7 +22,7 @@ type Point struct { idh []*InboundDetourHandler odh map[string]connhandler.OutboundConnectionHandler router router.Router - space *app.Space + space *app.SpaceController } // NewPoint returns a new Point server based on given configuration. @@ -50,7 +50,7 @@ func NewPoint(pConfig PointConfig) (*Point, error) { log.SetLogLevel(logConfig.LogLevel()) } - vpoint.space = app.NewSpace() + vpoint.space = app.NewSpaceController() vpoint.space.Bind(vpoint) ichFactory := connhandler.GetInboundConnectionHandlerFactory(pConfig.InboundConfig().Protocol()) @@ -59,7 +59,7 @@ func NewPoint(pConfig PointConfig) (*Point, error) { return nil, BadConfiguration } ichConfig := pConfig.InboundConfig().Settings() - ich, err := ichFactory.Create(vpoint.space, ichConfig) + ich, err := ichFactory.Create(vpoint.space.ForContext("vpoint-default-inbound"), ichConfig) if err != nil { log.Error("Failed to create inbound connection handler: %v", err) return nil, err @@ -72,7 +72,7 @@ func NewPoint(pConfig PointConfig) (*Point, error) { return nil, BadConfiguration } ochConfig := pConfig.OutboundConfig().Settings() - och, err := ochFactory.Create(vpoint.space, ochConfig) + och, err := ochFactory.Create(vpoint.space.ForContext("vpoint-default-outbound"), ochConfig) if err != nil { log.Error("Failed to create outbound connection handler: %v", err) return nil, err @@ -84,7 +84,7 @@ func NewPoint(pConfig PointConfig) (*Point, error) { vpoint.idh = make([]*InboundDetourHandler, len(detours)) for idx, detourConfig := range detours { detourHandler := &InboundDetourHandler{ - space: vpoint.space, + space: vpoint.space.ForContext(detourConfig.Tag()), config: detourConfig, } err := detourHandler.Initialize() @@ -104,7 +104,7 @@ func NewPoint(pConfig PointConfig) (*Point, error) { log.Error("Unknown detour outbound connection handler factory %s", detourConfig.Protocol()) return nil, BadConfiguration } - detourHandler, err := detourFactory.Create(vpoint.space, detourConfig.Settings()) + detourHandler, err := detourFactory.Create(vpoint.space.ForContext(detourConfig.Tag()), detourConfig.Settings()) if err != nil { log.Error("Failed to create detour outbound connection handler: %v", err) return nil, err @@ -159,7 +159,7 @@ func (this *Point) Start() error { // Dispatches a Packet to an OutboundConnection. // The packet will be passed through the router (if configured), and then sent to an outbound // connection with matching tag. -func (this *Point) DispatchToOutbound(packet v2net.Packet) ray.InboundRay { +func (this *Point) DispatchToOutbound(context app.Context, packet v2net.Packet) ray.InboundRay { direct := ray.NewRay() dest := packet.Destination()