Przeglądaj źródła

Implementation of rules router

V2Ray 10 lat temu
rodzic
commit
f4ec19625e

+ 9 - 1
app/router/config/json/json.go

@@ -2,6 +2,8 @@ package json
 
 import (
 	"encoding/json"
+
+	"github.com/v2ray/v2ray-core/common/log"
 )
 
 type RouterConfig struct {
@@ -14,5 +16,11 @@ func (this *RouterConfig) Strategy() string {
 }
 
 func (this *RouterConfig) Settings() interface{} {
-	return CreateRouterConfig(this.Strategy())
+	settings := CreateRouterConfig(this.Strategy())
+	err := json.Unmarshal(this.SettingsValue, settings)
+	if err != nil {
+		log.Error("Failed to load router settings: %v", err)
+		return nil
+	}
+	return settings
 }

+ 1 - 1
app/router/router.go

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

+ 0 - 15
app/router/rules/json/rules.go → app/router/rules/config/json/fieldrule.go

@@ -6,25 +6,10 @@ import (
 	"net"
 	"strings"
 
-	"github.com/v2ray/v2ray-core/app/point/config"
 	v2net "github.com/v2ray/v2ray-core/common/net"
 	v2netjson "github.com/v2ray/v2ray-core/common/net/json"
 )
 
-type Rule struct {
-	Type        string `json:"type"`
-	OutboundTag string `json:"outboundTag"`
-}
-
-func (this *Rule) Tag() *config.DetourTag {
-	detourTag := config.DetourTag(this.OutboundTag)
-	return &detourTag
-}
-
-func (this *Rule) Apply(dest v2net.Destination) bool {
-	return false
-}
-
 type FieldRule struct {
 	Rule
 	Domain  string

+ 0 - 0
app/router/rules/json/fieldrule_test.go → app/router/rules/config/json/fieldrule_test.go


+ 47 - 0
app/router/rules/config/json/router.go

@@ -0,0 +1,47 @@
+package json
+
+import (
+	"encoding/json"
+
+	v2routerconfigjson "github.com/v2ray/v2ray-core/app/router/config/json"
+	"github.com/v2ray/v2ray-core/app/router/rules/config"
+	"github.com/v2ray/v2ray-core/common/log"
+)
+
+type RouterRuleConfig struct {
+	RuleList []json.RawMessage `json:"rules"`
+}
+
+func parseRule(msg json.RawMessage) config.Rule {
+	rule := new(Rule)
+	err := json.Unmarshal(msg, rule)
+	if err != nil {
+		log.Error("Invalid router rule: %v", err)
+		return nil
+	}
+	if rule.Type == "field" {
+		fieldrule := new(FieldRule)
+		err = json.Unmarshal(msg, fieldrule)
+		if err != nil {
+			log.Error("Invalid field rule: %v", err)
+			return nil
+		}
+		return fieldrule
+	}
+	log.Error("Unknown router rule type: %s", rule.Type)
+	return nil
+}
+
+func (this *RouterRuleConfig) Rules() []config.Rule {
+	rules := make([]config.Rule, len(this.RuleList))
+	for idx, rawRule := range this.RuleList {
+		rules[idx] = parseRule(rawRule)
+	}
+	return rules
+}
+
+func init() {
+	v2routerconfigjson.RegisterRouterConfig("rules", func() interface{} {
+		return new(RouterRuleConfig)
+	})
+}

+ 20 - 0
app/router/rules/config/json/rules.go

@@ -0,0 +1,20 @@
+package json
+
+import (
+	"github.com/v2ray/v2ray-core/app/point/config"
+	v2net "github.com/v2ray/v2ray-core/common/net"
+)
+
+type Rule struct {
+	Type        string `json:"type"`
+	OutboundTag string `json:"outboundTag"`
+}
+
+func (this *Rule) Tag() *config.DetourTag {
+	detourTag := config.DetourTag(this.OutboundTag)
+	return &detourTag
+}
+
+func (this *Rule) Apply(dest v2net.Destination) bool {
+	return false
+}

+ 5 - 0
app/router/rules/config/router.go

@@ -0,0 +1,5 @@
+package config
+
+type RouterRuleConfig interface {
+	Rules() []Rule
+}

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

@@ -1,4 +1,4 @@
-package rules
+package config
 
 import (
 	"github.com/v2ray/v2ray-core/app/point/config"

+ 48 - 0
app/router/rules/router.go

@@ -1 +1,49 @@
 package rules
+
+import (
+	"errors"
+
+	pointconfig "github.com/v2ray/v2ray-core/app/point/config"
+	"github.com/v2ray/v2ray-core/app/router"
+	"github.com/v2ray/v2ray-core/app/router/rules/config"
+	"github.com/v2ray/v2ray-core/app/router/rules/config/json"
+	v2net "github.com/v2ray/v2ray-core/common/net"
+)
+
+var (
+	InvalidRule = errors.New("Invalid Rule")
+	EmptyTag    = pointconfig.DetourTag("")
+)
+
+type Router struct {
+	rules []config.Rule
+}
+
+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
+}
+
+type RouterFactory struct {
+}
+
+func (this *RouterFactory) Create(rawConfig interface{}) (router.Router, error) {
+	config := rawConfig.(*json.RouterRuleConfig)
+	rules := config.Rules()
+	for _, rule := range rules {
+		if rule == nil {
+			return nil, InvalidRule
+		}
+	}
+	return &Router{
+		rules: rules,
+	}, nil
+}
+
+func init() {
+	router.RegisterRouter("rules", &RouterFactory{})
+}