From f4ec19625e5e7c08303d494a9386a6d4c2e7930e Mon Sep 17 00:00:00 2001 From: V2Ray Date: Sun, 22 Nov 2015 12:05:21 +0100 Subject: [PATCH] Implementation of rules router --- app/router/config/json/json.go | 10 +++- app/router/router.go | 2 +- .../rules.go => config/json/fieldrule.go} | 15 ------ .../rules/{ => config}/json/fieldrule_test.go | 0 app/router/rules/config/json/router.go | 47 ++++++++++++++++++ app/router/rules/config/json/rules.go | 20 ++++++++ app/router/rules/config/router.go | 5 ++ app/router/rules/{ => config}/rules.go | 2 +- app/router/rules/router.go | 48 +++++++++++++++++++ 9 files changed, 131 insertions(+), 18 deletions(-) rename app/router/rules/{json/rules.go => config/json/fieldrule.go} (83%) rename app/router/rules/{ => config}/json/fieldrule_test.go (100%) create mode 100644 app/router/rules/config/json/router.go create mode 100644 app/router/rules/config/json/rules.go create mode 100644 app/router/rules/config/router.go rename app/router/rules/{ => config}/rules.go (92%) diff --git a/app/router/config/json/json.go b/app/router/config/json/json.go index 17363a621..2ce911b4c 100644 --- a/app/router/config/json/json.go +++ b/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 } diff --git a/app/router/router.go b/app/router/router.go index c984a809b..62c18c1ce 100644 --- a/app/router/router.go +++ b/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 { diff --git a/app/router/rules/json/rules.go b/app/router/rules/config/json/fieldrule.go similarity index 83% rename from app/router/rules/json/rules.go rename to app/router/rules/config/json/fieldrule.go index 1b86590b2..4474d080c 100644 --- a/app/router/rules/json/rules.go +++ b/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 diff --git a/app/router/rules/json/fieldrule_test.go b/app/router/rules/config/json/fieldrule_test.go similarity index 100% rename from app/router/rules/json/fieldrule_test.go rename to app/router/rules/config/json/fieldrule_test.go diff --git a/app/router/rules/config/json/router.go b/app/router/rules/config/json/router.go new file mode 100644 index 000000000..01f364239 --- /dev/null +++ b/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) + }) +} diff --git a/app/router/rules/config/json/rules.go b/app/router/rules/config/json/rules.go new file mode 100644 index 000000000..967b27c99 --- /dev/null +++ b/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 +} diff --git a/app/router/rules/config/router.go b/app/router/rules/config/router.go new file mode 100644 index 000000000..aea0ce084 --- /dev/null +++ b/app/router/rules/config/router.go @@ -0,0 +1,5 @@ +package config + +type RouterRuleConfig interface { + Rules() []Rule +} diff --git a/app/router/rules/rules.go b/app/router/rules/config/rules.go similarity index 92% rename from app/router/rules/rules.go rename to app/router/rules/config/rules.go index a7b98554d..355650bd5 100644 --- a/app/router/rules/rules.go +++ b/app/router/rules/config/rules.go @@ -1,4 +1,4 @@ -package rules +package config import ( "github.com/v2ray/v2ray-core/app/point/config" diff --git a/app/router/rules/router.go b/app/router/rules/router.go index 1e8c7fa08..33fc147eb 100644 --- a/app/router/rules/router.go +++ b/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{}) +}