Files
go-away/utils/dnsbl.go
2025-04-08 22:11:58 +02:00

76 lines
1.4 KiB
Go

package utils
import (
"context"
"net"
"strconv"
)
type DNSBL struct {
target string
resolver *net.Resolver
}
func NewDNSBL(target string, resolver *net.Resolver) *DNSBL {
if resolver == nil {
resolver = net.DefaultResolver
}
return &DNSBL{
target: target,
resolver: resolver,
}
}
var nibbleTable = [16]byte{
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f',
}
type DNSBLResponse uint8
func (r DNSBLResponse) Bad() bool {
return r != ResponseGood && r != ResponseUnknown
}
const (
ResponseGood = DNSBLResponse(0)
ResponseUnknown = DNSBLResponse(255)
)
func (bl DNSBL) Lookup(ctx context.Context, ip net.IP) (DNSBLResponse, error) {
var target []byte
if ip4 := ip.To4(); ip4 != nil {
// max length preallocate
target = make([]byte, 0, len(bl.target)+1+len(ip4)*4)
for i := len(ip4) - 1; i >= 0; i-- {
target = strconv.AppendUint(target, uint64(ip4[i]), 10)
target = append(target, '.')
}
} else {
// IPv6
// max length preallocate
target = make([]byte, 0, len(bl.target)+1+len(ip)*4)
for i := len(ip) - 1; i >= 0; i-- {
target = append(target, nibbleTable[ip[i]&0xf], '.', ip[i]>>4, '.')
}
}
target = append(target, bl.target...)
ips, err := bl.resolver.LookupIP(ctx, "ip4", string(target))
if err != nil {
return ResponseUnknown, err
}
for _, ip := range ips {
ip4 := ip.To4()
return DNSBLResponse(ip4[len(ip4)-1]), nil
}
return ResponseUnknown, nil
}