From 4f5743604abc83f2277eaaa284d07dc640c37e90 Mon Sep 17 00:00:00 2001 From: v2ray Date: Sun, 24 Jan 2016 14:40:46 +0100 Subject: [PATCH] AnyCondition --- app/router/rules/chinasites.go | 24 +++++++---------------- app/router/rules/chinasites_test.go | 2 +- app/router/rules/condition.go | 25 ++++++++++++++++++++++++ app/router/rules/router_config.go | 12 ++++++++---- app/router/rules/router_config_test.go | 27 ++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 app/router/rules/router_config_test.go diff --git a/app/router/rules/chinasites.go b/app/router/rules/chinasites.go index 4b45a9a46..87882ef06 100644 --- a/app/router/rules/chinasites.go +++ b/app/router/rules/chinasites.go @@ -5,21 +5,8 @@ package rules import ( "encoding/json" "github.com/v2ray/v2ray-core/common/log" - v2net "github.com/v2ray/v2ray-core/common/net" ) -type ChinaSitesCondition struct { -} - -func (this *ChinaSitesCondition) Apply(dest v2net.Destination) bool { - for _, cond := range chinaSitesConds { - if cond.Apply(dest) { - return true - } - } - return false -} - func parseChinaSitesRule(data []byte) (*Rule, error) { rawRule := new(JsonRule) err := json.Unmarshal(data, rawRule) @@ -29,7 +16,7 @@ func parseChinaSitesRule(data []byte) (*Rule, error) { } return &Rule{ Tag: rawRule.OutboundTag, - Condition: &ChinaSitesCondition{}, + Condition: ChinaSitesConds, }, nil } @@ -48,7 +35,7 @@ const ( ) var ( - chinaSitesConds []Condition + ChinaSitesConds Condition ) func init() { @@ -360,12 +347,15 @@ func init() { anySubDomain + "zhubajie" + dotCom, } - chinaSitesConds = make([]Condition, len(regexpDomains)) + conds := make([]Condition, len(regexpDomains)) for idx, pattern := range regexpDomains { matcher, err := NewRegexpDomainMatcher(pattern) if err != nil { panic(err) } - chinaSitesConds[idx] = matcher + conds[idx] = matcher } + + anyConds := AnyCondition(conds) + ChinaSitesConds = &anyConds } diff --git a/app/router/rules/chinasites_test.go b/app/router/rules/chinasites_test.go index 10bbab768..23799bb22 100644 --- a/app/router/rules/chinasites_test.go +++ b/app/router/rules/chinasites_test.go @@ -17,7 +17,7 @@ func makeDomainDestination(domain string) v2net.Destination { func TestChinaSites(t *testing.T) { v2testing.Current(t) - rule := new(ChinaSitesCondition) + rule := ChinaSitesConds assert.Bool(rule.Apply(makeDomainDestination("v.qq.com"))).IsTrue() assert.Bool(rule.Apply(makeDomainDestination("www.163.com"))).IsTrue() assert.Bool(rule.Apply(makeDomainDestination("ngacn.cc"))).IsTrue() diff --git a/app/router/rules/condition.go b/app/router/rules/condition.go index 390352f64..c8effc86e 100644 --- a/app/router/rules/condition.go +++ b/app/router/rules/condition.go @@ -37,6 +37,31 @@ func (this *ConditionChan) Len() int { return len(*this) } +type AnyCondition []Condition + +func NewAnyCondition() *AnyCondition { + var anyCond AnyCondition = make([]Condition, 0, 8) + return &anyCond +} + +func (this *AnyCondition) Add(cond Condition) *AnyCondition { + *this = append(*this, cond) + return this +} + +func (this *AnyCondition) Apply(dest v2net.Destination) bool { + for _, cond := range *this { + if cond.Apply(dest) { + return true + } + } + return false +} + +func (this *AnyCondition) Len() int { + return len(*this) +} + type PlainDomainMatcher struct { pattern serial.StringLiteral } diff --git a/app/router/rules/router_config.go b/app/router/rules/router_config.go index 72c4d0940..9719b2f7b 100644 --- a/app/router/rules/router_config.go +++ b/app/router/rules/router_config.go @@ -34,6 +34,7 @@ func parseFieldRule(msg json.RawMessage) (*Rule, error) { conds := NewConditionChan() if rawFieldRule.Domain != nil && rawFieldRule.Domain.Len() > 0 { + anyCond := NewAnyCondition() for _, rawDomain := range *(rawFieldRule.Domain) { var matcher Condition if strings.HasPrefix(rawDomain.String(), "regexp:") { @@ -45,19 +46,22 @@ func parseFieldRule(msg json.RawMessage) (*Rule, error) { } else { matcher = NewPlainDomainMatcher(rawDomain.String()) } - conds.Add(matcher) + anyCond.Add(matcher) } + conds.Add(anyCond) } if rawFieldRule.IP != nil && rawFieldRule.IP.Len() > 0 { + anyCond := NewAnyCondition() for _, ipStr := range *(rawFieldRule.IP) { cidrMatcher, err := NewCIDRMatcher(ipStr.String()) if err != nil { log.Error("Router: Invalid IP range in router rule: ", err) return nil, err } - conds.Add(cidrMatcher) + anyCond.Add(cidrMatcher) } + conds.Add(anyCond) } if rawFieldRule.Port != nil { conds.Add(NewPortMatcher(*rawFieldRule.Port)) @@ -74,7 +78,7 @@ func parseFieldRule(msg json.RawMessage) (*Rule, error) { }, nil } -func parseRule(msg json.RawMessage) *Rule { +func ParseRule(msg json.RawMessage) *Rule { rawRule := new(JsonRule) err := json.Unmarshal(msg, rawRule) if err != nil { @@ -121,7 +125,7 @@ func init() { } config := NewRouterRuleConfig() for _, rawRule := range jsonConfig.RuleList { - rule := parseRule(rawRule) + rule := ParseRule(rawRule) config.Add(rule) } return config, nil diff --git a/app/router/rules/router_config_test.go b/app/router/rules/router_config_test.go new file mode 100644 index 000000000..497263fb2 --- /dev/null +++ b/app/router/rules/router_config_test.go @@ -0,0 +1,27 @@ +// +build json + +package rules_test + +import ( + "testing" + + . "github.com/v2ray/v2ray-core/app/router/rules" + v2net "github.com/v2ray/v2ray-core/common/net" + v2testing "github.com/v2ray/v2ray-core/testing" + "github.com/v2ray/v2ray-core/testing/assert" +) + +func TestFieldRule(t *testing.T) { + v2testing.Current(t) + + rule := ParseRule([]byte(`{ + "type": "field", + "domain": [ + "ooxx.com", + "oxox.com" + ], + "outboundTag": "direct" + }`)) + assert.Pointer(rule).IsNotNil() + assert.Bool(rule.Apply(v2net.TCPDestination(v2net.DomainAddress("www.ooxx.com"), 80))).IsTrue() +}