mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-05-27 12:52:27 +02:00
all: rework fetching/generating config in cd mode
Config fetching/generating in cd mode is currently weird, error prone, and easy for user to break ctrld when using custom config. This commit reworks the flow: - Fetching config from Control D API. - No custom config, use the current default config. - If custom config presents, but there's no listener, use 0.0.0.0:53. - Try listening on current ip+port config, if ok, ctrld could be a direct listener with current setup, moving on. - If failed, trying 127.0.0.1:53. - If failed, trying current ip + port 5354 - If still failed, pick a random ip:port pair, retry until listening ok. With this flow, thing is more predictable/stable, and help removing the Config interface for router.
This commit is contained in:
committed by
Cuong Manh Le
parent
3f3c1d6d78
commit
7af59ee589
+1
-1
@@ -267,5 +267,5 @@ func (m *nmManager) Close() error {
|
||||
}
|
||||
|
||||
func (m *nmManager) Mode() string {
|
||||
return "network-maanger"
|
||||
return "network-manager"
|
||||
}
|
||||
|
||||
@@ -57,12 +57,6 @@ func (d *Ddwrt) PreRun() error {
|
||||
return ntp.Wait()
|
||||
}
|
||||
|
||||
func (d *Ddwrt) Configure() error {
|
||||
d.cfg.Listener["0"].IP = "127.0.0.1"
|
||||
d.cfg.Listener["0"].Port = 5354
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Ddwrt) Setup() error {
|
||||
// Already setup.
|
||||
if val, _ := nvram.Run("get", nvram.CtrldSetupKey); val == "1" {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dnsmasq
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"html/template"
|
||||
"net"
|
||||
"path/filepath"
|
||||
@@ -60,15 +61,20 @@ type Upstream struct {
|
||||
}
|
||||
|
||||
func ConfTmpl(tmplText string, cfg *ctrld.Config) (string, error) {
|
||||
upstreams := make([]Upstream, 0, len(cfg.Listener))
|
||||
for _, listener := range cfg.Listener {
|
||||
upstreams = append(upstreams, Upstream{Ip: listener.IP, Port: listener.Port})
|
||||
listener := cfg.FirstListener()
|
||||
if listener == nil {
|
||||
return "", errors.New("missing listener")
|
||||
}
|
||||
ip := listener.IP
|
||||
if ip == "0.0.0.0" || ip == "::" || ip == "" {
|
||||
ip = "127.0.0.1"
|
||||
}
|
||||
upstreams := []Upstream{{Ip: ip, Port: listener.Port}}
|
||||
return confTmpl(tmplText, upstreams, cfg.HasUpstreamSendClientInfo())
|
||||
}
|
||||
|
||||
func FirewallaConfTmpl(tmplText string, cfg *ctrld.Config) (string, error) {
|
||||
if lc := cfg.Listener["0"]; lc != nil && lc.IP == "0.0.0.0" {
|
||||
if lc := cfg.FirstListener(); lc != nil && (lc.IP == "0.0.0.0" || lc.IP == "") {
|
||||
return confTmpl(tmplText, firewallaUpstreams(lc.Port), cfg.HasUpstreamSendClientInfo())
|
||||
}
|
||||
return ConfTmpl(tmplText, cfg)
|
||||
|
||||
@@ -4,10 +4,6 @@ import "github.com/kardianos/service"
|
||||
|
||||
type dummy struct{}
|
||||
|
||||
func NewDummyRouter() Router {
|
||||
return &dummy{}
|
||||
}
|
||||
|
||||
func (d *dummy) ConfigureService(_ *service.Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -61,12 +61,6 @@ func (e *EdgeOS) PreRun() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *EdgeOS) Configure() error {
|
||||
e.cfg.Listener["0"].IP = "127.0.0.1"
|
||||
e.cfg.Listener["0"].Port = 5354
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *EdgeOS) Setup() error {
|
||||
if e.isUSG {
|
||||
return e.setupUSG()
|
||||
|
||||
@@ -53,12 +53,6 @@ func (f *Firewalla) PreRun() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Firewalla) Configure() error {
|
||||
f.cfg.Listener["0"].IP = "0.0.0.0"
|
||||
f.cfg.Listener["0"].Port = 5354
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Firewalla) Setup() error {
|
||||
data, err := dnsmasq.FirewallaConfTmpl(dnsmasq.ConfigContentTmpl, f.cfg)
|
||||
if err != nil {
|
||||
|
||||
@@ -48,12 +48,6 @@ func (m *Merlin) PreRun() error {
|
||||
return ntp.Wait()
|
||||
}
|
||||
|
||||
func (m *Merlin) Configure() error {
|
||||
m.cfg.Listener["0"].IP = "127.0.0.1"
|
||||
m.cfg.Listener["0"].Port = 5354
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Merlin) Setup() error {
|
||||
buf, err := os.ReadFile(dnsmasq.MerlinPostConfPath)
|
||||
// Already setup.
|
||||
|
||||
@@ -48,12 +48,6 @@ func (o *Openwrt) PreRun() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Openwrt) Configure() error {
|
||||
o.cfg.Listener["0"].IP = "127.0.0.1"
|
||||
o.cfg.Listener["0"].Port = 5354
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Openwrt) Setup() error {
|
||||
// Delete dnsmasq port if set.
|
||||
if _, err := uci("delete", "dhcp.@dnsmasq[0].port"); err != nil && !errors.Is(err, errUCIEntryNotFound) {
|
||||
|
||||
@@ -54,6 +54,14 @@ func (p *Pfsense) ConfigureService(svc *service.Config) error {
|
||||
}
|
||||
|
||||
func (p *Pfsense) Install(config *service.Config) error {
|
||||
// pfsense need ".sh" extension for script to be run at boot.
|
||||
// See: https://docs.netgate.com/pfsense/en/latest/development/boot-commands.html#shell-script-option
|
||||
oldname := filepath.Join(rcPath, p.svcName)
|
||||
newname := filepath.Join(rcPath, p.svcName+".sh")
|
||||
_ = os.Remove(newname)
|
||||
if err := os.Symlink(oldname, newname); err != nil {
|
||||
return fmt.Errorf("os.Symlink: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -62,16 +70,7 @@ func (p *Pfsense) Uninstall(config *service.Config) error {
|
||||
}
|
||||
|
||||
func (p *Pfsense) PreRun() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Pfsense) Configure() error {
|
||||
p.cfg.Listener["0"].IP = "127.0.0.1"
|
||||
p.cfg.Listener["0"].Port = 53
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Pfsense) Setup() error {
|
||||
// TODO: remove this hacky solution.
|
||||
// If Pfsense is in DNS Resolver mode, ensure no unbound processes running.
|
||||
_ = exec.Command("killall", "unbound").Run()
|
||||
|
||||
@@ -80,6 +79,10 @@ func (p *Pfsense) Setup() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Pfsense) Setup() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Pfsense) Cleanup() error {
|
||||
if err := os.Remove(filepath.Join(rcPath, p.svcName+".sh")); err != nil {
|
||||
return fmt.Errorf("os.Remove: %w", err)
|
||||
|
||||
@@ -27,15 +27,9 @@ type Service interface {
|
||||
Uninstall(*service.Config) error
|
||||
}
|
||||
|
||||
// Config is the interface to manage ctrld config on router.
|
||||
type Config interface {
|
||||
Configure() error
|
||||
}
|
||||
|
||||
// Router is the interface for managing ctrld running on router.
|
||||
type Router interface {
|
||||
Service
|
||||
Config
|
||||
|
||||
PreRun() error
|
||||
Setup() error
|
||||
@@ -64,7 +58,7 @@ func New(cfg *ctrld.Config) Router {
|
||||
case firewalla.Name:
|
||||
return firewalla.New(cfg)
|
||||
}
|
||||
return NewDummyRouter()
|
||||
return &dummy{}
|
||||
}
|
||||
|
||||
// IsGLiNet reports whether the router is an GL.iNet router.
|
||||
@@ -94,38 +88,6 @@ type router struct {
|
||||
sendClientInfo bool
|
||||
}
|
||||
|
||||
// IsSupported reports whether the given platform is supported by ctrld.
|
||||
func IsSupported(platform string) bool {
|
||||
switch platform {
|
||||
case ddwrt.Name,
|
||||
edgeos.Name,
|
||||
firewalla.Name,
|
||||
merlin.Name,
|
||||
openwrt.Name,
|
||||
pfsense.Name,
|
||||
synology.Name,
|
||||
tomato.Name,
|
||||
ubios.Name:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SupportedPlatforms return all platforms that can be configured to run with ctrld.
|
||||
func SupportedPlatforms() []string {
|
||||
return []string{
|
||||
ddwrt.Name,
|
||||
edgeos.Name,
|
||||
firewalla.Name,
|
||||
merlin.Name,
|
||||
openwrt.Name,
|
||||
pfsense.Name,
|
||||
synology.Name,
|
||||
tomato.Name,
|
||||
ubios.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns name of the router platform.
|
||||
func Name() string {
|
||||
if r := routerPlatform.Load(); r != nil {
|
||||
|
||||
@@ -43,12 +43,6 @@ func (s *Synology) PreRun() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Synology) Configure() error {
|
||||
s.cfg.Listener["0"].IP = "127.0.0.1"
|
||||
s.cfg.Listener["0"].Port = 5354
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Synology) Setup() error {
|
||||
data, err := dnsmasq.ConfTmpl(dnsmasq.ConfigContentTmpl, s.cfg)
|
||||
if err != nil {
|
||||
|
||||
@@ -52,12 +52,6 @@ func (f *FreshTomato) PreRun() error {
|
||||
return ntp.Wait()
|
||||
}
|
||||
|
||||
func (f *FreshTomato) Configure() error {
|
||||
f.cfg.Listener["0"].IP = "127.0.0.1"
|
||||
f.cfg.Listener["0"].Port = 5354
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FreshTomato) Setup() error {
|
||||
// Already setup.
|
||||
if val, _ := nvram.Run("get", nvram.CtrldSetupKey); val == "1" {
|
||||
|
||||
@@ -46,12 +46,6 @@ func (u *Ubios) PreRun() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *Ubios) Configure() error {
|
||||
u.cfg.Listener["0"].IP = "127.0.0.1"
|
||||
u.cfg.Listener["0"].Port = 5354
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *Ubios) Setup() error {
|
||||
data, err := dnsmasq.ConfTmpl(dnsmasq.ConfigContentTmpl, u.cfg)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user