summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Crawshaw <crawshaw@tailscale.com>2021-06-13 16:29:17 -0700
committerDavid Crawshaw <crawshaw@tailscale.com>2021-06-18 09:14:41 -0700
commit8a46ee7920d888fc99d6f3986d68697c2ceb28b1 (patch)
tree84a6815fd10bbd98dfd22c6240f07bee7984c2e9
parent525eb5ce411041ecab616a885aa9664fae8cbf9a (diff)
downloadtailscale-crawshaw/wslresolvconf.tar.xz
tailscale-crawshaw/wslresolvconf.zip
net/dns: some WSL wiringcrawshaw/wslresolvconf
-rw-r--r--net/dns/manager_windows.go17
-rw-r--r--net/dns/wsl_windows.go52
2 files changed, 69 insertions, 0 deletions
diff --git a/net/dns/manager_windows.go b/net/dns/manager_windows.go
index 83cc0db51..26597821f 100644
--- a/net/dns/manager_windows.go
+++ b/net/dns/manager_windows.go
@@ -259,6 +259,10 @@ func (m windowsManager) SetDNS(cfg OSConfig) error {
}
}
+ if len(cfg.SearchDomains) != 0 {
+ go w.setWSL2DNS()
+ }
+
// Force DNS re-registration in Active Directory. What we actually
// care about is that this command invokes the undocumented hidden
// function that forces Windows to notice that adapter settings
@@ -299,6 +303,19 @@ func (m windowsManager) SetDNS(cfg OSConfig) error {
return nil
}
+func (w windowsManager) setWSL2DNS() {
+ cmd := exec.Command("wsl.exe", "-l", "-q")
+ cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ m.logf("wsl.exe did not list distros, skipping WSL DNS config")
+ return
+ }
+ for _, distroName := range strings.Split(string(out), "\n") {
+ distroName = strings.TrimSpace(distroName)
+ }
+}
+
func (m windowsManager) SupportsSplitDNS() bool {
return m.nrptWorks
}
diff --git a/net/dns/wsl_windows.go b/net/dns/wsl_windows.go
new file mode 100644
index 000000000..7a5d54b65
--- /dev/null
+++ b/net/dns/wsl_windows.go
@@ -0,0 +1,52 @@
+// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dns
+
+import (
+ "fmt"
+ "io"
+ "os/exec"
+ "strings"
+ "syscall"
+)
+
+// We access WSL2 file systems via wsl.exe instead of \\wsl$\ because
+// the netpath appears to operate as the standard user, not root.
+
+func wslFileExists(distro string, fileName string) (bool, error) {
+ cmd := exec.Command("wsl.exe", "-u", "root", "-d", distro, "/bin/test", fileName)
+ cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
+ err := cmd.Run()
+ if err == nil {
+ return true, nil
+ }
+ if ee, _ := err.(*exec.ExitError); ee != nil {
+ if ee.ExitCode() == 1 {
+ return false, nil
+ }
+ }
+ return false, fmt.Errorf("wslFileExists(%q): %w", fileName, err)
+}
+
+func wslReadFile(distro, fileName string) (string, error) {
+ cmd := exec.Command("wsl.exe", "-u", "root", "-d", distro, "/bin/cat", fileName)
+ cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
+ b, err := cmd.CombinedOutput()
+ if err != nil {
+ return "", fmt.Errorf("wslReadFile(%q): %w", fileName, err)
+ }
+ return strings.TrimSpace(string(b)), nil
+}
+
+func wslWriteFile(distro, fileName string, r io.Reader) error {
+ cmd := exec.Command("wsl.exe", "-u", "root", "-d", distro, "tee", fileName)
+ cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
+ cmd.Stdin = r
+ cmd.Stdout = null
+ if err := cmd.Run(); err != nil {
+ return "", fmt.Errorf("wslWriteFile(%q): %w", fileName, err)
+ }
+ return nil
+}