package dnsfilter import ( "fmt" "os" "path" "runtime" "strings" "sync/atomic" ) func isValidRule(rule string) bool { if len(rule) < 4 { return false } if rule[0] == '!' { return false } if rule[0] == '#' { return false } if strings.HasPrefix(rule, "[Adblock") { return false } // Filter out all sorts of cosmetic rules: // https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#cosmetic-rules masks := []string{ "##", "#@#", "#?#", "#@?#", "#$#", "#@$#", "#?$#", "#@?$#", "$$", "$@$", "#%#", "#@%#", } for _, mask := range masks { if strings.Contains(rule, mask) { return false } } return true } func updateMax(valuePtr *int64, maxPtr *int64) { for { current := atomic.LoadInt64(valuePtr) max := atomic.LoadInt64(maxPtr) if current <= max { break } swapped := atomic.CompareAndSwapInt64(maxPtr, max, current) if swapped { break } // swapping failed because value has changed after reading, try again } } func trace(format string, args ...interface{}) { pc := make([]uintptr, 10) // at least 1 entry needed runtime.Callers(2, pc) f := runtime.FuncForPC(pc[0]) var buf strings.Builder buf.WriteString(fmt.Sprintf("%s(): ", path.Base(f.Name()))) text := fmt.Sprintf(format, args...) buf.WriteString(text) if len(text) == 0 || text[len(text)-1] != '\n' { buf.WriteRune('\n') } fmt.Fprint(os.Stderr, buf.String()) }