diff --git a/internal/router/dnsmasq/dnsmasq.go b/internal/router/dnsmasq/dnsmasq.go index 9fab8b6..50c7d0e 100644 --- a/internal/router/dnsmasq/dnsmasq.go +++ b/internal/router/dnsmasq/dnsmasq.go @@ -1,12 +1,9 @@ package dnsmasq import ( - "bytes" "errors" - "fmt" "html/template" "net" - "os" "path/filepath" "strings" @@ -24,6 +21,8 @@ add-subnet=32,128 {{- end}} {{- if .CacheDisabled}} cache-size=0 +{{- else}} +max-cache-ttl=0 {{- end}} ` @@ -72,11 +71,18 @@ type Upstream struct { Port int } +// ConfTmpl generates dnsmasq configuration from ctrld config. func ConfTmpl(tmplText string, cfg *ctrld.Config) (string, error) { - return ConfTmplWitchCacheDisabled(tmplText, cfg, true) + return ConfTmplWithCacheDisabled(tmplText, cfg, true) } -func ConfTmplWitchCacheDisabled(tmplText string, cfg *ctrld.Config, cacheDisabled bool) (string, error) { +// ConfTmplWithCacheDisabled is like ConfTmpl, but the caller can control whether +// dnsmasq cache is disabled using cacheDisabled parameter. +// +// Generally, the caller should use ConfTmpl, but on some routers which dnsmasq config may be changed +// after ctrld started (like EdgeOS/Ubios, Firewalla ...), dnsmasq cache should not be disabled because +// the cache-size=0 generated by ctrld will conflict with router's generated config. +func ConfTmplWithCacheDisabled(tmplText string, cfg *ctrld.Config, cacheDisabled bool) (string, error) { listener := cfg.FirstListener() if listener == nil { return "", errors.New("missing listener") @@ -89,11 +95,14 @@ func ConfTmplWitchCacheDisabled(tmplText string, cfg *ctrld.Config, cacheDisable return confTmpl(tmplText, upstreams, cfg.HasUpstreamSendClientInfo(), cacheDisabled) } +// FirewallaConfTmpl generates dnsmasq config for Firewalla routers. func FirewallaConfTmpl(tmplText string, cfg *ctrld.Config) (string, error) { + // If ctrld listen on all interfaces, generating config for all of them. if lc := cfg.FirstListener(); lc != nil && (lc.IP == "0.0.0.0" || lc.IP == "") { - return confTmpl(tmplText, firewallaUpstreams(lc.Port), cfg.HasUpstreamSendClientInfo(), true) + return confTmpl(tmplText, firewallaUpstreams(lc.Port), cfg.HasUpstreamSendClientInfo(), false) } - return ConfTmpl(tmplText, cfg) + // Otherwise, generating config for the specific listener from ctrld's config. + return ConfTmplWithCacheDisabled(tmplText, cfg, false) } func confTmpl(tmplText string, upstreams []Upstream, sendClientInfo, cacheDisabled bool) (string, error) { @@ -136,20 +145,6 @@ func firewallaDnsmasqConfFiles() ([]string, error) { return filepath.Glob("/home/pi/firerouter/etc/dnsmasq.dns.*.conf") } -// firewallUpdateConf updates all firewall config files using given function. -func firewallUpdateConf(update func(conf string) error) error { - confFiles, err := firewallaDnsmasqConfFiles() - if err != nil { - return err - } - for _, conf := range confFiles { - if err := update(conf); err != nil { - return fmt.Errorf("%s: %w", conf, err) - } - } - return nil -} - // FirewallaSelfInterfaces returns list of interfaces that will be configured with default dnsmasq setup on Firewalla. func FirewallaSelfInterfaces() []*net.Interface { matches, err := firewallaDnsmasqConfFiles() @@ -166,32 +161,3 @@ func FirewallaSelfInterfaces() []*net.Interface { } return ifaces } - -// FirewallaDisableCache comments out "cache-size" line in all firewalla dnsmasq config files. -func FirewallaDisableCache() error { - return firewallUpdateConf(DisableCache) -} - -// FirewallaEnableCache un-comments out "cache-size" line in all firewalla dnsmasq config files. -func FirewallaEnableCache() error { - return firewallUpdateConf(EnableCache) -} - -// DisableCache comments out "cache-size" line in dnsmasq config file. -func DisableCache(conf string) error { - return replaceFileContent(conf, "\ncache-size=", "\n#cache-size=") -} - -// EnableCache un-comments "cache-size" line in dnsmasq config file. -func EnableCache(conf string) error { - return replaceFileContent(conf, "\n#cache-size=", "\ncache-size=") -} - -func replaceFileContent(filename, old, new string) error { - content, err := os.ReadFile(filename) - if err != nil { - return err - } - content = bytes.ReplaceAll(content, []byte(old), []byte(new)) - return os.WriteFile(filename, content, 0644) -} diff --git a/internal/router/edgeos/edgeos.go b/internal/router/edgeos/edgeos.go index 3e7003b..df7b57b 100644 --- a/internal/router/edgeos/edgeos.go +++ b/internal/router/edgeos/edgeos.go @@ -109,7 +109,7 @@ func (e *EdgeOS) setupUSG() error { sb.WriteString(line) } - data, err := dnsmasq.ConfTmplWitchCacheDisabled(dnsmasq.ConfigContentTmpl, e.cfg, false) + data, err := dnsmasq.ConfTmplWithCacheDisabled(dnsmasq.ConfigContentTmpl, e.cfg, false) if err != nil { return err } @@ -127,7 +127,7 @@ func (e *EdgeOS) setupUSG() error { } func (e *EdgeOS) setupUDM() error { - data, err := dnsmasq.ConfTmplWitchCacheDisabled(dnsmasq.ConfigContentTmpl, e.cfg, false) + data, err := dnsmasq.ConfTmplWithCacheDisabled(dnsmasq.ConfigContentTmpl, e.cfg, false) if err != nil { return err } diff --git a/internal/router/firewalla/firewalla.go b/internal/router/firewalla/firewalla.go index 66cd15e..cdf6586 100644 --- a/internal/router/firewalla/firewalla.go +++ b/internal/router/firewalla/firewalla.go @@ -65,11 +65,6 @@ func (f *Firewalla) Setup() error { return fmt.Errorf("writing ctrld config: %w", err) } - // Disable dnsmasq cache. - if err := dnsmasq.FirewallaDisableCache(); err != nil { - return err - } - // Restart dnsmasq service. if err := restartDNSMasq(); err != nil { return fmt.Errorf("restartDNSMasq: %w", err) @@ -87,11 +82,6 @@ func (f *Firewalla) Cleanup() error { return fmt.Errorf("removing ctrld config: %w", err) } - // Enable dnsmasq cache. - if err := dnsmasq.FirewallaEnableCache(); err != nil { - return err - } - // Restart dnsmasq service. if err := restartDNSMasq(); err != nil { return fmt.Errorf("restartDNSMasq: %w", err) diff --git a/internal/router/ubios/ubios.go b/internal/router/ubios/ubios.go index 32c7576..6513657 100644 --- a/internal/router/ubios/ubios.go +++ b/internal/router/ubios/ubios.go @@ -51,17 +51,13 @@ func (u *Ubios) Setup() error { if u.cfg.FirstListener().IsDirectDnsListener() { return nil } - data, err := dnsmasq.ConfTmpl(dnsmasq.ConfigContentTmpl, u.cfg) + data, err := dnsmasq.ConfTmplWithCacheDisabled(dnsmasq.ConfigContentTmpl, u.cfg, false) if err != nil { return err } if err := os.WriteFile(ubiosDNSMasqConfigPath, []byte(data), 0600); err != nil { return err } - // Disable dnsmasq cache. - if err := dnsmasq.DisableCache(ubiosDNSMasqDnsConfigPath); err != nil { - return err - } // Restart dnsmasq service. if err := restartDNSMasq(); err != nil { return err @@ -77,10 +73,6 @@ func (u *Ubios) Cleanup() error { if err := os.Remove(ubiosDNSMasqConfigPath); err != nil { return err } - // Enable dnsmasq cache. - if err := dnsmasq.EnableCache(ubiosDNSMasqDnsConfigPath); err != nil { - return err - } // Restart dnsmasq service. if err := restartDNSMasq(); err != nil { return err