From 9feeba5c7f24ff1d308a216608d985cb2a7b7588 Mon Sep 17 00:00:00 2001 From: Eugene Burkov Date: Thu, 4 Apr 2024 20:25:57 +0300 Subject: [PATCH] all: imp code, docs --- internal/dnsforward/dnsforward.go | 22 ++++++++++++++++++++-- internal/dnsforward/process.go | 2 -- internal/home/dns.go | 9 +++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/internal/dnsforward/dnsforward.go b/internal/dnsforward/dnsforward.go index 9d7e3693..6776b6e8 100644 --- a/internal/dnsforward/dnsforward.go +++ b/internal/dnsforward/dnsforward.go @@ -345,7 +345,7 @@ func (s *Server) Exchange(ip netip.Addr) (host string, ttl time.Duration, err er s.serverLock.RLock() defer s.serverLock.RUnlock() - // TODO(e.burkov): Migrate to netip.Addr already. + // TODO(e.burkov): Migrate to [netip.Addr] already. arpa, err := netutil.IPToReversedAddr(ip.AsSlice()) if err != nil { return "", 0, fmt.Errorf("reversing ip: %w", err) @@ -366,7 +366,7 @@ func (s *Server) Exchange(ip netip.Addr) (host string, ttl time.Duration, err er } dctx := &proxy.DNSContext{ - Proto: "udp", + Proto: proxy.ProtoUDP, Req: req, IsPrivateClient: true, } @@ -451,6 +451,15 @@ func (s *Server) startLocked() error { return err } +// ErrBadPrivateRDNSUpstreams is returned when the private rDNS upstreams are +// invalid but enabled. +// +// TODO(e.burkov): Consider allowing to use incomplete private rDNS upstreams +// configuration in proxy when the private rDNS function is enabled. In theory, +// proxy supports the case when no upstreams provided to resolve the private +// request, since it already supports this for DNS64-prefixed PTR requests. +const ErrBadPrivateRDNSUpstreams errors.Error = "bad private rDNS upstreams" + // prepareLocalResolvers initializes the local upstreams configuration using // boot as bootstrap. It assumes that s.serverLock is locked or s not running. func (s *Server) prepareLocalResolvers( @@ -493,6 +502,15 @@ func (s *Server) prepareLocalResolvers( } } + // Prevalidate the config to catch the exact error before creating proxy. + // See TODO on [ErrBadPrivateRDNSUpstreams]. + err = proxy.ValidatePrivateConfig(uc, s.privateNets) + if err != nil { + log.Debug("dnsforward: validating private rdns upstreams: %s", err) + + return nil, ErrBadPrivateRDNSUpstreams + } + return uc, nil } diff --git a/internal/dnsforward/process.go b/internal/dnsforward/process.go index 93c9ec0f..c3d3254e 100644 --- a/internal/dnsforward/process.go +++ b/internal/dnsforward/process.go @@ -420,8 +420,6 @@ func (s *Server) processFilteringBeforeRequest(dctx *dnsContext) (rc resultCode) if dctx.proxyCtx.RequestedPrivateRDNS != (netip.Prefix{}) { // There is no need to filter request for locally served ARPA hostname // so disable redundant filters. - // - // TODO(e.burkov): !! check the above comment. dctx.setts.ParentalEnabled = false dctx.setts.SafeBrowsingEnabled = false dctx.setts.SafeSearchEnabled = false diff --git a/internal/home/dns.go b/internal/home/dns.go index a1f841b7..5a23e357 100644 --- a/internal/home/dns.go +++ b/internal/home/dns.go @@ -156,7 +156,16 @@ func initDNSServer( return fmt.Errorf("newServerConfig: %w", err) } + // Try to prepare the server with disabled private RDNS resolution if it + // failed to prepare as is. See TODO on [ErrBadPrivateRDNSUpstreams]. err = Context.dnsServer.Prepare(dnsConf) + if errors.Is(err, dnsforward.ErrBadPrivateRDNSUpstreams) { + log.Info("WARNING: no local resolvers configured while private RDNS " + + "resolution enabled, trying to disable") + dnsConf.UsePrivateRDNS = false + err = Context.dnsServer.Prepare(dnsConf) + } + if err != nil { return fmt.Errorf("dnsServer.Prepare: %w", err) }