| 
					
				 | 
			
			
				@@ -8,19 +8,27 @@ import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"v2ray.com/core/common/task" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Matcher is the interface to determine a string matches a pattern. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type Matcher interface { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Match returns true if the given string matches a predefined pattern. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Match(string) bool 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Type is the type of the matcher. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type Type byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Full is the type of matcher that the input string must exactly equal to the pattern. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Full Type = iota 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Substr is the type of matcher that the input string must contain the pattern as a sub-string. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Substr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Domain is the type of matcher that the input string must be a sub-domain or itself of the pattern. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Domain 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Regex is the type of matcher that the input string must matches the regular-expression pattern. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Regex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// New creates a new Matcher based on the given pattern. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (t Type) New(pattern string) (Matcher, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	switch t { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	case Full: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -42,8 +50,10 @@ func (t Type) New(pattern string) (Matcher, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// IndexMatcher is the interface for matching with a group of matchers. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type IndexMatcher interface { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	Match(pattern string) uint32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Match returns the the index of a matcher that matches the input. It returns 0 if no such matcher exists. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	Match(input string) uint32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type matcherEntry struct { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -51,6 +61,8 @@ type matcherEntry struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	id uint32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// MatcherGroup is an implementation of IndexMatcher. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Empty initialization works. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type MatcherGroup struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	count         uint32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	fullMatcher   FullMatcherGroup 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -58,10 +70,7 @@ type MatcherGroup struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	otherMatchers []matcherEntry 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func NewMatcherGroup() *MatcherGroup { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return &MatcherGroup{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Add adds a new Matcher into the MatcherGroup, and returns its index. The index will never be 0. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (g *MatcherGroup) Add(m Matcher) uint32 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	g.count++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	c := g.count 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -81,6 +90,7 @@ func (g *MatcherGroup) Add(m Matcher) uint32 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Match implements IndexMatcher.Match. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (g *MatcherGroup) Match(pattern string) uint32 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if c := g.fullMatcher.Match(pattern); c > 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return c 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -99,6 +109,7 @@ func (g *MatcherGroup) Match(pattern string) uint32 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Size returns the number of matchers in the MatcherGroup. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (g *MatcherGroup) Size() uint32 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return g.count 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -108,6 +119,7 @@ type cacheEntry struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	result    uint32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// CachedMatcherGroup is a IndexMatcher with cachable results. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type CachedMatcherGroup struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	sync.RWMutex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	group   *MatcherGroup 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -115,6 +127,7 @@ type CachedMatcherGroup struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	cleanup *task.Periodic 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// NewCachedMatcherGroup creats a new CachedMatcherGroup. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func NewCachedMatcherGroup(g *MatcherGroup) *CachedMatcherGroup { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	r := &CachedMatcherGroup{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		group: g, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -139,6 +152,7 @@ func NewCachedMatcherGroup(g *MatcherGroup) *CachedMatcherGroup { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return r 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Match implements IndexMatcher.Match. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (g *CachedMatcherGroup) Match(pattern string) uint32 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	g.RLock() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	r, f := g.cache[pattern] 
			 |