all: workaround problem with EdgeOS dnsmasq config

This commit is contained in:
Cuong Manh Le
2023-07-11 00:24:54 +07:00
committed by Cuong Manh Le
parent 7af59ee589
commit a4edf266f0
4 changed files with 94 additions and 10 deletions

View File

@@ -16,6 +16,8 @@ import (
"github.com/Control-D-Inc/ctrld/internal/clientinfo"
"github.com/Control-D-Inc/ctrld/internal/dnscache"
"github.com/Control-D-Inc/ctrld/internal/router"
"github.com/Control-D-Inc/ctrld/internal/router/dnsmasq"
"github.com/Control-D-Inc/ctrld/internal/router/edgeos"
"github.com/Control-D-Inc/ctrld/internal/router/firewalla"
)
@@ -243,19 +245,26 @@ func (p *prog) setDNS() {
}
logger.Debug().Msg("setting DNS for interface")
ns := lc.IP
ifaceName := defaultIfaceName()
isFirewalla := router.Name() == firewalla.Name
if isFirewalla {
// On Firewalla, the lo interface is excluded in all dnsmasq settings of all interfaces.
// Thus, we use "br0" as the nameserver in /etc/resolv.conf file.
ifaceName = "br0"
logger.Warn().Msg("using br0 interface IP address as DNS server")
}
if couldBeDirectListener(lc) {
// If ctrld is direct listener, use 127.0.0.1 as nameserver.
ns = "127.0.0.1"
} else if lc.Port != 53 {
logger.Warn().Msg("ctrld is not running on port 53, use default route interface as DNS server")
ifaceName := defaultIfaceName()
switch router.Name() {
case firewalla.Name:
// On Firewalla, the lo interface is excluded in all dnsmasq settings of all interfaces.
// Thus, we use "br0" as the nameserver in /etc/resolv.conf file.
ifaceName = "br0"
logger.Warn().Msg("using br0 interface IP address as DNS server")
case edgeos.Name:
// On EdgeOS, dnsmasq is run with "--local-service", so we need to get
// the proper interface from dnsmasq config.
if name, _ := dnsmasq.InterfaceNameFromConfig("/etc/dnsmasq.conf"); name != "" {
ifaceName = name
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")
netIface, err := net.InterfaceByName(ifaceName)
if err != nil {
mainLog.Fatal().Err(err).Msg("failed to get default route interface")

View File

@@ -34,7 +34,6 @@ func setDependencies(svc *service.Config) {
svc.Dependencies = append(svc.Dependencies, "Wants=vyatta-dhcpd.service")
svc.Dependencies = append(svc.Dependencies, "After=vyatta-dhcpd.service")
svc.Dependencies = append(svc.Dependencies, "Wants=dnsmasq.service")
svc.Dependencies = append(svc.Dependencies, "After=dnsmasq.service")
}
}

View File

@@ -0,0 +1,30 @@
package dnsmasq
import (
"bufio"
"bytes"
"errors"
"io"
"os"
"strings"
)
func InterfaceNameFromConfig(filename string) (string, error) {
buf, err := os.ReadFile(filename)
if err != nil {
return "", err
}
return interfaceNameFromReader(bytes.NewReader(buf))
}
func interfaceNameFromReader(r io.Reader) (string, error) {
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
after, found := strings.CutPrefix(line, "interface=")
if found {
return after, nil
}
}
return "", errors.New("not found")
}

View File

@@ -0,0 +1,46 @@
package dnsmasq
import (
"strings"
"testing"
)
func Test_interfaceNameFromReader(t *testing.T) {
tests := []struct {
name string
in string
wantIface string
}{
{
"good",
`interface=lo`,
"lo",
},
{
"multiple",
`interface=lo
interface=eth0
`,
"lo",
},
{
"no iface",
`cache-size=100`,
"",
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ifaceName, err := interfaceNameFromReader(strings.NewReader(tc.in))
if tc.wantIface != "" && err != nil {
t.Errorf("unexpected error: %v", err)
return
}
if tc.wantIface != ifaceName {
t.Errorf("mismatched, want: %q, got: %q", tc.wantIface, ifaceName)
}
})
}
}