Skip to content

Commit 6fe418b

Browse files
committed
tunnel: avoid calling netsh on <1809 for DNS changes
And it turns out we can use SearchList on old Windows 10 too. This gets total feature parity with the new DNS function. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
1 parent 388bd85 commit 6fe418b

2 files changed

Lines changed: 32 additions & 114 deletions

File tree

tunnel/winipcfg/luid.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ package winipcfg
77

88
import (
99
"errors"
10+
"fmt"
1011
"net/netip"
1112
"strings"
1213

1314
"golang.org/x/sys/windows"
15+
"golang.org/x/sys/windows/registry"
16+
"golang.org/x/sys/windows/svc"
17+
"golang.org/x/sys/windows/svc/mgr"
1418
)
1519

1620
// LUID represents a network interface.
@@ -370,15 +374,37 @@ func (luid LUID) SetDNS(family AddressFamily, servers []netip.Addr, domains []st
370374
}
371375

372376
// For < Windows 10 1809
373-
err = luid.fallbackSetDNSForFamily(family, servers)
377+
var regPath string
378+
switch family {
379+
case windows.AF_INET:
380+
regPath = fmt.Sprintf("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%v", guid)
381+
case windows.AF_INET6:
382+
regPath = fmt.Sprintf("SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters\\Interfaces\\%v", guid)
383+
}
384+
key, err := registry.OpenKey(registry.LOCAL_MACHINE, regPath, registry.SET_VALUE)
374385
if err != nil {
375-
return err
386+
return fmt.Errorf("opening interface registry key: %w", err)
387+
}
388+
defer key.Close()
389+
if err := key.SetStringValue("NameServer", strings.Join(filteredServers, ",")); err != nil {
390+
return fmt.Errorf("setting NameServer registry value: %w", err)
376391
}
377-
if len(domains) > 0 {
378-
return luid.fallbackSetDNSDomain(domains[0])
379-
} else {
380-
return luid.fallbackSetDNSDomain("")
392+
if err := key.SetStringValue("SearchList", strings.Join(domains, ",")); err != nil {
393+
return fmt.Errorf("setting SearchList registry value: %w", err)
394+
}
395+
scm, err := mgr.Connect()
396+
if err != nil {
397+
return nil
381398
}
399+
defer scm.Disconnect()
400+
s := mgr.Service{Name: "dnscache"}
401+
s.Handle, err = windows.OpenService(scm.Handle, windows.StringToUTF16Ptr(s.Name), windows.SERVICE_PAUSE_CONTINUE)
402+
if err != nil {
403+
return nil
404+
}
405+
defer s.Close()
406+
s.Control(svc.ParamChange)
407+
return nil
382408
}
383409

384410
// FlushDNS method clears all DNS servers associated with the adapter.

tunnel/winipcfg/netsh.go

Lines changed: 0 additions & 108 deletions
This file was deleted.

0 commit comments

Comments
 (0)