Pull request: 3185 detecting recursion

Merge in DNS/adguard-home from 3185-recursion to master

Closes #3185.

Squashed commit of the following:

commit 2fa44223f533c471f2b8c0e17d8550bf4ff73c7b
Merge: 7975957c 7a48e92e
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu May 27 19:04:44 2021 +0300

    Merge branch 'master' into 3185-recursion

commit 7975957cceb840f76eef0e2e434f4163a122ac34
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu May 27 17:36:22 2021 +0300

    dnsforward: imp docs

commit 1af7131a5b7c1fefed2d1eb8ee24ebfd3602dc77
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu May 27 17:15:00 2021 +0300

    dnsforward: imp code, tests, docs

commit f3f9145fb5e1174fab87ca6890da9df722cfebf0
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu May 27 15:45:44 2021 +0300

    dnsforward: add recursion detector
This commit is contained in:
Eugene Burkov
2021-05-27 19:19:19 +03:00
parent 7a48e92e4d
commit 48b8579703
6 changed files with 324 additions and 23 deletions

View File

@@ -82,6 +82,7 @@ func (s *Server) handleDNSRequest(_ *proxy.Proxy, d *proxy.DNSContext) error {
// (*proxy.Proxy).handleDNSRequest method performs it before calling the
// appropriate handler.
mods := []modProcessFunc{
s.processRecursion,
processInitial,
s.processDetermineLocal,
s.processInternalHosts,
@@ -90,7 +91,7 @@ func (s *Server) handleDNSRequest(_ *proxy.Proxy, d *proxy.DNSContext) error {
processClientID,
processFilteringBeforeRequest,
s.processLocalPTR,
processUpstream,
s.processUpstream,
processDNSSECAfterResponse,
processFilteringAfterResponse,
s.ipset.process,
@@ -116,6 +117,22 @@ func (s *Server) handleDNSRequest(_ *proxy.Proxy, d *proxy.DNSContext) error {
return nil
}
// processRecursion checks the incoming request and halts it's handling if s
// have tried to resolve it recently.
func (s *Server) processRecursion(dctx *dnsContext) (rc resultCode) {
pctx := dctx.proxyCtx
if msg := pctx.Req; msg != nil && s.recDetector.check(*msg) {
log.Debug("recursion detected resolving %q", msg.Question[0].Name)
pctx.Res = s.genNXDomain(pctx.Req)
return resultCodeFinish
}
return resultCodeSuccess
}
// Perform initial checks; process WHOIS & rDNS
func processInitial(ctx *dnsContext) (rc resultCode) {
s := ctx.srv
@@ -422,6 +439,7 @@ func (s *Server) processLocalPTR(ctx *dnsContext) (rc resultCode) {
}
if s.conf.UsePrivateRDNS {
s.recDetector.add(*d.Req)
if err := s.localResolvers.Resolve(d); err != nil {
ctx.err = err
@@ -472,8 +490,7 @@ func processFilteringBeforeRequest(ctx *dnsContext) (rc resultCode) {
}
// processUpstream passes request to upstream servers and handles the response.
func processUpstream(ctx *dnsContext) (rc resultCode) {
s := ctx.srv
func (s *Server) processUpstream(ctx *dnsContext) (rc resultCode) {
d := ctx.proxyCtx
if d.Res != nil {
return resultCodeSuccess // response is already set - nothing to do
@@ -481,18 +498,18 @@ func processUpstream(ctx *dnsContext) (rc resultCode) {
if d.Addr != nil && s.conf.GetCustomUpstreamByClient != nil {
clientIP := IPStringFromAddr(d.Addr)
upstreamsConf := s.conf.GetCustomUpstreamByClient(clientIP)
if upstreamsConf != nil {
log.Debug("Using custom upstreams for %s", clientIP)
d.CustomUpstreamConfig = upstreamsConf
if upsConf := s.conf.GetCustomUpstreamByClient(clientIP); upsConf != nil {
log.Debug("dns: using custom upstreams for client %s", clientIP)
d.CustomUpstreamConfig = upsConf
}
}
req := d.Req
if s.conf.EnableDNSSEC {
opt := d.Req.IsEdns0()
opt := req.IsEdns0()
if opt == nil {
log.Debug("dns: Adding OPT record with DNSSEC flag")
d.Req.SetEdns0(4096, true)
log.Debug("dns: adding OPT record with DNSSEC flag")
req.SetEdns0(4096, true)
} else if !opt.Do() {
opt.SetDo(true)
} else {
@@ -501,13 +518,13 @@ func processUpstream(ctx *dnsContext) (rc resultCode) {
}
// request was not filtered so let it be processed further
err := s.dnsProxy.Resolve(d)
if err != nil {
ctx.err = err
s.recDetector.add(*req)
if ctx.err = s.dnsProxy.Resolve(d); ctx.err != nil {
return resultCodeError
}
ctx.responseFromUpstream = true
return resultCodeSuccess
}