mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-18 02:48:40 +00:00
net/dns: do not wait for the interface registry key to appear if the windowsManager is being closed
The WinTun adapter may have been removed by the time we're closing the dns.windowsManager, and its associated interface registry key might also have been deleted. We shouldn't use winutil.OpenKeyWait and wait for the interface key to appear when performing a cleanup as a part of the windowsManager shutdown. Updates #11222 Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
parent
82c569a83a
commit
b42b9817b0
@ -14,6 +14,7 @@ import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@ -38,6 +39,9 @@ type windowsManager struct {
|
||||
guid string
|
||||
nrptDB *nrptRuleDatabase
|
||||
wslManager *wslManager
|
||||
|
||||
mu sync.Mutex
|
||||
closing bool
|
||||
}
|
||||
|
||||
func NewOSConfigurator(logf logger.Logf, interfaceName string) (OSConfigurator, error) {
|
||||
@ -64,14 +68,37 @@ func NewOSConfigurator(logf logger.Logf, interfaceName string) (OSConfigurator,
|
||||
}
|
||||
|
||||
func (m *windowsManager) openInterfaceKey(pfx winutil.RegistryPathPrefix) (registry.Key, error) {
|
||||
var key registry.Key
|
||||
var err error
|
||||
path := pfx.WithSuffix(m.guid)
|
||||
key, err := winutil.OpenKeyWait(registry.LOCAL_MACHINE, path, registry.SET_VALUE)
|
||||
|
||||
m.mu.Lock()
|
||||
closing := m.closing
|
||||
m.mu.Unlock()
|
||||
if closing {
|
||||
// Do not wait for the interface key to appear if the manager is being closed.
|
||||
// If it's being closed due to the removal of the wintun adapter,
|
||||
// the key would already be gone by now and will not reappear until tailscaled is restarted.
|
||||
key, err = registry.OpenKey(registry.LOCAL_MACHINE, string(path), registry.SET_VALUE)
|
||||
} else {
|
||||
key, err = winutil.OpenKeyWait(registry.LOCAL_MACHINE, path, registry.SET_VALUE)
|
||||
}
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("opening %s: %w", path, err)
|
||||
}
|
||||
return key, nil
|
||||
}
|
||||
|
||||
func (m *windowsManager) muteKeyNotFoundIfClosing(err error) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if !m.closing || (err != windows.ERROR_FILE_NOT_FOUND && err != windows.ERROR_PATH_NOT_FOUND) {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func delValue(key registry.Key, name string) error {
|
||||
if err := key.DeleteValue(name); err != nil && err != registry.ErrNotExist {
|
||||
return err
|
||||
@ -205,7 +232,7 @@ func (m *windowsManager) setPrimaryDNS(resolvers []netip.Addr, domains []dnsname
|
||||
|
||||
key4, err := m.openInterfaceKey(winutil.IPv4TCPIPInterfacePrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
return m.muteKeyNotFoundIfClosing(err)
|
||||
}
|
||||
defer key4.Close()
|
||||
|
||||
@ -227,7 +254,7 @@ func (m *windowsManager) setPrimaryDNS(resolvers []netip.Addr, domains []dnsname
|
||||
|
||||
key6, err := m.openInterfaceKey(winutil.IPv6TCPIPInterfacePrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
return m.muteKeyNotFoundIfClosing(err)
|
||||
}
|
||||
defer key6.Close()
|
||||
|
||||
@ -387,6 +414,14 @@ func (m *windowsManager) SupportsSplitDNS() bool {
|
||||
}
|
||||
|
||||
func (m *windowsManager) Close() error {
|
||||
m.mu.Lock()
|
||||
if m.closing {
|
||||
m.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
m.closing = true
|
||||
m.mu.Unlock()
|
||||
|
||||
err := m.SetDNS(OSConfig{})
|
||||
if m.nrptDB != nil {
|
||||
m.nrptDB.Close()
|
||||
@ -407,7 +442,7 @@ func (m *windowsManager) disableDynamicUpdates() error {
|
||||
for _, prefix := range prefixen {
|
||||
k, err := m.openInterfaceKey(prefix)
|
||||
if err != nil {
|
||||
return err
|
||||
return m.muteKeyNotFoundIfClosing(err)
|
||||
}
|
||||
defer k.Close()
|
||||
|
||||
@ -426,7 +461,7 @@ func (m *windowsManager) disableDynamicUpdates() error {
|
||||
func (m *windowsManager) setSingleDWORD(prefix winutil.RegistryPathPrefix, value string, data uint32) error {
|
||||
k, err := m.openInterfaceKey(prefix)
|
||||
if err != nil {
|
||||
return err
|
||||
return m.muteKeyNotFoundIfClosing(err)
|
||||
}
|
||||
defer k.Close()
|
||||
return k.SetDWordValue(value, data)
|
||||
|
Loading…
x
Reference in New Issue
Block a user