net/dns: return error from NewOSManager, use it to initialize NM.

Signed-off-by: David Anderson <danderson@tailscale.com>
pull/1678/head
David Anderson 3 years ago
parent 4d142ebe06
commit 854d5d36a1

@ -365,7 +365,11 @@ func tryEngine(logf logger.Logf, linkMon *monitor.Mon, name string) (e wgengine.
dev.Close()
return nil, false, err
}
conf.DNS = dns.NewOSConfigurator(logf, devName)
d, err := dns.NewOSConfigurator(logf, devName)
if err != nil {
return nil, false, err
}
conf.DNS = d
conf.Router = r
if wrapNetstack {
conf.Router = netstack.NewSubnetRouterWrapper(conf.Router)

@ -175,10 +175,16 @@ func startIPNServer(ctx context.Context, logid string) error {
if wrapNetstack {
r = netstack.NewSubnetRouterWrapper(r)
}
d, err := dns.NewOSConfigurator(logf, devName)
if err != nil {
r.Close()
dev.Close()
return nil, err
}
eng, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{
Tun: dev,
Router: r,
DNS: dns.NewOSConfigurator(logf, devName),
DNS: d,
ListenPort: 41641,
})
if err != nil {

@ -53,7 +53,7 @@ type resolvconfManager struct {
scriptInstalled bool // libc update script has been installed
}
func newDebianResolvconfManager(logf logger.Logf) *resolvconfManager {
func newDebianResolvconfManager(logf logger.Logf) (*resolvconfManager, error) {
ret := &resolvconfManager{
logf: logf,
listRecordsPath: "/lib/resolvconf/list-records",
@ -86,7 +86,7 @@ func newDebianResolvconfManager(logf logger.Logf) *resolvconfManager {
ret.interfacesDir = "/etc/resolvconf/run/interfaces"
}
return ret
return ret, nil
}
func (m *resolvconfManager) SetDNS(config OSConfig) error {

@ -120,8 +120,8 @@ func isResolvedRunning() bool {
// or as cleanup if the program terminates unexpectedly.
type directManager struct{}
func newDirectManager() directManager {
return directManager{}
func newDirectManager() (directManager, error) {
return directManager{}, nil
}
// ownedByTailscale reports whether /etc/resolv.conf seems to be a

@ -240,7 +240,11 @@ func (m *Manager) Down() error {
// in case the Tailscale daemon terminated without closing the router.
// No other state needs to be instantiated before this runs.
func Cleanup(logf logger.Logf, interfaceName string) {
oscfg := NewOSConfigurator(logf, interfaceName)
oscfg, err := NewOSConfigurator(logf, interfaceName)
if err != nil {
logf("creating dns cleanup: %v", err)
return
}
dns := NewManager(logf, oscfg, nil)
if err := dns.Down(); err != nil {
logf("dns down: %v", err)

@ -8,7 +8,7 @@ package dns
import "tailscale.com/types/logger"
func NewOSConfigurator(logger.Logf, string) OSConfigurator {
func NewOSConfigurator(logger.Logf, string) (OSConfigurator, error) {
// TODO(dmytro): on darwin, we should use a macOS-specific method such as scutil.
// This is currently not implemented. Editing /etc/resolv.conf does not work,
// as most applications use the system resolver, which disregards it.

@ -6,7 +6,7 @@ package dns
import "tailscale.com/types/logger"
func NewOSConfigurator(logf logger.Logf, _ string) OSConfigurator {
func NewOSConfigurator(logf logger.Logf, _ string) (OSConfigurator, error) {
switch {
case isResolvconfActive():
return newResolvconfManager(logf)

@ -6,7 +6,7 @@ package dns
import "tailscale.com/types/logger"
func NewOSConfigurator(logf logger.Logf, interfaceName string) OSConfigurator {
func NewOSConfigurator(logf logger.Logf, interfaceName string) (OSConfigurator, error) {
switch {
case isResolvedActive():
return newResolvedManager(logf)

@ -6,6 +6,6 @@ package dns
import "tailscale.com/types/logger"
func NewOSConfigurator(logger.Logf, string) OSConfigurator {
func NewOSConfigurator(logger.Logf, string) (OSConfigurator, error) {
return newDirectManager()
}

@ -39,7 +39,7 @@ type windowsManager struct {
nrptWorks bool
}
func NewOSConfigurator(logf logger.Logf, interfaceName string) OSConfigurator {
func NewOSConfigurator(logf logger.Logf, interfaceName string) (OSConfigurator, error) {
ret := windowsManager{
logf: logf,
guid: interfaceName,
@ -56,7 +56,7 @@ func NewOSConfigurator(logf logger.Logf, interfaceName string) OSConfigurator {
ret.delKey(nrptBase)
}
return ret
return ret, nil
}
// keyOpenTimeout is how long we wait for a registry key to

@ -71,42 +71,26 @@ func isNMActive() bool {
// nmManager uses the NetworkManager DBus API.
type nmManager struct {
interfaceName string
canSplit bool
manager dbus.BusObject
dnsManager dbus.BusObject
}
func nmCanSplitDNS() bool {
func newNMManager(interfaceName string) (*nmManager, error) {
conn, err := dbus.SystemBus()
if err != nil {
return false
}
var mode string
nm := conn.Object("org.freedesktop.NetworkManager", dbus.ObjectPath("/org/freedesktop/NetworkManager/DnsManager"))
v, err := nm.GetProperty("org.freedesktop.NetworkManager.DnsManager.Mode")
if err != nil {
return false
}
mode, ok := v.Value().(string)
if !ok {
return false
return nil, err
}
// Per NM's documentation, it only does split-DNS when it's
// programming dnsmasq or systemd-resolved. All other modes are
// primary-only.
return mode == "dnsmasq" || mode == "systemd-resolved"
}
func newNMManager(interfaceName string) nmManager {
return nmManager{
return &nmManager{
interfaceName: interfaceName,
canSplit: nmCanSplitDNS(),
}
manager: conn.Object("org.freedesktop.NetworkManager", dbus.ObjectPath("/org/freedesktop/NetworkManager")),
dnsManager: conn.Object("org.freedesktop.NetworkManager", dbus.ObjectPath("/org/freedesktop/NetworkManager/DnsManager")),
}, nil
}
type nmConnectionSettings map[string]map[string]dbus.Variant
func (m nmManager) SetDNS(config OSConfig) error {
func (m *nmManager) SetDNS(config OSConfig) error {
ctx, cancel := context.WithTimeout(context.Background(), reconfigTimeout)
defer cancel()
@ -127,7 +111,7 @@ func (m nmManager) SetDNS(config OSConfig) error {
return err
}
func (m nmManager) trySet(ctx context.Context, config OSConfig) error {
func (m *nmManager) trySet(ctx context.Context, config OSConfig) error {
conn, err := dbus.SystemBus()
if err != nil {
return fmt.Errorf("connecting to system bus: %w", err)
@ -262,9 +246,24 @@ func (m nmManager) trySet(ctx context.Context, config OSConfig) error {
return nil
}
func (m nmManager) SupportsSplitDNS() bool { return m.canSplit }
func (m *nmManager) SupportsSplitDNS() bool {
var mode string
v, err := m.dnsManager.GetProperty("org.freedesktop.NetworkManager.DnsManager.Mode")
if err != nil {
return false
}
mode, ok := v.Value().(string)
if !ok {
return false
}
// Per NM's documentation, it only does split-DNS when it's
// programming dnsmasq or systemd-resolved. All other modes are
// primary-only.
return mode == "dnsmasq" || mode == "systemd-resolved"
}
func (m nmManager) GetBaseConfig() (OSConfig, error) {
func (m *nmManager) GetBaseConfig() (OSConfig, error) {
conn, err := dbus.SystemBus()
if err != nil {
return OSConfig{}, err
@ -362,7 +361,7 @@ func (m nmManager) GetBaseConfig() (OSConfig, error) {
return ret, nil
}
func (m nmManager) Close() error {
func (m *nmManager) Close() error {
// No need to do anything on close, NetworkManager will delete our
// settings when the tailscale interface goes away.
return nil

@ -13,6 +13,6 @@ func (m noopManager) GetBaseConfig() (OSConfig, error) {
return OSConfig{}, ErrGetBaseConfigNotSupported
}
func NewNoopManager() noopManager {
return noopManager{}
func NewNoopManager() (noopManager, error) {
return noopManager{}, nil
}

@ -15,8 +15,8 @@ import (
// implementation of the `resolvconf` program.
type openresolvManager struct{}
func newOpenresolvManager() openresolvManager {
return openresolvManager{}
func newOpenresolvManager() (openresolvManager, error) {
return openresolvManager{}, nil
}
func (m openresolvManager) SetDNS(config OSConfig) error {

@ -42,7 +42,7 @@ func isResolvconfActive() bool {
return false
}
func newResolvconfManager(logf logger.Logf) OSConfigurator {
func newResolvconfManager(logf logger.Logf) (OSConfigurator, error) {
_, err := exec.Command("resolvconf", "--version").CombinedOutput()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == 99 {

@ -87,10 +87,10 @@ type resolvedManager struct {
logf logger.Logf
}
func newResolvedManager(logf logger.Logf) resolvedManager {
func newResolvedManager(logf logger.Logf) (resolvedManager, error) {
return resolvedManager{
logf: logf,
}
}, nil
}
// Up implements managerImpl.

@ -219,7 +219,11 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
}
if conf.DNS == nil {
logf("[v1] using fake (no-op) DNS configurator")
conf.DNS = dns.NewNoopManager()
d, err := dns.NewNoopManager()
if err != nil {
return nil, err
}
conf.DNS = d
}
tsTUNDev := tstun.Wrap(logf, conf.Tun)

Loading…
Cancel
Save