Pull request: imp-dnsforward-cyclo

Merge in DNS/adguard-home from imp-dnsforward-cyclo to master

Squashed commit of the following:

commit ab05ebbcc62c5f66f838a9df6ce8e51721606bb6
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Sep 6 18:43:18 2022 +0300

    dnsforward: imp cyclo
This commit is contained in:
Ainar Garipov 2022-09-06 19:03:47 +03:00
parent 3c0d2a9253
commit ab02c829ea
2 changed files with 113 additions and 52 deletions

View File

@ -19,16 +19,40 @@ func (s *Server) filterDNSRewriteResponse(
rr rules.RRType, rr rules.RRType,
v rules.RRValue, v rules.RRValue,
) (ans dns.RR, err error) { ) (ans dns.RR, err error) {
// TODO(a.garipov): As more types are added, we will probably want to use a
// handler-oriented approach here. So, think of a way to decouple the
// answer generation logic from the Server.
switch rr { switch rr {
case dns.TypeA, case
dns.TypeA,
dns.TypeAAAA: dns.TypeAAAA:
return s.ansFromDNSRewriteIP(v, rr, req)
case
dns.TypePTR,
dns.TypeTXT:
return s.ansFromDNSRewriteText(v, rr, req)
case dns.TypeMX:
return s.ansFromDNSRewriteMX(v, rr, req)
case
dns.TypeHTTPS,
dns.TypeSVCB:
return s.ansFromDNSRewriteSVCB(v, rr, req)
case dns.TypeSRV:
return s.ansFromDNSRewriteSRV(v, rr, req)
default:
log.Debug("don't know how to handle dns rr type %d, skipping", rr)
return nil, nil
}
}
// ansFromDNSRewriteIP creates a new answer resource record from the A/AAAA
// dnsrewrite rule data.
func (s *Server) ansFromDNSRewriteIP(
v rules.RRValue,
rr rules.RRType,
req *dns.Msg,
) (ans dns.RR, err error) {
ip, ok := v.(net.IP) ip, ok := v.(net.IP)
if !ok { if !ok {
return nil, fmt.Errorf("value for rr type %d has type %T, not net.IP", rr, v) return nil, fmt.Errorf("value for rr type %s has type %T, not net.IP", dns.Type(rr), v)
} }
if rr == dns.TypeA { if rr == dns.TypeA {
@ -36,11 +60,18 @@ func (s *Server) filterDNSRewriteResponse(
} }
return s.genAnswerAAAA(req, ip), nil return s.genAnswerAAAA(req, ip), nil
case dns.TypePTR, }
dns.TypeTXT:
// ansFromDNSRewriteText creates a new answer resource record from the TXT/PTR
// dnsrewrite rule data.
func (s *Server) ansFromDNSRewriteText(
v rules.RRValue,
rr rules.RRType,
req *dns.Msg,
) (ans dns.RR, err error) {
str, ok := v.(string) str, ok := v.(string)
if !ok { if !ok {
return nil, fmt.Errorf("value for rr type %d has type %T, not string", rr, v) return nil, fmt.Errorf("value for rr type %s has type %T, not string", dns.Type(rr), v)
} }
if rr == dns.TypeTXT { if rr == dns.TypeTXT {
@ -48,18 +79,41 @@ func (s *Server) filterDNSRewriteResponse(
} }
return s.genAnswerPTR(req, str), nil return s.genAnswerPTR(req, str), nil
case dns.TypeMX: }
// ansFromDNSRewriteMX creates a new answer resource record from the MX
// dnsrewrite rule data.
func (s *Server) ansFromDNSRewriteMX(
v rules.RRValue,
rr rules.RRType,
req *dns.Msg,
) (ans dns.RR, err error) {
mx, ok := v.(*rules.DNSMX) mx, ok := v.(*rules.DNSMX)
if !ok { if !ok {
return nil, fmt.Errorf("value for rr type %d has type %T, not *rules.DNSMX", rr, v) return nil, fmt.Errorf(
"value for rr type %s has type %T, not *rules.DNSMX",
dns.Type(rr),
v,
)
} }
return s.genAnswerMX(req, mx), nil return s.genAnswerMX(req, mx), nil
case dns.TypeHTTPS, }
dns.TypeSVCB:
// ansFromDNSRewriteSVCB creates a new answer resource record from the
// SVCB/HTTPS dnsrewrite rule data.
func (s *Server) ansFromDNSRewriteSVCB(
v rules.RRValue,
rr rules.RRType,
req *dns.Msg,
) (ans dns.RR, err error) {
svcb, ok := v.(*rules.DNSSVCB) svcb, ok := v.(*rules.DNSSVCB)
if !ok { if !ok {
return nil, fmt.Errorf("value for rr type %d has type %T, not *rules.DNSSVCB", rr, v) return nil, fmt.Errorf(
"value for rr type %s has type %T, not *rules.DNSSVCB",
dns.Type(rr),
v,
)
} }
if rr == dns.TypeHTTPS { if rr == dns.TypeHTTPS {
@ -67,18 +121,25 @@ func (s *Server) filterDNSRewriteResponse(
} }
return s.genAnswerSVCB(req, svcb), nil return s.genAnswerSVCB(req, svcb), nil
case dns.TypeSRV: }
// ansFromDNSRewriteSRV creates a new answer resource record from the SRV
// dnsrewrite rule data.
func (s *Server) ansFromDNSRewriteSRV(
v rules.RRValue,
rr rules.RRType,
req *dns.Msg,
) (dns.RR, error) {
srv, ok := v.(*rules.DNSSRV) srv, ok := v.(*rules.DNSSRV)
if !ok { if !ok {
return nil, fmt.Errorf("value for rr type %d has type %T, not *rules.DNSSRV", rr, v) return nil, fmt.Errorf(
"value for rr type %s has type %T, not *rules.DNSSRV",
dns.Type(rr),
v,
)
} }
return s.genAnswerSRV(req, srv), nil return s.genAnswerSRV(req, srv), nil
default:
log.Debug("don't know how to handle dns rr type %d, skipping", rr)
return nil, nil
}
} }
// filterDNSRewrite handles dnsrewrite filters. It constructs a DNS response // filterDNSRewrite handles dnsrewrite filters. It constructs a DNS response

View File

@ -222,13 +222,13 @@ exit_on_output gofumpt --extra -e -l .
# Apply more lax standards to the code we haven't properly refactored yet. # Apply more lax standards to the code we haven't properly refactored yet.
gocyclo --over 17 ./internal/querylog/ gocyclo --over 17 ./internal/querylog/
gocyclo --over 15 ./internal/home/ ./internal/dhcpd gocyclo --over 15 ./internal/home/ ./internal/dhcpd
gocyclo --over 14 ./internal/dnsforward/
gocyclo --over 13 ./internal/filtering/ gocyclo --over 13 ./internal/filtering/
# Apply stricter standards to new or somewhat refactored code. # Apply stricter standards to new or somewhat refactored code.
gocyclo --over 10 ./internal/aghio/ ./internal/aghnet/ ./internal/aghos/\ gocyclo --over 10 ./internal/aghio/ ./internal/aghnet/ ./internal/aghos/\
./internal/aghtest/ ./internal/stats/ ./internal/tools/\ ./internal/aghtest/ ./internal/dnsforward/ ./internal/stats/\
./internal/updater/ ./internal/v1/ ./internal/version/ ./main.go\ ./internal/tools/ ./internal/updater/ ./internal/v1/ ./internal/version/\
./main.go
ineffassign ./... ineffassign ./...