mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
internal/router: use max-cache-ttl=0 on some routers
On some routers, dnsmasq config may change cache-size dynamically after ctrld starts, causing dnsmasq crashes. Fixing this by using max-cache-ttl, which have the same effect with setting cache-size=0 but won't conflict with existing routers config.
This commit is contained in:
committed by
Cuong Manh Le
parent
cb445825f4
commit
dc700bbd52
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user