| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 | package router_testimport (	"context"	"os"	"path/filepath"	"strconv"	"testing"	"time"	"v2ray.com/core/common/session"	proto "github.com/golang/protobuf/proto"	"v2ray.com/core/app/dispatcher"	. "v2ray.com/core/app/router"	"v2ray.com/core/common"	"v2ray.com/core/common/errors"	"v2ray.com/core/common/net"	"v2ray.com/core/common/platform"	"v2ray.com/core/common/protocol"	"v2ray.com/core/common/protocol/http"	. "v2ray.com/ext/assert"	"v2ray.com/ext/sysio")func withOutbound(outbound *session.Outbound) context.Context {	return session.ContextWithOutbound(context.Background(), outbound)}func TestRoutingRule(t *testing.T) {	assert := With(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,					},					{						Value: "^facebook\\.com$",						Type:  Domain_Regex,					},				},			},			test: []ruleTest{				{					input:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2ray.com"), 80)}),					output: true,				},				{					input:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("www.v2ray.com.www"), 80)}),					output: true,				},				{					input:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2ray.co"), 80)}),					output: false,				},				{					input:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("www.google.com"), 80)}),					output: true,				},				{					input:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("facebook.com"), 80)}),					output: true,				},				{					input:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("www.facebook.com"), 80)}),					output: false,				},				{					input:  context.Background(),					output: false,				},			},		},		{			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{				{					input:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress("8.8.8.8"), 80)}),					output: true,				},				{					input:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress("8.8.4.4"), 80)}),					output: false,				},				{					input:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), 80)}),					output: true,				},				{					input:  context.Background(),					output: false,				},			},		},		{			rule: &RoutingRule{				UserEmail: []string{					"admin@v2ray.com",				},			},			test: []ruleTest{				{					input:  protocol.ContextWithUser(context.Background(), &protocol.MemoryUser{Email: "admin@v2ray.com"}),					output: true,				},				{					input:  protocol.ContextWithUser(context.Background(), &protocol.MemoryUser{Email: "love@v2ray.com"}),					output: false,				},				{					input:  context.Background(),					output: false,				},			},		},		{			rule: &RoutingRule{				Protocol: []string{"http"},			},			test: []ruleTest{				{					input:  dispatcher.ContextWithSniffingResult(context.Background(), &http.SniffHeader{}),					output: true,				},			},		},	}	for _, test := range cases {		cond, err := test.rule.BuildCondition()		assert(err, IsNil)		for _, t := range test.test {			assert(cond.Apply(t.input), Equals, t.output)		}	}}func loadGeoSite(country string) ([]*Domain, error) {	geositeBytes, err := sysio.ReadAsset("geosite.dat")	if err != nil {		return nil, err	}	var geositeList GeoSiteList	if err := proto.Unmarshal(geositeBytes, &geositeList); err != nil {		return nil, err	}	for _, site := range geositeList.Entry {		if site.CountryCode == country {			return site.Domain, nil		}	}	return nil, errors.New("country not found: " + country)}func TestChinaSites(t *testing.T) {	assert := With(t)	common.Must(sysio.CopyFile(platform.GetAssetLocation("geosite.dat"), filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", "release", "config", "geosite.dat")))	domains, err := loadGeoSite("CN")	assert(err, IsNil)	matcher, err := NewDomainMatcher(domains)	common.Must(err)	assert(matcher.ApplyDomain("163.com"), IsTrue)	assert(matcher.ApplyDomain("163.com"), IsTrue)	assert(matcher.ApplyDomain("164.com"), IsFalse)	assert(matcher.ApplyDomain("164.com"), IsFalse)	for i := 0; i < 1024; i++ {		assert(matcher.ApplyDomain(strconv.Itoa(i)+".not-exists.com"), IsFalse)	}	time.Sleep(time.Second * 10)	for i := 0; i < 1024; i++ {		assert(matcher.ApplyDomain(strconv.Itoa(i)+".not-exists2.com"), IsFalse)	}}
 |