From 43d82cf1a77e9c00c6852ae1f8e1546af542787e Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Thu, 14 Mar 2024 23:53:34 +0700 Subject: [PATCH] cmd/cli,internal/router: detect unbound/dnsmasq status correctly on *BSD Also detect cd mode for stop/uninstall command correctly, too. --- cmd/cli/cli.go | 21 +++++++++++++-- cmd/cli/control_server.go | 8 ++++++ internal/router/os_config_freebsd.go | 40 ++++++++++++++++++++++++++++ internal/router/os_freebsd.go | 12 +++++++-- 4 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 internal/router/os_config_freebsd.go diff --git a/cmd/cli/cli.go b/cmd/cli/cli.go index 289f218..093192a 100644 --- a/cmd/cli/cli.go +++ b/cmd/cli/cli.go @@ -437,7 +437,7 @@ func initCLI() { Run: func(cmd *cobra.Command, args []string) { readConfig(false) v.Unmarshal(&cfg) - p := &prog{router: router.New(&cfg, cdUID != "")} + p := &prog{router: router.New(&cfg, runInCdMode())} s, err := newService(p, svcConfig) if err != nil { mainLog.Load().Error().Msg(err.Error()) @@ -594,7 +594,7 @@ NOTE: Uninstalling will set DNS to values provided by DHCP.`, Run: func(cmd *cobra.Command, args []string) { readConfig(false) v.Unmarshal(&cfg) - p := &prog{router: router.New(&cfg, cdUID != "")} + p := &prog{router: router.New(&cfg, runInCdMode())} s, err := newService(p, svcConfig) if err != nil { mainLog.Load().Error().Msg(err.Error()) @@ -2440,3 +2440,20 @@ func absHomeDir(filename string) string { } return filepath.Join(dir, filename) } + +// runInCdMode reports whether ctrld service is running in cd mode. +func runInCdMode() bool { + if s, _ := newService(&prog{}, svcConfig); s != nil { + if dir, _ := socketDir(); dir != "" { + cc := newSocketControlClient(s, dir) + if cc != nil { + resp, _ := cc.post(cdPath, nil) + if resp != nil { + defer resp.Body.Close() + return resp.StatusCode == http.StatusOK + } + } + } + } + return false +} diff --git a/cmd/cli/control_server.go b/cmd/cli/control_server.go index 28c20a6..4d243bf 100644 --- a/cmd/cli/control_server.go +++ b/cmd/cli/control_server.go @@ -21,6 +21,7 @@ const ( startedPath = "/started" reloadPath = "/reload" deactivationPath = "/deactivation" + cdPath = "/cd" ) type controlServer struct { @@ -171,6 +172,13 @@ func (p *prog) registerControlServerHandler() { } w.WriteHeader(code) })) + p.cs.register(cdPath, http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) { + if cdUID != "" { + w.WriteHeader(http.StatusOK) + return + } + w.WriteHeader(http.StatusBadRequest) + })) } func jsonResponse(next http.Handler) http.Handler { diff --git a/internal/router/os_config_freebsd.go b/internal/router/os_config_freebsd.go new file mode 100644 index 0000000..9066191 --- /dev/null +++ b/internal/router/os_config_freebsd.go @@ -0,0 +1,40 @@ +package router + +import ( + "encoding/xml" + "os" +) + +// Config represents /conf/config.xml file found on pfsense/opnsense. +type Config struct { + PfsenseUnbound *string `xml:"unbound>enable,omitempty"` + OPNsenseUnbound *string `xml:"OPNsense>unboundplus>general>enabled,omitempty"` + Dnsmasq *string `xml:"dnsmasq>enable,omitempty"` +} + +// DnsmasqEnabled reports whether dnsmasq is enabled. +func (c *Config) DnsmasqEnabled() bool { + if isPfsense() { // pfsense only set the attribute if dnsmasq is enabled. + return c.Dnsmasq != nil + } + return c.Dnsmasq != nil && *c.Dnsmasq == "1" +} + +// UnboundEnabled reports whether unbound is enabled. +func (c *Config) UnboundEnabled() bool { + if isPfsense() { // pfsense only set the attribute if unbound is enabled. + return c.PfsenseUnbound != nil + } + return c.OPNsenseUnbound != nil && *c.OPNsenseUnbound == "1" +} + +// currentConfig does unmarshalling /conf/config.xml file, +// return the corresponding *Config represent it. +func currentConfig() (*Config, error) { + buf, _ := os.ReadFile("/conf/config.xml") + c := Config{} + if err := xml.Unmarshal(buf, &c); err != nil { + return nil, err + } + return &c, nil +} diff --git a/internal/router/os_freebsd.go b/internal/router/os_freebsd.go index c38eebc..9a79188 100644 --- a/internal/router/os_freebsd.go +++ b/internal/router/os_freebsd.go @@ -111,8 +111,16 @@ func (or *osRouter) Setup() error { func (or *osRouter) Cleanup() error { if or.cdMode { - _ = exec.Command(unboundRcPath, "onerestart").Run() - _ = exec.Command(dnsmasqRcPath, "onerestart").Run() + c, err := currentConfig() + if err != nil { + return err + } + if c.UnboundEnabled() { + _ = exec.Command(unboundRcPath, "onerestart").Run() + } + if c.DnsmasqEnabled() { + _ = exec.Command(dnsmasqRcPath, "onerestart").Run() + } } return nil }