all: update handling of local config

For local config, we don't want to alter what user explicitly set, and
only try filling in missing value.

While at it, also remove the dnsmasq port delete on openwrt, we don't
need that hack anymore.
This commit is contained in:
Cuong Manh Le
2023-07-11 18:23:09 +07:00
committed by Cuong Manh Le
parent a4edf266f0
commit dc61fd2554
3 changed files with 87 additions and 18 deletions
+86 -12
View File
@@ -996,7 +996,13 @@ func selfCheckStatus(status service.Status, domain string) service.Status {
lcChanged map[string]*ctrld.ListenerConfig lcChanged map[string]*ctrld.ListenerConfig
mu sync.Mutex mu sync.Mutex
) )
curCfg := cfg
if err := v.ReadInConfig(); err != nil {
mainLog.Fatal().Err(err).Msg("failed to read new config")
}
if err := v.Unmarshal(&cfg); err != nil {
mainLog.Fatal().Err(err).Msg("failed to update new config")
}
watcher, err := fsnotify.NewWatcher() watcher, err := fsnotify.NewWatcher()
if err != nil { if err != nil {
mainLog.Error().Err(err).Msg("could not watch config change") mainLog.Error().Err(err).Msg("could not watch config change")
@@ -1016,10 +1022,10 @@ func selfCheckStatus(status service.Status, domain string) service.Status {
for i := 0; i < maxAttempts; i++ { for i := 0; i < maxAttempts; i++ {
mu.Lock() mu.Lock()
if lcChanged != nil { if lcChanged != nil {
curCfg.Listener = lcChanged cfg.Listener = lcChanged
} }
mu.Unlock() mu.Unlock()
lc := curCfg.FirstListener() lc := cfg.FirstListener()
m := new(dns.Msg) m := new(dns.Msg)
m.SetQuestion(domain+".", dns.TypeA) m.SetQuestion(domain+".", dns.TypeA)
@@ -1183,16 +1189,31 @@ func shouldAllocateLoopbackIP(ipStr string) bool {
return ip.IsLoopback() && ip.String() != "127.0.0.1" return ip.IsLoopback() && ip.String() != "127.0.0.1"
} }
type listenerConfigCheck struct {
IP bool
Port bool
}
// updateListenerConfig updates the config for listeners if not defined, // updateListenerConfig updates the config for listeners if not defined,
// or defined but invalid to be used, e.g: using loopback address other // or defined but invalid to be used, e.g: using loopback address other
// than 127.0.0.1 with sytemd-resolved. // than 127.0.0.1 with sytemd-resolved.
func updateListenerConfig() { func updateListenerConfig() {
for _, listener := range cfg.Listener { lcc := make(map[string]*listenerConfigCheck)
cdMode := cdUID != ""
for n, listener := range cfg.Listener {
lcc[n] = &listenerConfigCheck{}
if listener.IP == "" { if listener.IP == "" {
listener.IP = "0.0.0.0" listener.IP = "0.0.0.0"
lcc[n].IP = true
} }
if listener.Port == 0 { if listener.Port == 0 {
listener.Port = 53 listener.Port = 53
lcc[n].Port = true
}
// In cd mode, we always try to pick an ip:port pair to work.
if cdMode {
lcc[n].IP = true
lcc[n].Port = true
} }
} }
@@ -1229,7 +1250,10 @@ func updateListenerConfig() {
for _, n := range listeners { for _, n := range listeners {
listener := cfg.Listener[strconv.Itoa(n)] listener := cfg.Listener[strconv.Itoa(n)]
check := lcc[strconv.Itoa(n)]
oldIP := listener.IP oldIP := listener.IP
oldPort := listener.Port
// Check if we could listen on the current IP + Port, if not, try following thing, pick first one success: // Check if we could listen on the current IP + Port, if not, try following thing, pick first one success:
// - Try 127.0.0.1:53 // - Try 127.0.0.1:53
// - Pick a random port until success. // - Pick a random port until success.
@@ -1243,6 +1267,8 @@ func updateListenerConfig() {
// On firewalla, we don't need to check localhost, because the lo interface is excluded in dnsmasq // On firewalla, we don't need to check localhost, because the lo interface is excluded in dnsmasq
// config, so we can always listen on localhost port 53, but no traffic could be routed there. // config, so we can always listen on localhost port 53, but no traffic could be routed there.
tryLocalhost := !isLoopback(listener.IP) && router.Name() != firewalla.Name tryLocalhost := !isLoopback(listener.IP) && router.Name() != firewalla.Name
tryAllPort53 := true
tryOldIPPort5354 := true
tryPort5354 := true tryPort5354 := true
attempts := 0 attempts := 0
maxAttempts := 10 maxAttempts := 10
@@ -1254,22 +1280,70 @@ func updateListenerConfig() {
if listenOk(addr) { if listenOk(addr) {
break break
} }
if !check.IP && !check.Port {
mainLog.Fatal().Msgf("failed to listen on: %s", addr)
}
if tryAllPort53 {
tryAllPort53 = false
if check.IP {
listener.IP = "0.0.0.0"
}
if check.Port {
listener.Port = 53
}
if check.IP {
mainLog.Warn().Msgf("could not listen on address: %s, trying: %s", addr, net.JoinHostPort(listener.IP, strconv.Itoa(listener.Port)))
}
continue
}
if tryLocalhost { if tryLocalhost {
tryLocalhost = false tryLocalhost = false
listener.IP = localhostIP(listener.IP) if check.IP {
listener.Port = 53 listener.IP = localhostIP(listener.IP)
mainLog.Warn().Msgf("could not listen on address: %s, trying localhost: %s", addr, net.JoinHostPort(listener.IP, strconv.Itoa(listener.Port))) }
if check.Port {
listener.Port = 53
}
if check.IP {
mainLog.Warn().Msgf("could not listen on address: %s, trying localhost: %s", addr, net.JoinHostPort(listener.IP, strconv.Itoa(listener.Port)))
}
continue
}
if tryOldIPPort5354 {
tryOldIPPort5354 = false
if check.IP {
listener.IP = oldIP
}
if check.Port {
listener.Port = 5354
}
mainLog.Warn().Msgf("could not listen on address: %s, trying current ip with port 5354", addr)
continue continue
} }
if tryPort5354 { if tryPort5354 {
tryPort5354 = false tryPort5354 = false
listener.IP = oldIP if check.IP {
listener.Port = 5354 listener.IP = "0.0.0.0"
mainLog.Warn().Msgf("could not listen on address: %s, trying port 5354", addr) }
if check.Port {
listener.Port = 5354
}
mainLog.Warn().Msgf("could not listen on address: %s, trying 0.0.0.0:5354", addr)
continue continue
} }
listener.IP = randomLocalIP() if check.IP {
listener.Port = randomPort() listener.IP = randomLocalIP()
} else {
listener.IP = oldIP
}
if check.Port {
listener.Port = randomPort()
} else {
listener.Port = oldPort
}
if listener.IP == oldIP && listener.Port == oldPort {
mainLog.Fatal().Msgf("could not listener on: %s", net.JoinHostPort(listener.IP, strconv.Itoa(listener.Port)))
}
mainLog.Warn().Msgf("could not listen on address: %s, pick a random ip+port", addr) mainLog.Warn().Msgf("could not listen on address: %s, pick a random ip+port", addr)
attempts++ attempts++
} }
+1 -1
View File
@@ -264,7 +264,7 @@ func (p *prog) setDNS() {
logger.Warn().Msgf("using %s interface IP address as DNS server", ifaceName) logger.Warn().Msgf("using %s interface IP address as DNS server", ifaceName)
} }
} }
logger.Warn().Msg("ctrld is not running on port 53, use interface %s IP as DNS server") logger.Warn().Msgf("ctrld is not running on port 53, use interface %s IP as DNS server", ifaceName)
netIface, err := net.InterfaceByName(ifaceName) netIface, err := net.InterfaceByName(ifaceName)
if err != nil { if err != nil {
mainLog.Fatal().Err(err).Msg("failed to get default route interface") mainLog.Fatal().Err(err).Msg("failed to get default route interface")
-5
View File
@@ -49,11 +49,6 @@ func (o *Openwrt) PreRun() error {
} }
func (o *Openwrt) Setup() error { func (o *Openwrt) Setup() error {
// Delete dnsmasq port if set.
if _, err := uci("delete", "dhcp.@dnsmasq[0].port"); err != nil && !errors.Is(err, errUCIEntryNotFound) {
return err
}
data, err := dnsmasq.ConfTmpl(dnsmasq.ConfigContentTmpl, o.cfg) data, err := dnsmasq.ConfTmpl(dnsmasq.ConfigContentTmpl, o.cfg)
if err != nil { if err != nil {
return err return err