Pull request: 4890-panic-internal-proxy

Updates #4890.

Squashed commit of the following:

commit 20c8f3348125672403c3968b8e08b15eba69347d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Sep 6 16:55:11 2022 +0300

    dnsforward: imp names

commit 2c21644623c321df46a5c386ec00ca532b7603b6
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Sep 6 16:36:46 2022 +0300

    dnsforward: imp validations; refactor more

commit 221e8c5ebbd0b64e5c554cddb683d116212e5901
Merge: e5f5b76e 58512c3a
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Sep 6 14:57:31 2022 +0300

    Merge branch 'master' into 4890-panic-internal-proxy

commit e5f5b76e3e2b43656af9939a52a9e46e5d9b5a40
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Sep 6 14:51:48 2022 +0300

    dnsforward: fix panic; refactor
This commit is contained in:
Ainar Garipov
2022-09-06 17:09:54 +03:00
parent 58512c3af9
commit 3c0d2a9253
12 changed files with 290 additions and 257 deletions

View File

@@ -434,65 +434,54 @@ func (s *Server) setupResolvers(localAddrs []string) (err error) {
return nil
}
// Prepare the object
func (s *Server) Prepare(config *ServerConfig) error {
// Initialize the server configuration
// --
if config != nil {
s.conf = *config
if s.conf.BlockingMode == "custom_ip" {
if s.conf.BlockingIPv4 == nil || s.conf.BlockingIPv6 == nil {
return fmt.Errorf("dns: invalid custom blocking IP address specified")
}
}
// Prepare initializes parameters of s using data from conf. conf must not be
// nil.
func (s *Server) Prepare(conf *ServerConfig) (err error) {
s.conf = *conf
err = validateBlockingMode(s.conf.BlockingMode, s.conf.BlockingIPv4, s.conf.BlockingIPv6)
if err != nil {
return fmt.Errorf("checking blocking mode: %w", err)
}
// Set default values in the case if nothing is configured
// --
s.initDefaultSettings()
// Initialize ipset configuration
// --
err := s.ipset.init(s.conf.IpsetList)
err = s.ipset.init(s.conf.IpsetList)
if err != nil {
// Don't wrap the error, because it's informative enough as is.
return err
}
log.Debug("inited ipset")
// Prepare DNS servers settings
// --
err = s.prepareUpstreamSettings()
if err != nil {
return err
return fmt.Errorf("preparing upstream settings: %w", err)
}
// Create DNS proxy configuration
// --
var proxyConfig proxy.Config
proxyConfig, err = s.createProxyConfig()
if err != nil {
return err
return fmt.Errorf("preparing proxy: %w", err)
}
// Prepare a DNS proxy instance that we use for internal DNS queries
// --
s.prepareInternalProxy()
s.access, err = newAccessCtx(s.conf.AllowedClients, s.conf.DisallowedClients, s.conf.BlockedHosts)
err = s.prepareInternalProxy()
if err != nil {
return err
return fmt.Errorf("preparing internal proxy: %w", err)
}
s.access, err = newAccessCtx(
s.conf.AllowedClients,
s.conf.DisallowedClients,
s.conf.BlockedHosts,
)
if err != nil {
return fmt.Errorf("preparing access: %w", err)
}
// Register web handlers if necessary
// --
if !webRegistered && s.conf.HTTPRegister != nil {
webRegistered = true
s.registerHandlers()
}
// Create the main DNS proxy instance
// --
s.dnsProxy = &proxy.Proxy{Config: proxyConfig}
err = s.setupResolvers(s.conf.LocalPTRResolvers)
@@ -505,6 +494,61 @@ func (s *Server) Prepare(config *ServerConfig) error {
return nil
}
// validateBlockingMode returns an error if the blocking mode data aren't valid.
func validateBlockingMode(mode BlockingMode, blockingIPv4, blockingIPv6 net.IP) (err error) {
switch mode {
case
BlockingModeDefault,
BlockingModeNXDOMAIN,
BlockingModeREFUSED,
BlockingModeNullIP:
return nil
case BlockingModeCustomIP:
if blockingIPv4 == nil {
return fmt.Errorf("blocking_ipv4 must be set when blocking_mode is custom_ip")
} else if blockingIPv6 == nil {
return fmt.Errorf("blocking_ipv6 must be set when blocking_mode is custom_ip")
}
return nil
default:
return fmt.Errorf("bad blocking mode %q", mode)
}
}
// prepareInternalProxy initializes the DNS proxy that is used for internal DNS
// queries, such at client PTR resolving and updater hostname resolving.
func (s *Server) prepareInternalProxy() (err error) {
conf := &proxy.Config{
CacheEnabled: true,
CacheSizeBytes: 4096,
UpstreamConfig: s.conf.UpstreamConfig,
MaxGoroutines: int(s.conf.MaxGoroutines),
}
srvConf := s.conf
setProxyUpstreamMode(
conf,
srvConf.AllServers,
srvConf.FastestAddr,
srvConf.FastestTimeout.Duration,
)
// TODO(a.garipov): Make a proper constructor for proxy.Proxy.
p := &proxy.Proxy{
Config: *conf,
}
err = p.Init()
if err != nil {
return err
}
s.internalProxy = p
return nil
}
// Stop stops the DNS server.
func (s *Server) Stop() error {
s.serverLock.Lock()
@@ -550,7 +594,7 @@ func (s *Server) proxy() (p *proxy.Proxy) {
}
// Reconfigure applies the new configuration to the DNS server.
func (s *Server) Reconfigure(config *ServerConfig) error {
func (s *Server) Reconfigure(conf *ServerConfig) error {
s.serverLock.Lock()
defer s.serverLock.Unlock()
@@ -564,7 +608,12 @@ func (s *Server) Reconfigure(config *ServerConfig) error {
// We wait for some time and hope that this fd will be closed.
time.Sleep(100 * time.Millisecond)
err = s.Prepare(config)
// TODO(a.garipov): This whole piece of API is weird and needs to be remade.
if conf == nil {
conf = &s.conf
}
err = s.Prepare(conf)
if err != nil {
return fmt.Errorf("could not reconfigure the server: %w", err)
}