@@ -20,12 +20,10 @@ import (
20
20
"tailscale.com/envknob"
21
21
"tailscale.com/types/logger"
22
22
"tailscale.com/util/dnsname"
23
+ "tailscale.com/util/winutil"
23
24
)
24
25
25
26
const (
26
- ipv4RegBase = `SYSTEM\CurrentControlSet\Services\Tcpip\Parameters`
27
- ipv6RegBase = `SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters`
28
-
29
27
versionKey = `SOFTWARE\Microsoft\Windows NT\CurrentVersion`
30
28
)
31
29
@@ -59,24 +57,15 @@ func NewOSConfigurator(logf logger.Logf, interfaceName string) (OSConfigurator,
59
57
return ret , nil
60
58
}
61
59
62
- // keyOpenTimeout is how long we wait for a registry key to
63
- // appear. For some reason, registry keys tied to ephemeral interfaces
64
- // can take a long while to appear after interface creation, and we
65
- // can end up racing with that.
66
- const keyOpenTimeout = 20 * time .Second
67
-
68
- func (m windowsManager ) openKey (path string ) (registry.Key , error ) {
69
- key , err := openKeyWait (registry .LOCAL_MACHINE , path , registry .SET_VALUE , keyOpenTimeout )
60
+ func (m windowsManager ) openInterfaceKey (pfx winutil.RegistryPathPrefix ) (registry.Key , error ) {
61
+ path := pfx .WithSuffix (m .guid )
62
+ key , err := winutil .OpenKeyWait (registry .LOCAL_MACHINE , path , registry .SET_VALUE )
70
63
if err != nil {
71
64
return 0 , fmt .Errorf ("opening %s: %w" , path , err )
72
65
}
73
66
return key , nil
74
67
}
75
68
76
- func (m windowsManager ) ifPath (basePath string ) string {
77
- return fmt .Sprintf (`%s\Interfaces\%s` , basePath , m .guid )
78
- }
79
-
80
69
func delValue (key registry.Key , name string ) error {
81
70
if err := key .DeleteValue (name ); err != nil && err != registry .ErrNotExist {
82
71
return err
@@ -134,7 +123,7 @@ func (m windowsManager) setPrimaryDNS(resolvers []netip.Addr, domains []dnsname.
134
123
domStrs = append (domStrs , dom .WithoutTrailingDot ())
135
124
}
136
125
137
- key4 , err := m .openKey ( m . ifPath ( ipv4RegBase ) )
126
+ key4 , err := m .openInterfaceKey ( winutil . IPv4TCPIPInterfacePrefix )
138
127
if err != nil {
139
128
return err
140
129
}
@@ -156,7 +145,7 @@ func (m windowsManager) setPrimaryDNS(resolvers []netip.Addr, domains []dnsname.
156
145
return err
157
146
}
158
147
159
- key6 , err := m .openKey ( m . ifPath ( ipv6RegBase ) )
148
+ key6 , err := m .openInterfaceKey ( winutil . IPv6TCPIPInterfacePrefix )
160
149
if err != nil {
161
150
return err
162
151
}
@@ -308,25 +297,26 @@ func (m windowsManager) Close() error {
308
297
// Windows DHCP client from sending dynamic DNS updates for our interface to
309
298
// AD domain controllers.
310
299
func (m windowsManager ) disableDynamicUpdates () error {
311
- setRegValue := func (regBase string ) error {
312
- key , err := m .openKey (m .ifPath (regBase ))
313
- if err != nil {
314
- return err
315
- }
316
- defer key .Close ()
317
-
318
- return key .SetDWordValue ("DisableDynamicUpdate" , 1 )
300
+ if err := m .setSingleDWORD (winutil .IPv4TCPIPInterfacePrefix , "EnableDNSUpdate" , 0 ); err != nil {
301
+ return err
319
302
}
320
-
321
- for _ , regBase := range []string {ipv4RegBase , ipv6RegBase } {
322
- if err := setRegValue (regBase ); err != nil {
323
- return err
324
- }
303
+ if err := m .setSingleDWORD (winutil .IPv6TCPIPInterfacePrefix , "EnableDNSUpdate" , 0 ); err != nil {
304
+ return err
325
305
}
326
-
327
306
return nil
328
307
}
329
308
309
+ // setSingleDWORD opens the Registry Key in HKLM for the interface associated
310
+ // with the windowsManager and sets the "keyPrefix\value" to data.
311
+ func (m windowsManager ) setSingleDWORD (prefix winutil.RegistryPathPrefix , value string , data uint32 ) error {
312
+ k , err := m .openInterfaceKey (prefix )
313
+ if err != nil {
314
+ return err
315
+ }
316
+ defer k .Close ()
317
+ return k .SetDWordValue (value , data )
318
+ }
319
+
330
320
func (m windowsManager ) GetBaseConfig () (OSConfig , error ) {
331
321
resolvers , err := m .getBasePrimaryResolver ()
332
322
if err != nil {
0 commit comments