From 069837417f375f72516e871da3710463efb8e0d6 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Wed, 17 May 2017 13:24:53 +0200 Subject: [PATCH] test case for routing rule --- app/router/condition.go | 2 +- app/router/condition_test.go | 88 ++++++++++++++++++++++++++++++++ app/router/config.go | 99 +++++++++++++++--------------------- 3 files changed, 130 insertions(+), 59 deletions(-) diff --git a/app/router/condition.go b/app/router/condition.go index 9c41db8b5..939c3c9f1 100644 --- a/app/router/condition.go +++ b/app/router/condition.go @@ -140,7 +140,7 @@ type CIDRMatcher struct { func NewCIDRMatcher(ip []byte, mask uint32, onSource bool) (*CIDRMatcher, error) { cidr := &net.IPNet{ IP: net.IP(ip), - Mask: net.CIDRMask(int(mask), len(ip)), + Mask: net.CIDRMask(int(mask), len(ip)*8), } return &CIDRMatcher{ cidr: cidr, diff --git a/app/router/condition_test.go b/app/router/condition_test.go index 2c9a7146c..0d0df3e44 100644 --- a/app/router/condition_test.go +++ b/app/router/condition_test.go @@ -49,3 +49,91 @@ func TestSubDomainMatcher(t *testing.T) { assert.Bool(matcher.Apply(test.input) == test.output).IsTrue() } } + +func TestRoutingRule(t *testing.T) { + assert := assert.On(t) + + type ruleTest struct { + input context.Context + output bool + } + + cases := []struct { + rule *RoutingRule + test []ruleTest + }{ + { + rule: &RoutingRule{ + Domain: []*Domain{ + { + Value: "v2ray.com", + Type: Domain_Plain, + }, + { + Value: "google.com", + Type: Domain_Domain, + }, + }, + }, + test: []ruleTest{ + ruleTest{ + input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("v2ray.com"), 80)), + output: true, + }, + ruleTest{ + input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("www.v2ray.com.www"), 80)), + output: true, + }, + ruleTest{ + input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("v2ray.co"), 80)), + output: false, + }, + ruleTest{ + input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("www.google.com"), 80)), + output: true, + }, + }, + }, + { + rule: &RoutingRule{ + Cidr: []*CIDR{ + { + Ip: []byte{8, 8, 8, 8}, + Prefix: 32, + }, + { + Ip: []byte{8, 8, 8, 8}, + Prefix: 32, + }, + { + Ip: net.ParseAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334").IP(), + Prefix: 128, + }, + }, + }, + test: []ruleTest{ + ruleTest{ + input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.ParseAddress("8.8.8.8"), 80)), + output: true, + }, + ruleTest{ + input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.ParseAddress("8.8.4.4"), 80)), + output: false, + }, + ruleTest{ + input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.ParseAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), 80)), + output: true, + }, + }, + }, + } + + for _, test := range cases { + cond, err := test.rule.BuildCondition() + assert.Error(err).IsNil() + + for _, t := range test.test { + assert.Bool(cond.Apply(t.input)).Equals(t.output) + } + } +} diff --git a/app/router/config.go b/app/router/config.go index 7101f38ed..77456acb4 100644 --- a/app/router/config.go +++ b/app/router/config.go @@ -16,6 +16,39 @@ func (r *Rule) Apply(ctx context.Context) bool { return r.Condition.Apply(ctx) } +func cidrToCondition(cidr []*CIDR, source bool) (Condition, error) { + ipv4Net := v2net.NewIPNet() + ipv6Cond := NewAnyCondition() + hasIpv6 := false + + for _, ip := range cidr { + switch len(ip.Ip) { + case net.IPv4len: + ipv4Net.AddIP(ip.Ip, byte(ip.Prefix)) + case net.IPv6len: + hasIpv6 = true + matcher, err := NewCIDRMatcher(ip.Ip, ip.Prefix, source) + if err != nil { + return nil, err + } + ipv6Cond.Add(matcher) + default: + return nil, newError("invalid IP length").AtError() + } + } + + if !ipv4Net.IsEmpty() && hasIpv6 { + cond := NewAnyCondition() + cond.Add(NewIPv4Matcher(ipv4Net, source)) + cond.Add(ipv6Cond) + return cond, nil + } else if !ipv4Net.IsEmpty() { + return NewIPv4Matcher(ipv4Net, source), nil + } else { + return ipv6Cond, nil + } +} + func (rr *RoutingRule) BuildCondition() (Condition, error) { conds := NewConditionChan() @@ -41,36 +74,11 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) { } if len(rr.Cidr) > 0 { - ipv4Net := v2net.NewIPNet() - ipv6Cond := NewAnyCondition() - hasIpv6 := false - - for _, ip := range rr.Cidr { - switch len(ip.Ip) { - case net.IPv4len: - ipv4Net.AddIP(ip.Ip, byte(ip.Prefix)) - case net.IPv6len: - hasIpv6 = true - matcher, err := NewCIDRMatcher(ip.Ip, ip.Prefix, false) - if err != nil { - return nil, err - } - ipv6Cond.Add(matcher) - default: - return nil, newError("invalid IP length").AtError() - } - } - - if !ipv4Net.IsEmpty() && hasIpv6 { - cond := NewAnyCondition() - cond.Add(NewIPv4Matcher(ipv4Net, false)) - cond.Add(ipv6Cond) - conds.Add(cond) - } else if !ipv4Net.IsEmpty() { - conds.Add(NewIPv4Matcher(ipv4Net, false)) - } else if hasIpv6 { - conds.Add(ipv6Cond) + cond, err := cidrToCondition(rr.Cidr, false) + if err != nil { + return nil, err } + conds.Add(cond) } if rr.PortRange != nil { @@ -82,36 +90,11 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) { } if len(rr.SourceCidr) > 0 { - ipv4Net := v2net.NewIPNet() - ipv6Cond := NewAnyCondition() - hasIpv6 := false - - for _, ip := range rr.SourceCidr { - switch len(ip.Ip) { - case net.IPv4len: - ipv4Net.AddIP(ip.Ip, byte(ip.Prefix)) - case net.IPv6len: - hasIpv6 = true - matcher, err := NewCIDRMatcher(ip.Ip, ip.Prefix, true) - if err != nil { - return nil, err - } - ipv6Cond.Add(matcher) - default: - return nil, newError("invalid IP length").AtError() - } - } - - if !ipv4Net.IsEmpty() && hasIpv6 { - cond := NewAnyCondition() - cond.Add(NewIPv4Matcher(ipv4Net, true)) - cond.Add(ipv6Cond) - conds.Add(cond) - } else if !ipv4Net.IsEmpty() { - conds.Add(NewIPv4Matcher(ipv4Net, true)) - } else if hasIpv6 { - conds.Add(ipv6Cond) + cond, err := cidrToCondition(rr.SourceCidr, true) + if err != nil { + return nil, err } + conds.Add(cond) } if len(rr.UserEmail) > 0 {