diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a686982..a0cf3821 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ NOTE: Add new changes BELOW THIS COMMENT. ### Fixed +- The ability to apply an invalid configuration for private RDNS, which led to + server inoperability. - Ignoring query log for clients with ClientID set ([#5812]). - Subdomains of `in-addr.arpa` and `ip6.arpa` containing zero-length prefix incorrectly considered invalid when specified for private RDNS upstream diff --git a/internal/dnsforward/http.go b/internal/dnsforward/http.go index 1a1a7b31..01fe6720 100644 --- a/internal/dnsforward/http.go +++ b/internal/dnsforward/http.go @@ -1,6 +1,7 @@ package dnsforward import ( + "cmp" "encoding/json" "fmt" "io" @@ -332,6 +333,28 @@ func (req *jsonDNSConfig) checkBootstrap() (err error) { return nil } +// checkPrivateRDNS returns an error if the configuration of the private RDNS is +// not valid. +func (req *jsonDNSConfig) checkPrivateRDNS( + ownAddrs addrPortSet, + sysResolvers SystemResolvers, + privateNets netutil.SubnetSet, +) (err error) { + if (req.UsePrivateRDNS == nil || !*req.UsePrivateRDNS) && req.LocalPTRUpstreams == nil { + return nil + } + + addrs := cmp.Or(req.LocalPTRUpstreams, &[]string{}) + + uc, err := newPrivateConfig(*addrs, ownAddrs, sysResolvers, privateNets, &upstream.Options{}) + err = errors.WithDeferred(err, uc.Close()) + if err != nil { + return fmt.Errorf("private upstream servers: %w", err) + } + + return nil +} + // validateUpstreamDNSServers returns an error if any field of req is invalid. func (req *jsonDNSConfig) validateUpstreamDNSServers( ownAddrs addrPortSet, @@ -349,12 +372,10 @@ func (req *jsonDNSConfig) validateUpstreamDNSServers( } } - if addrs := req.LocalPTRUpstreams; addrs != nil { - uc, err = newPrivateConfig(*addrs, ownAddrs, sysResolvers, privateNets, opts) - err = errors.WithDeferred(err, uc.Close()) - if err != nil { - return fmt.Errorf("private upstream servers: %w", err) - } + err = req.checkPrivateRDNS(ownAddrs, sysResolvers, privateNets) + if err != nil { + // Don't wrap the error since it's informative enough as is. + return err } err = req.checkBootstrap() @@ -440,7 +461,7 @@ func (s *Server) handleSetConfig(w http.ResponseWriter, r *http.Request) { // TODO(e.burkov): Consider prebuilding this set on startup. ourAddrs, err := s.conf.ourAddrsSet() if err != nil { - // TODO(e.burkov): !! Put into openapi + // TODO(e.burkov): Put into openapi aghhttp.Error(r, w, http.StatusInternalServerError, "getting our addresses: %s", err) return