package blocklist import ( "bufio" "os" "strings" ) type Blocklist struct { domains map[string]struct{} } func Load(path string) (*Blocklist, error) { bl := &Blocklist{domains: make(map[string]struct{})} f, err := os.Open(path) if err != nil { if os.IsNotExist(err) { return bl, nil } return nil, err } defer f.Close() sc := bufio.NewScanner(f) for sc.Scan() { line := strings.TrimSpace(sc.Text()) if line == "" || line[0] == '#' { continue } line = strings.ToLower(line) line = strings.TrimSuffix(line, ".") bl.domains[line] = struct{}{} } return bl, sc.Err() } func (bl *Blocklist) Blocked(qname string) bool { qname = strings.ToLower(qname) qname = strings.TrimSuffix(qname, ".") if _, ok := bl.domains[qname]; ok { return true } for i := 0; i < len(qname); i++ { if qname[i] == '.' { if _, ok := bl.domains[qname[i+1:]]; ok { return true } } } return false }