diff --git a/common/strmatcher/domain_matcher.go b/common/strmatcher/domain_matcher.go index f853efb0..314818bd 100644 --- a/common/strmatcher/domain_matcher.go +++ b/common/strmatcher/domain_matcher.go @@ -25,6 +25,11 @@ func (g *DomainMatcherGroup) Add(domain string, value uint32) { current := g.root parts := breakDomain(domain) for i := len(parts) - 1; i >= 0; i-- { + if current.value > 0 { + // if current node is already a match, it is not necessary to match further. + return + } + part := parts[i] if current.sub == nil { current.sub = make(map[string]*node) @@ -38,6 +43,7 @@ func (g *DomainMatcherGroup) Add(domain string, value uint32) { } current.value = value + current.sub = nil // shortcut sub nodes as current node is a match. } func (g *DomainMatcherGroup) addMatcher(m domainMatcher, value uint32) { diff --git a/common/strmatcher/domain_matcher_test.go b/common/strmatcher/domain_matcher_test.go index f8f0b42a..e01b30f7 100644 --- a/common/strmatcher/domain_matcher_test.go +++ b/common/strmatcher/domain_matcher_test.go @@ -11,6 +11,8 @@ func TestDomainMatcherGroup(t *testing.T) { g.Add("v2ray.com", 1) g.Add("google.com", 2) g.Add("x.a.com", 3) + g.Add("a.b.com", 4) + g.Add("c.a.b.com", 5) testCases := []struct { Domain string @@ -24,6 +26,14 @@ func TestDomainMatcherGroup(t *testing.T) { Domain: "y.com", Result: 0, }, + { + Domain: "a.b.com", + Result: 4, + }, + { + Domain: "c.a.b.com", + Result: 4, + }, } for _, testCase := range testCases {