Moar parsers
This commit is contained in:
@@ -5,7 +5,7 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
@@ -22,12 +22,24 @@ type DomainsParser interface {
|
||||
ParseDomains(io.Reader) (domains []string, ignored int, err error)
|
||||
}
|
||||
|
||||
var domainsParsers []DomainsParser
|
||||
type NetworksParser interface {
|
||||
Parser
|
||||
ParseNetworks(io.Reader) (prefixes []netip.Prefix, ignored int, err error)
|
||||
}
|
||||
|
||||
var (
|
||||
domainsParsers []DomainsParser
|
||||
networksParsers []NetworksParser
|
||||
)
|
||||
|
||||
func RegisterDomainsParser(parser DomainsParser) {
|
||||
domainsParsers = append(domainsParsers, parser)
|
||||
}
|
||||
|
||||
func RegisterNetworksParser(parser NetworksParser) {
|
||||
networksParsers = append(networksParsers, parser)
|
||||
}
|
||||
|
||||
func ParseDomains(r io.Reader) (domains []string, ignored int, err error) {
|
||||
var (
|
||||
buffer = new(bytes.Buffer)
|
||||
@@ -42,7 +54,7 @@ func ParseDomains(r io.Reader) (domains []string, ignored int, err error) {
|
||||
}
|
||||
for _, parser = range domainsParsers {
|
||||
if parser.CanHandle(line) {
|
||||
log.Printf("using parser %T", parser)
|
||||
// log.Printf("using parser %T", parser)
|
||||
return parser.ParseDomains(io.MultiReader(buffer, r))
|
||||
}
|
||||
}
|
||||
@@ -51,26 +63,60 @@ func ParseDomains(r io.Reader) (domains []string, ignored int, err error) {
|
||||
return nil, 0, ErrNoParser
|
||||
}
|
||||
|
||||
func ParseNetworks(r io.Reader) (prefixes []netip.Prefix, ignored int, err error) {
|
||||
var (
|
||||
buffer = new(bytes.Buffer)
|
||||
scanner = bufio.NewScanner(io.TeeReader(r, buffer))
|
||||
line string
|
||||
parser NetworksParser
|
||||
)
|
||||
for scanner.Scan() {
|
||||
line = strings.TrimSpace(scanner.Text())
|
||||
if isComment(line) {
|
||||
continue
|
||||
}
|
||||
for _, parser = range networksParsers {
|
||||
if parser.CanHandle(line) {
|
||||
// log.Printf("using parser %T", parser)
|
||||
return parser.ParseNetworks(io.MultiReader(buffer, r))
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
return nil, 0, ErrNoParser
|
||||
}
|
||||
|
||||
func isComment(line string) bool {
|
||||
return line == "" || line[0] == '#' || line[0] == '!'
|
||||
}
|
||||
|
||||
func isDomainName(name string) bool {
|
||||
n, ok := dns.IsDomainName(name)
|
||||
func isDomainName(s string) bool {
|
||||
n, ok := dns.IsDomainName(s)
|
||||
return n >= 2 && ok
|
||||
}
|
||||
|
||||
func unique(strings []string) []string {
|
||||
if strings == nil {
|
||||
return nil
|
||||
}
|
||||
v := make(map[string]struct{})
|
||||
for _, s := range strings {
|
||||
v[s] = struct{}{}
|
||||
}
|
||||
o := make([]string, 0, len(v))
|
||||
for k := range v {
|
||||
o = append(o, k)
|
||||
}
|
||||
return o
|
||||
func isIP(s string) bool {
|
||||
_, err := netip.ParseAddr(s)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func isPrefix(s string) bool {
|
||||
_, err := netip.ParsePrefix(s)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func addrToPrefix(addr netip.Addr) netip.Prefix {
|
||||
switch {
|
||||
case addr.Is4():
|
||||
prefix, _ := addr.Prefix(32)
|
||||
return prefix
|
||||
case addr.Is4In6():
|
||||
prefix, _ := addr.Unmap().Prefix(32)
|
||||
return prefix
|
||||
case addr.Is6():
|
||||
prefix, _ := addr.Prefix(128)
|
||||
return prefix
|
||||
default:
|
||||
return netip.Prefix{}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user