net/dns: teach OpenBSD's manager to talk to resolvd(8). (#2789)

OpenBSD 6.9 and up has a daemon which handles nameserver configuration. This PR
teaches the OpenBSD dns manager to check if resolvd is being used. If it is, it
will use the route(8) command to tell resolvd to add the Tailscale dns entries
to resolv.conf

Signed-off-by: Aaron Bieber <aaron@bolddaemon.com>
This commit is contained in:
Aaron Bieber
2022-01-11 09:45:50 -07:00
committed by GitHub
parent b8ad90c2bf
commit 189f359609
2 changed files with 206 additions and 2 deletions

View File

@@ -4,8 +4,71 @@
package dns
import "tailscale.com/types/logger"
import (
"bytes"
"fmt"
"os"
func NewOSConfigurator(logf logger.Logf, _ string) (OSConfigurator, error) {
"tailscale.com/types/logger"
)
type kv struct {
k, v string
}
func (kv kv) String() string {
return fmt.Sprintf("%s=%s", kv.k, kv.v)
}
func NewOSConfigurator(logf logger.Logf, interfaceName string) (OSConfigurator, error) {
return newOSConfigurator(logf, interfaceName,
newOSConfigEnv{
rcIsResolvd: rcIsResolvd,
fs: directFS{},
})
}
// newOSConfigEnv are the funcs newOSConfigurator needs, pulled out for testing.
type newOSConfigEnv struct {
fs directFS
rcIsResolvd func(resolvConfContents []byte) bool
}
func newOSConfigurator(logf logger.Logf, interfaceName string, env newOSConfigEnv) (ret OSConfigurator, err error) {
var debug []kv
dbg := func(k, v string) {
debug = append(debug, kv{k, v})
}
defer func() {
if ret != nil {
dbg("ret", fmt.Sprintf("%T", ret))
}
logf("dns: %v", debug)
}()
bs, err := env.fs.ReadFile(resolvConf)
if os.IsNotExist(err) {
dbg("rc", "missing")
return newDirectManager(logf), nil
}
if err != nil {
return nil, fmt.Errorf("reading /etc/resolv.conf: %w", err)
}
if env.rcIsResolvd(bs) {
dbg("resolvd", "yes")
return newResolvdManager(logf, interfaceName)
}
dbg("resolvd", "missing")
return newDirectManager(logf), nil
}
func rcIsResolvd(resolvConfContents []byte) bool {
// If we have the string "# resolvd:" in resolv.conf resolvd(8) is
// managing things.
if bytes.Contains(resolvConfContents, []byte("# resolvd:")) {
return true
}
return false
}