Parcourir la source

code ready for selective routing

V2Ray il y a 10 ans
Parent
commit
12e72509a5

+ 3 - 0
app/point/config/config.go

@@ -1,6 +1,7 @@
 package config
 
 import (
+	routerconfig "github.com/v2ray/v2ray-core/app/router/config"
 	v2net "github.com/v2ray/v2ray-core/common/net"
 )
 
@@ -30,7 +31,9 @@ type OutboundDetourConfig interface {
 type PointConfig interface {
 	Port() uint16
 	LogConfig() LogConfig
+	RouterConfig() routerconfig.RouterConfig
 	InboundConfig() ConnectionConfig
 	OutboundConfig() ConnectionConfig
 	InboundDetours() []InboundDetourConfig
+	OutboundDetours() []OutboundDetourConfig
 }

+ 16 - 6
app/point/config/json/json.go

@@ -6,18 +6,21 @@ import (
 	"os"
 
 	"github.com/v2ray/v2ray-core/app/point/config"
+	routerconfig "github.com/v2ray/v2ray-core/app/router/config"
+	routerconfigjson "github.com/v2ray/v2ray-core/app/router/config/json"
 	"github.com/v2ray/v2ray-core/common/log"
 	proxyconfig "github.com/v2ray/v2ray-core/proxy/common/config"
 )
 
 // Config is the config for Point server.
 type Config struct {
-	PortValue            uint16                  `json:"port"` // Port of this Point server.
-	LogConfigValue       *LogConfig              `json:"log"`
-	InboundConfigValue   *ConnectionConfig       `json:"inbound"`
-	OutboundConfigValue  *ConnectionConfig       `json:"outbound"`
-	InboundDetoursValue  []*InboundDetourConfig  `json:"inboundDetour"`
-	OutboundDetoursValue []*OutboundDetourConfig `json:"outboundDetour"`
+	PortValue            uint16                         `json:"port"` // Port of this Point server.
+	LogConfigValue       *LogConfig                     `json:"log"`
+	RouterConfigValue    *routerconfigjson.RouterConfig `json:"router"`
+	InboundConfigValue   *ConnectionConfig              `json:"inbound"`
+	OutboundConfigValue  *ConnectionConfig              `json:"outbound"`
+	InboundDetoursValue  []*InboundDetourConfig         `json:"inboundDetour"`
+	OutboundDetoursValue []*OutboundDetourConfig        `json:"outboundDetour"`
 }
 
 func (config *Config) Port() uint16 {
@@ -31,6 +34,13 @@ func (config *Config) LogConfig() config.LogConfig {
 	return config.LogConfigValue
 }
 
+func (this *Config) RouterConfig() routerconfig.RouterConfig {
+	if this.RouterConfigValue == nil {
+		return nil
+	}
+	return this.RouterConfigValue
+}
+
 func (config *Config) InboundConfig() config.ConnectionConfig {
 	if config.InboundConfigValue == nil {
 		return nil

+ 29 - 5
app/point/config/testing/mocks/config.go

@@ -2,6 +2,7 @@ package mocks
 
 import (
 	"github.com/v2ray/v2ray-core/app/point/config"
+	routerconfig "github.com/v2ray/v2ray-core/app/router/config"
 	v2net "github.com/v2ray/v2ray-core/common/net"
 )
 
@@ -44,16 +45,27 @@ func (this *InboundDetourConfig) PortRange() v2net.PortRange {
 	return this.PortRangeValue
 }
 
+type OutboundDetourConfig struct {
+	ConnectionConfig
+	TagValue config.DetourTag
+}
+
+func (this *OutboundDetourConfig) Tag() config.DetourTag {
+	return this.TagValue
+}
+
 func (config *LogConfig) AccessLog() string {
 	return config.AccessLogValue
 }
 
 type Config struct {
-	PortValue           uint16
-	LogConfigValue      *LogConfig
-	InboundConfigValue  *ConnectionConfig
-	OutboundConfigValue *ConnectionConfig
-	InboundDetoursValue []*InboundDetourConfig
+	PortValue            uint16
+	LogConfigValue       *LogConfig
+	RouterConfigValue    routerconfig.RouterConfig
+	InboundConfigValue   *ConnectionConfig
+	OutboundConfigValue  *ConnectionConfig
+	InboundDetoursValue  []*InboundDetourConfig
+	OutboundDetoursValue []*OutboundDetourConfig
 }
 
 func (config *Config) Port() uint16 {
@@ -64,6 +76,10 @@ func (config *Config) LogConfig() config.LogConfig {
 	return config.LogConfigValue
 }
 
+func (this *Config) RouterConfig() routerconfig.RouterConfig {
+	return this.RouterConfigValue
+}
+
 func (config *Config) InboundConfig() config.ConnectionConfig {
 	return config.InboundConfigValue
 }
@@ -79,3 +95,11 @@ func (this *Config) InboundDetours() []config.InboundDetourConfig {
 	}
 	return detours
 }
+
+func (this *Config) OutboundDetours() []config.OutboundDetourConfig {
+	detours := make([]config.OutboundDetourConfig, len(this.OutboundDetoursValue))
+	for idx, detour := range this.OutboundDetoursValue {
+		detours[idx] = detour
+	}
+	return detours
+}

+ 48 - 4
app/point/point.go

@@ -2,6 +2,7 @@ package point
 
 import (
 	"github.com/v2ray/v2ray-core/app/point/config"
+	"github.com/v2ray/v2ray-core/app/router"
 	"github.com/v2ray/v2ray-core/common/log"
 	v2net "github.com/v2ray/v2ray-core/common/net"
 	"github.com/v2ray/v2ray-core/common/retry"
@@ -11,10 +12,12 @@ import (
 
 // Point is an single server in V2Ray system.
 type Point struct {
-	port uint16
-	ich  connhandler.InboundConnectionHandler
-	och  connhandler.OutboundConnectionHandler
-	idh  []*InboundDetourHandler
+	port   uint16
+	ich    connhandler.InboundConnectionHandler
+	och    connhandler.OutboundConnectionHandler
+	idh    []*InboundDetourHandler
+	odh    map[config.DetourTag]connhandler.OutboundConnectionHandler
+	router router.Router
 }
 
 // NewPoint returns a new Point server based on given configuration.
@@ -65,6 +68,34 @@ func NewPoint(pConfig config.PointConfig) (*Point, error) {
 		}
 	}
 
+	outboundDetours := pConfig.OutboundDetours()
+	if len(outboundDetours) > 0 {
+		vpoint.odh = make(map[config.DetourTag]connhandler.OutboundConnectionHandler)
+		for _, detourConfig := range outboundDetours {
+			detourFactory := connhandler.GetOutboundConnectionHandlerFactory(detourConfig.Protocol())
+			if detourFactory == nil {
+				log.Error("Unknown detour outbound connection handler factory %s", detourConfig.Protocol())
+				return nil, config.BadConfiguration
+			}
+			detourHandler, err := detourFactory.Create(detourConfig.Settings())
+			if err != nil {
+				log.Error("Failed to create detour outbound connection handler: %v", err)
+				return nil, err
+			}
+			vpoint.odh[detourConfig.Tag()] = detourHandler
+		}
+	}
+
+	routerConfig := pConfig.RouterConfig()
+	if routerConfig != nil {
+		r, err := router.CreateRouter(routerConfig.Strategy(), routerConfig.Settings())
+		if err != nil {
+			log.Error("Failed to create router: %v", err)
+			return nil, config.BadConfiguration
+		}
+		vpoint.router = r
+	}
+
 	return vpoint, nil
 }
 
@@ -100,6 +131,19 @@ func (vp *Point) Start() error {
 
 func (p *Point) DispatchToOutbound(packet v2net.Packet) ray.InboundRay {
 	direct := ray.NewRay()
+	dest := packet.Destination()
+
+	if p.router != nil {
+		tag, err := p.router.TakeDetour(dest)
+		if err == nil {
+			handler, found := p.odh[tag]
+			if found {
+				go handler.Dispatch(packet, direct)
+				return direct
+			}
+		}
+	}
+
 	go p.och.Dispatch(packet, direct)
 	return direct
 }

+ 1 - 1
app/router/router.go

@@ -12,7 +12,7 @@ var (
 )
 
 type Router interface {
-	TakeDetour(v2net.Destination) (*config.DetourTag, error)
+	TakeDetour(v2net.Destination) (config.DetourTag, error)
 }
 
 type RouterFactory interface {

+ 2 - 3
app/router/rules/config/json/rules.go

@@ -10,9 +10,8 @@ type Rule struct {
 	OutboundTag string `json:"outboundTag"`
 }
 
-func (this *Rule) Tag() *config.DetourTag {
-	detourTag := config.DetourTag(this.OutboundTag)
-	return &detourTag
+func (this *Rule) Tag() config.DetourTag {
+	return config.DetourTag(this.OutboundTag)
 }
 
 func (this *Rule) Apply(dest v2net.Destination) bool {

+ 1 - 1
app/router/rules/config/rules.go

@@ -6,6 +6,6 @@ import (
 )
 
 type Rule interface {
-	Tag() *config.DetourTag
+	Tag() config.DetourTag
 	Apply(dest v2net.Destination) bool
 }

+ 6 - 4
app/router/rules/router.go

@@ -11,21 +11,23 @@ import (
 )
 
 var (
-	InvalidRule = errors.New("Invalid Rule")
-	EmptyTag    = pointconfig.DetourTag("")
+	InvalidRule      = errors.New("Invalid Rule")
+	NoRuleApplicable = errors.New("No rule applicable")
+
+	EmptyTag = pointconfig.DetourTag("")
 )
 
 type Router struct {
 	rules []config.Rule
 }
 
-func (this *Router) TakeDetour(dest v2net.Destination) (*pointconfig.DetourTag, error) {
+func (this *Router) TakeDetour(dest v2net.Destination) (pointconfig.DetourTag, error) {
 	for _, rule := range this.rules {
 		if rule.Apply(dest) {
 			return rule.Tag(), nil
 		}
 	}
-	return &EmptyTag, nil
+	return EmptyTag, NoRuleApplicable
 }
 
 type RouterFactory struct {