safing-portmaster/service/resolver/block-detection.go

61 lines
1.2 KiB
Go

package resolver
import (
"net"
"github.com/miekg/dns"
)
// Supported upstream block detections.
const (
BlockDetectionRefused = "refused"
BlockDetectionZeroIP = "zeroip"
BlockDetectionEmptyAnswer = "empty"
BlockDetectionDisabled = "disabled"
)
func isBlockedUpstream(resolver *Resolver, answer *dns.Msg) bool {
if resolver.UpstreamBlockDetection == BlockDetectionDisabled {
return false
}
switch resolver.UpstreamBlockDetection {
case BlockDetectionRefused:
return answer.Rcode == dns.RcodeRefused
case BlockDetectionZeroIP:
if answer.Rcode != dns.RcodeSuccess {
return false
}
var ips []net.IP
for _, rr := range answer.Answer {
switch v := rr.(type) {
case *dns.A:
ips = append(ips, v.A)
case *dns.AAAA:
ips = append(ips, v.AAAA)
}
}
if len(ips) == 0 {
return false // we expected an empty IP
}
for _, ip := range ips {
if ip.To4() != nil {
if !ip.Equal(net.IPv4zero) {
return false
}
} else {
if !ip.To16().Equal(net.IPv6zero) {
return false
}
}
}
return true
case BlockDetectionEmptyAnswer:
return answer.Rcode == dns.RcodeNameError && len(answer.Ns) == 0 && len(answer.Answer) == 0 && len(answer.Extra) == 0
}
return false
}