New syntax for blocking/whitelisting rules: exact matching

Example: =example.com

Matches `example.com` but not `api.example.com`
This commit is contained in:
Frank Denis 2018-04-09 13:02:42 +02:00
parent de6a8d230e
commit 7d10628a5f
4 changed files with 20 additions and 0 deletions

View File

@ -10,6 +10,7 @@
## ads.* | matches anything with an "ads." prefix
## *.example.com | matches example.com and all names within that zone such as www.example.com
## example.com | identical to the above
## =example.com | block example.com but not *.example.com
## *sex* | matches any name containing that substring
## ads[0-9]* | matches "ads" followed by one or more digits
## ads*.example* | *, ? and [] can be used anywhere, but prefixes/suffixes are faster

View File

@ -297,6 +297,7 @@ cache_neg_ttl = 60
## Blacklists are made of one pattern per line. Example of valid patterns:
##
## example.com
## =example.com
## *sex*
## ads.*
## ads*.example.*

View File

@ -10,6 +10,7 @@
## ads.* | matches anything with an "ads." prefix
## *.example.com | matches example.com and all names within that zone such as www.example.com
## example.com | identical to the above
## =example.com | whitelists example.com but not *.example.com
## *sex* | matches any name containing that substring
## ads[0-9]* | matches "ads" followed by one or more digits
## ads*.example* | *, ? and [] can be used anywhere, but prefixes/suffixes are faster

View File

@ -18,6 +18,7 @@ const (
PatternTypeSuffix
PatternTypeSubstring
PatternTypePattern
PatternTypeExact
)
type PatternMatcher struct {
@ -25,6 +26,7 @@ type PatternMatcher struct {
blockedSuffixes *critbitgo.Trie
blockedSubstrings []string
blockedPatterns []string
blockedExact map[string]interface{}
indirectVals map[string]interface{}
}
@ -32,6 +34,7 @@ func NewPatternPatcher() *PatternMatcher {
patternMatcher := PatternMatcher{
blockedPrefixes: critbitgo.NewTrie(),
blockedSuffixes: critbitgo.NewTrie(),
blockedExact: make(map[string]interface{}),
indirectVals: make(map[string]interface{}),
}
return &patternMatcher
@ -51,6 +54,7 @@ func isGlobCandidate(str string) bool {
func (patternMatcher *PatternMatcher) Add(pattern string, val interface{}, position int) (PatternType, error) {
leadingStar := strings.HasPrefix(pattern, "*")
trailingStar := strings.HasSuffix(pattern, "*")
exact := strings.HasPrefix(pattern, "=")
patternType := PatternTypeNone
if isGlobCandidate(pattern) {
patternType = PatternTypePattern
@ -70,6 +74,12 @@ func (patternMatcher *PatternMatcher) Add(pattern string, val interface{}, posit
return patternType, fmt.Errorf("Syntax error in block rules at pattern %d", position)
}
pattern = pattern[:len(pattern)-1]
} else if exact {
patternType = PatternTypeExact
if len(pattern) < 2 {
return patternType, fmt.Errorf("Syntax error in block rules at pattern %d", position)
}
pattern = pattern[1:]
} else {
patternType = PatternTypeSuffix
if leadingStar {
@ -97,6 +107,8 @@ func (patternMatcher *PatternMatcher) Add(pattern string, val interface{}, posit
patternMatcher.blockedPrefixes.Insert([]byte(pattern), val)
case PatternTypeSuffix:
patternMatcher.blockedSuffixes.Insert([]byte(StringReverse(pattern)), val)
case PatternTypeExact:
patternMatcher.blockedExact[pattern] = val
default:
dlog.Fatal("Unexpected block type")
}
@ -140,5 +152,10 @@ func (patternMatcher *PatternMatcher) Eval(qName string) (reject bool, reason st
return true, pattern, patternMatcher.indirectVals[pattern]
}
}
if xval := patternMatcher.blockedExact[qName]; xval != nil {
return true, qName, xval
}
return false, "", nil
}