Moar parsers

This commit is contained in:
2025-10-06 23:11:50 +02:00
parent a254b306f2
commit 5f0f4aa96b
14 changed files with 419 additions and 136 deletions

View File

@@ -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{}
}
}