summaryrefslogtreecommitdiffhomepage
path: root/cmd/tailscaled
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/tailscaled')
-rw-r--r--cmd/tailscaled/childproc/childproc.go38
-rw-r--r--cmd/tailscaled/generate.go16
-rw-r--r--cmd/tailscaled/install_darwin.go398
-rw-r--r--cmd/tailscaled/install_windows.go248
-rw-r--r--cmd/tailscaled/proxy.go160
-rw-r--r--cmd/tailscaled/sigpipe.go24
-rw-r--r--cmd/tailscaled/tailscaled.defaults16
-rwxr-xr-xcmd/tailscaled/tailscaled.openrc50
-rw-r--r--cmd/tailscaled/tailscaled_bird.go34
-rw-r--r--cmd/tailscaled/tailscaled_notwindows.go28
-rw-r--r--cmd/tailscaled/windows-manifest.xml26
-rw-r--r--cmd/tailscaled/with_cli.go46
12 files changed, 542 insertions, 542 deletions
diff --git a/cmd/tailscaled/childproc/childproc.go b/cmd/tailscaled/childproc/childproc.go
index cc83a06c6..068015c59 100644
--- a/cmd/tailscaled/childproc/childproc.go
+++ b/cmd/tailscaled/childproc/childproc.go
@@ -1,19 +1,19 @@
-// Copyright (c) Tailscale Inc & AUTHORS
-// SPDX-License-Identifier: BSD-3-Clause
-
-// Package childproc allows other packages to register "tailscaled be-child"
-// child process hook code. This avoids duplicating build tags in the
-// tailscaled package. Instead, the code that needs to fork/exec the self
-// executable (when it's tailscaled) can instead register the code
-// they want to run.
-package childproc
-
-var Code = map[string]func([]string) error{}
-
-// Add registers code f to run as 'tailscaled be-child <typ> [args]'.
-func Add(typ string, f func(args []string) error) {
- if _, dup := Code[typ]; dup {
- panic("dup hook " + typ)
- }
- Code[typ] = f
-}
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Package childproc allows other packages to register "tailscaled be-child"
+// child process hook code. This avoids duplicating build tags in the
+// tailscaled package. Instead, the code that needs to fork/exec the self
+// executable (when it's tailscaled) can instead register the code
+// they want to run.
+package childproc
+
+var Code = map[string]func([]string) error{}
+
+// Add registers code f to run as 'tailscaled be-child <typ> [args]'.
+func Add(typ string, f func(args []string) error) {
+ if _, dup := Code[typ]; dup {
+ panic("dup hook " + typ)
+ }
+ Code[typ] = f
+}
diff --git a/cmd/tailscaled/generate.go b/cmd/tailscaled/generate.go
index 5c2e9be91..fa38b3704 100644
--- a/cmd/tailscaled/generate.go
+++ b/cmd/tailscaled/generate.go
@@ -1,8 +1,8 @@
-// Copyright (c) Tailscale Inc & AUTHORS
-// SPDX-License-Identifier: BSD-3-Clause
-
-package main
-
-//go:generate go run tailscale.com/cmd/mkmanifest amd64 windows-manifest.xml manifest_windows_amd64.syso
-//go:generate go run tailscale.com/cmd/mkmanifest 386 windows-manifest.xml manifest_windows_386.syso
-//go:generate go run tailscale.com/cmd/mkmanifest arm64 windows-manifest.xml manifest_windows_arm64.syso
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package main
+
+//go:generate go run tailscale.com/cmd/mkmanifest amd64 windows-manifest.xml manifest_windows_amd64.syso
+//go:generate go run tailscale.com/cmd/mkmanifest 386 windows-manifest.xml manifest_windows_386.syso
+//go:generate go run tailscale.com/cmd/mkmanifest arm64 windows-manifest.xml manifest_windows_arm64.syso
diff --git a/cmd/tailscaled/install_darwin.go b/cmd/tailscaled/install_darwin.go
index 05e5eaed8..9013b39ba 100644
--- a/cmd/tailscaled/install_darwin.go
+++ b/cmd/tailscaled/install_darwin.go
@@ -1,199 +1,199 @@
-// Copyright (c) Tailscale Inc & AUTHORS
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build go1.19
-
-package main
-
-import (
- "errors"
- "fmt"
- "io"
- "io/fs"
- "os"
- "os/exec"
- "path/filepath"
-)
-
-func init() {
- installSystemDaemon = installSystemDaemonDarwin
- uninstallSystemDaemon = uninstallSystemDaemonDarwin
-}
-
-// darwinLaunchdPlist is the launchd.plist that's written to
-// /Library/LaunchDaemons/com.tailscale.tailscaled.plist or (in the
-// future) a user-specific location.
-//
-// See man launchd.plist.
-const darwinLaunchdPlist = `
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-
- <key>Label</key>
- <string>com.tailscale.tailscaled</string>
-
- <key>ProgramArguments</key>
- <array>
- <string>/usr/local/bin/tailscaled</string>
- </array>
-
- <key>RunAtLoad</key>
- <true/>
-
-</dict>
-</plist>
-`
-
-const sysPlist = "/Library/LaunchDaemons/com.tailscale.tailscaled.plist"
-const targetBin = "/usr/local/bin/tailscaled"
-const service = "com.tailscale.tailscaled"
-
-func uninstallSystemDaemonDarwin(args []string) (ret error) {
- if len(args) > 0 {
- return errors.New("uninstall subcommand takes no arguments")
- }
-
- plist, err := exec.Command("launchctl", "list", "com.tailscale.tailscaled").Output()
- _ = plist // parse it? https://github.com/DHowett/go-plist if we need something.
- running := err == nil
-
- if running {
- out, err := exec.Command("launchctl", "stop", "com.tailscale.tailscaled").CombinedOutput()
- if err != nil {
- fmt.Printf("launchctl stop com.tailscale.tailscaled: %v, %s\n", err, out)
- ret = err
- }
- out, err = exec.Command("launchctl", "unload", sysPlist).CombinedOutput()
- if err != nil {
- fmt.Printf("launchctl unload %s: %v, %s\n", sysPlist, err, out)
- if ret == nil {
- ret = err
- }
- }
- }
-
- if err := os.Remove(sysPlist); err != nil {
- if os.IsNotExist(err) {
- err = nil
- }
- if ret == nil {
- ret = err
- }
- }
-
- // Do not delete targetBin if it's a symlink, which happens if it was installed via
- // Homebrew.
- if isSymlink(targetBin) {
- return ret
- }
-
- if err := os.Remove(targetBin); err != nil {
- if os.IsNotExist(err) {
- err = nil
- }
- if ret == nil {
- ret = err
- }
- }
- return ret
-}
-
-func installSystemDaemonDarwin(args []string) (err error) {
- if len(args) > 0 {
- return errors.New("install subcommand takes no arguments")
- }
- defer func() {
- if err != nil && os.Getuid() != 0 {
- err = fmt.Errorf("%w; try running tailscaled with sudo", err)
- }
- }()
-
- // Best effort:
- uninstallSystemDaemonDarwin(nil)
-
- exe, err := os.Executable()
- if err != nil {
- return fmt.Errorf("failed to find our own executable path: %w", err)
- }
-
- same, err := sameFile(exe, targetBin)
- if err != nil {
- return err
- }
-
- // Do not overwrite targetBin with the binary file if it it's already
- // pointing to it. This is primarily to handle Homebrew that writes
- // /usr/local/bin/tailscaled is a symlink to the actual binary.
- if !same {
- if err := copyBinary(exe, targetBin); err != nil {
- return err
- }
- }
- if err := os.WriteFile(sysPlist, []byte(darwinLaunchdPlist), 0700); err != nil {
- return err
- }
-
- if out, err := exec.Command("launchctl", "load", sysPlist).CombinedOutput(); err != nil {
- return fmt.Errorf("error running launchctl load %s: %v, %s", sysPlist, err, out)
- }
-
- if out, err := exec.Command("launchctl", "start", service).CombinedOutput(); err != nil {
- return fmt.Errorf("error running launchctl start %s: %v, %s", service, err, out)
- }
-
- return nil
-}
-
-// copyBinary copies binary file `src` into `dst`.
-func copyBinary(src, dst string) error {
- if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
- return err
- }
- tmpBin := dst + ".tmp"
- f, err := os.Create(tmpBin)
- if err != nil {
- return err
- }
- srcf, err := os.Open(src)
- if err != nil {
- f.Close()
- return err
- }
- _, err = io.Copy(f, srcf)
- srcf.Close()
- if err != nil {
- f.Close()
- return err
- }
- if err := f.Close(); err != nil {
- return err
- }
- if err := os.Chmod(tmpBin, 0755); err != nil {
- return err
- }
- if err := os.Rename(tmpBin, dst); err != nil {
- return err
- }
-
- return nil
-}
-
-func isSymlink(path string) bool {
- fi, err := os.Lstat(path)
- return err == nil && (fi.Mode()&os.ModeSymlink == os.ModeSymlink)
-}
-
-// sameFile returns true if both file paths exist and resolve to the same file.
-func sameFile(path1, path2 string) (bool, error) {
- dst1, err := filepath.EvalSymlinks(path1)
- if err != nil && !errors.Is(err, fs.ErrNotExist) {
- return false, fmt.Errorf("EvalSymlinks(%s): %w", path1, err)
- }
- dst2, err := filepath.EvalSymlinks(path2)
- if err != nil && !errors.Is(err, fs.ErrNotExist) {
- return false, fmt.Errorf("EvalSymlinks(%s): %w", path2, err)
- }
- return dst1 == dst2, nil
-}
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build go1.19
+
+package main
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "io/fs"
+ "os"
+ "os/exec"
+ "path/filepath"
+)
+
+func init() {
+ installSystemDaemon = installSystemDaemonDarwin
+ uninstallSystemDaemon = uninstallSystemDaemonDarwin
+}
+
+// darwinLaunchdPlist is the launchd.plist that's written to
+// /Library/LaunchDaemons/com.tailscale.tailscaled.plist or (in the
+// future) a user-specific location.
+//
+// See man launchd.plist.
+const darwinLaunchdPlist = `
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+
+ <key>Label</key>
+ <string>com.tailscale.tailscaled</string>
+
+ <key>ProgramArguments</key>
+ <array>
+ <string>/usr/local/bin/tailscaled</string>
+ </array>
+
+ <key>RunAtLoad</key>
+ <true/>
+
+</dict>
+</plist>
+`
+
+const sysPlist = "/Library/LaunchDaemons/com.tailscale.tailscaled.plist"
+const targetBin = "/usr/local/bin/tailscaled"
+const service = "com.tailscale.tailscaled"
+
+func uninstallSystemDaemonDarwin(args []string) (ret error) {
+ if len(args) > 0 {
+ return errors.New("uninstall subcommand takes no arguments")
+ }
+
+ plist, err := exec.Command("launchctl", "list", "com.tailscale.tailscaled").Output()
+ _ = plist // parse it? https://github.com/DHowett/go-plist if we need something.
+ running := err == nil
+
+ if running {
+ out, err := exec.Command("launchctl", "stop", "com.tailscale.tailscaled").CombinedOutput()
+ if err != nil {
+ fmt.Printf("launchctl stop com.tailscale.tailscaled: %v, %s\n", err, out)
+ ret = err
+ }
+ out, err = exec.Command("launchctl", "unload", sysPlist).CombinedOutput()
+ if err != nil {
+ fmt.Printf("launchctl unload %s: %v, %s\n", sysPlist, err, out)
+ if ret == nil {
+ ret = err
+ }
+ }
+ }
+
+ if err := os.Remove(sysPlist); err != nil {
+ if os.IsNotExist(err) {
+ err = nil
+ }
+ if ret == nil {
+ ret = err
+ }
+ }
+
+ // Do not delete targetBin if it's a symlink, which happens if it was installed via
+ // Homebrew.
+ if isSymlink(targetBin) {
+ return ret
+ }
+
+ if err := os.Remove(targetBin); err != nil {
+ if os.IsNotExist(err) {
+ err = nil
+ }
+ if ret == nil {
+ ret = err
+ }
+ }
+ return ret
+}
+
+func installSystemDaemonDarwin(args []string) (err error) {
+ if len(args) > 0 {
+ return errors.New("install subcommand takes no arguments")
+ }
+ defer func() {
+ if err != nil && os.Getuid() != 0 {
+ err = fmt.Errorf("%w; try running tailscaled with sudo", err)
+ }
+ }()
+
+ // Best effort:
+ uninstallSystemDaemonDarwin(nil)
+
+ exe, err := os.Executable()
+ if err != nil {
+ return fmt.Errorf("failed to find our own executable path: %w", err)
+ }
+
+ same, err := sameFile(exe, targetBin)
+ if err != nil {
+ return err
+ }
+
+ // Do not overwrite targetBin with the binary file if it it's already
+ // pointing to it. This is primarily to handle Homebrew that writes
+ // /usr/local/bin/tailscaled is a symlink to the actual binary.
+ if !same {
+ if err := copyBinary(exe, targetBin); err != nil {
+ return err
+ }
+ }
+ if err := os.WriteFile(sysPlist, []byte(darwinLaunchdPlist), 0700); err != nil {
+ return err
+ }
+
+ if out, err := exec.Command("launchctl", "load", sysPlist).CombinedOutput(); err != nil {
+ return fmt.Errorf("error running launchctl load %s: %v, %s", sysPlist, err, out)
+ }
+
+ if out, err := exec.Command("launchctl", "start", service).CombinedOutput(); err != nil {
+ return fmt.Errorf("error running launchctl start %s: %v, %s", service, err, out)
+ }
+
+ return nil
+}
+
+// copyBinary copies binary file `src` into `dst`.
+func copyBinary(src, dst string) error {
+ if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
+ return err
+ }
+ tmpBin := dst + ".tmp"
+ f, err := os.Create(tmpBin)
+ if err != nil {
+ return err
+ }
+ srcf, err := os.Open(src)
+ if err != nil {
+ f.Close()
+ return err
+ }
+ _, err = io.Copy(f, srcf)
+ srcf.Close()
+ if err != nil {
+ f.Close()
+ return err
+ }
+ if err := f.Close(); err != nil {
+ return err
+ }
+ if err := os.Chmod(tmpBin, 0755); err != nil {
+ return err
+ }
+ if err := os.Rename(tmpBin, dst); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func isSymlink(path string) bool {
+ fi, err := os.Lstat(path)
+ return err == nil && (fi.Mode()&os.ModeSymlink == os.ModeSymlink)
+}
+
+// sameFile returns true if both file paths exist and resolve to the same file.
+func sameFile(path1, path2 string) (bool, error) {
+ dst1, err := filepath.EvalSymlinks(path1)
+ if err != nil && !errors.Is(err, fs.ErrNotExist) {
+ return false, fmt.Errorf("EvalSymlinks(%s): %w", path1, err)
+ }
+ dst2, err := filepath.EvalSymlinks(path2)
+ if err != nil && !errors.Is(err, fs.ErrNotExist) {
+ return false, fmt.Errorf("EvalSymlinks(%s): %w", path2, err)
+ }
+ return dst1 == dst2, nil
+}
diff --git a/cmd/tailscaled/install_windows.go b/cmd/tailscaled/install_windows.go
index c36418642..9e39c8ab3 100644
--- a/cmd/tailscaled/install_windows.go
+++ b/cmd/tailscaled/install_windows.go
@@ -1,124 +1,124 @@
-// Copyright (c) Tailscale Inc & AUTHORS
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build go1.19
-
-package main
-
-import (
- "context"
- "errors"
- "fmt"
- "os"
- "time"
-
- "golang.org/x/sys/windows"
- "golang.org/x/sys/windows/svc"
- "golang.org/x/sys/windows/svc/mgr"
- "tailscale.com/logtail/backoff"
- "tailscale.com/types/logger"
- "tailscale.com/util/osshare"
-)
-
-func init() {
- installSystemDaemon = installSystemDaemonWindows
- uninstallSystemDaemon = uninstallSystemDaemonWindows
-}
-
-func installSystemDaemonWindows(args []string) (err error) {
- m, err := mgr.Connect()
- if err != nil {
- return fmt.Errorf("failed to connect to Windows service manager: %v", err)
- }
-
- service, err := m.OpenService(serviceName)
- if err == nil {
- service.Close()
- return fmt.Errorf("service %q is already installed", serviceName)
- }
-
- // no such service; proceed to install the service.
-
- exe, err := os.Executable()
- if err != nil {
- return err
- }
-
- c := mgr.Config{
- ServiceType: windows.SERVICE_WIN32_OWN_PROCESS,
- StartType: mgr.StartAutomatic,
- ErrorControl: mgr.ErrorNormal,
- DisplayName: serviceName,
- Description: "Connects this computer to others on the Tailscale network.",
- }
-
- service, err = m.CreateService(serviceName, exe, c)
- if err != nil {
- return fmt.Errorf("failed to create %q service: %v", serviceName, err)
- }
- defer service.Close()
-
- // Exponential backoff is often too aggressive, so use (mostly)
- // squares instead.
- ra := []mgr.RecoveryAction{
- {mgr.ServiceRestart, 1 * time.Second},
- {mgr.ServiceRestart, 2 * time.Second},
- {mgr.ServiceRestart, 4 * time.Second},
- {mgr.ServiceRestart, 9 * time.Second},
- {mgr.ServiceRestart, 16 * time.Second},
- {mgr.ServiceRestart, 25 * time.Second},
- {mgr.ServiceRestart, 36 * time.Second},
- {mgr.ServiceRestart, 49 * time.Second},
- {mgr.ServiceRestart, 64 * time.Second},
- }
- const resetPeriodSecs = 60
- err = service.SetRecoveryActions(ra, resetPeriodSecs)
- if err != nil {
- return fmt.Errorf("failed to set service recovery actions: %v", err)
- }
-
- return nil
-}
-
-func uninstallSystemDaemonWindows(args []string) (ret error) {
- // Remove file sharing from Windows shell (noop in non-windows)
- osshare.SetFileSharingEnabled(false, logger.Discard)
-
- m, err := mgr.Connect()
- if err != nil {
- return fmt.Errorf("failed to connect to Windows service manager: %v", err)
- }
- defer m.Disconnect()
-
- service, err := m.OpenService(serviceName)
- if err != nil {
- return fmt.Errorf("failed to open %q service: %v", serviceName, err)
- }
-
- st, err := service.Query()
- if err != nil {
- service.Close()
- return fmt.Errorf("failed to query service state: %v", err)
- }
- if st.State != svc.Stopped {
- service.Control(svc.Stop)
- }
- err = service.Delete()
- service.Close()
- if err != nil {
- return fmt.Errorf("failed to delete service: %v", err)
- }
-
- bo := backoff.NewBackoff("uninstall", logger.Discard, 30*time.Second)
- end := time.Now().Add(15 * time.Second)
- for time.Until(end) > 0 {
- service, err = m.OpenService(serviceName)
- if err != nil {
- // service is no longer openable; success!
- break
- }
- service.Close()
- bo.BackOff(context.Background(), errors.New("service not deleted"))
- }
- return nil
-}
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build go1.19
+
+package main
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "os"
+ "time"
+
+ "golang.org/x/sys/windows"
+ "golang.org/x/sys/windows/svc"
+ "golang.org/x/sys/windows/svc/mgr"
+ "tailscale.com/logtail/backoff"
+ "tailscale.com/types/logger"
+ "tailscale.com/util/osshare"
+)
+
+func init() {
+ installSystemDaemon = installSystemDaemonWindows
+ uninstallSystemDaemon = uninstallSystemDaemonWindows
+}
+
+func installSystemDaemonWindows(args []string) (err error) {
+ m, err := mgr.Connect()
+ if err != nil {
+ return fmt.Errorf("failed to connect to Windows service manager: %v", err)
+ }
+
+ service, err := m.OpenService(serviceName)
+ if err == nil {
+ service.Close()
+ return fmt.Errorf("service %q is already installed", serviceName)
+ }
+
+ // no such service; proceed to install the service.
+
+ exe, err := os.Executable()
+ if err != nil {
+ return err
+ }
+
+ c := mgr.Config{
+ ServiceType: windows.SERVICE_WIN32_OWN_PROCESS,
+ StartType: mgr.StartAutomatic,
+ ErrorControl: mgr.ErrorNormal,
+ DisplayName: serviceName,
+ Description: "Connects this computer to others on the Tailscale network.",
+ }
+
+ service, err = m.CreateService(serviceName, exe, c)
+ if err != nil {
+ return fmt.Errorf("failed to create %q service: %v", serviceName, err)
+ }
+ defer service.Close()
+
+ // Exponential backoff is often too aggressive, so use (mostly)
+ // squares instead.
+ ra := []mgr.RecoveryAction{
+ {mgr.ServiceRestart, 1 * time.Second},
+ {mgr.ServiceRestart, 2 * time.Second},
+ {mgr.ServiceRestart, 4 * time.Second},
+ {mgr.ServiceRestart, 9 * time.Second},
+ {mgr.ServiceRestart, 16 * time.Second},
+ {mgr.ServiceRestart, 25 * time.Second},
+ {mgr.ServiceRestart, 36 * time.Second},
+ {mgr.ServiceRestart, 49 * time.Second},
+ {mgr.ServiceRestart, 64 * time.Second},
+ }
+ const resetPeriodSecs = 60
+ err = service.SetRecoveryActions(ra, resetPeriodSecs)
+ if err != nil {
+ return fmt.Errorf("failed to set service recovery actions: %v", err)
+ }
+
+ return nil
+}
+
+func uninstallSystemDaemonWindows(args []string) (ret error) {
+ // Remove file sharing from Windows shell (noop in non-windows)
+ osshare.SetFileSharingEnabled(false, logger.Discard)
+
+ m, err := mgr.Connect()
+ if err != nil {
+ return fmt.Errorf("failed to connect to Windows service manager: %v", err)
+ }
+ defer m.Disconnect()
+
+ service, err := m.OpenService(serviceName)
+ if err != nil {
+ return fmt.Errorf("failed to open %q service: %v", serviceName, err)
+ }
+
+ st, err := service.Query()
+ if err != nil {
+ service.Close()
+ return fmt.Errorf("failed to query service state: %v", err)
+ }
+ if st.State != svc.Stopped {
+ service.Control(svc.Stop)
+ }
+ err = service.Delete()
+ service.Close()
+ if err != nil {
+ return fmt.Errorf("failed to delete service: %v", err)
+ }
+
+ bo := backoff.NewBackoff("uninstall", logger.Discard, 30*time.Second)
+ end := time.Now().Add(15 * time.Second)
+ for time.Until(end) > 0 {
+ service, err = m.OpenService(serviceName)
+ if err != nil {
+ // service is no longer openable; success!
+ break
+ }
+ service.Close()
+ bo.BackOff(context.Background(), errors.New("service not deleted"))
+ }
+ return nil
+}
diff --git a/cmd/tailscaled/proxy.go b/cmd/tailscaled/proxy.go
index a91c62bfa..109ad029d 100644
--- a/cmd/tailscaled/proxy.go
+++ b/cmd/tailscaled/proxy.go
@@ -1,80 +1,80 @@
-// Copyright (c) Tailscale Inc & AUTHORS
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build go1.19
-
-// HTTP proxy code
-
-package main
-
-import (
- "context"
- "io"
- "net"
- "net/http"
- "net/http/httputil"
- "strings"
-)
-
-// httpProxyHandler returns an HTTP proxy http.Handler using the
-// provided backend dialer.
-func httpProxyHandler(dialer func(ctx context.Context, netw, addr string) (net.Conn, error)) http.Handler {
- rp := &httputil.ReverseProxy{
- Director: func(r *http.Request) {}, // no change
- Transport: &http.Transport{
- DialContext: dialer,
- },
- }
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.Method != "CONNECT" {
- backURL := r.RequestURI
- if strings.HasPrefix(backURL, "/") || backURL == "*" {
- http.Error(w, "bogus RequestURI; must be absolute URL or CONNECT", 400)
- return
- }
- rp.ServeHTTP(w, r)
- return
- }
-
- // CONNECT support:
-
- dst := r.RequestURI
- c, err := dialer(r.Context(), "tcp", dst)
- if err != nil {
- w.Header().Set("Tailscale-Connect-Error", err.Error())
- http.Error(w, err.Error(), 500)
- return
- }
- defer c.Close()
-
- cc, ccbuf, err := w.(http.Hijacker).Hijack()
- if err != nil {
- http.Error(w, err.Error(), 500)
- return
- }
- defer cc.Close()
-
- io.WriteString(cc, "HTTP/1.1 200 OK\r\n\r\n")
-
- var clientSrc io.Reader = ccbuf
- if ccbuf.Reader.Buffered() == 0 {
- // In the common case (with no
- // buffered data), read directly from
- // the underlying client connection to
- // save some memory, letting the
- // bufio.Reader/Writer get GC'ed.
- clientSrc = cc
- }
-
- errc := make(chan error, 1)
- go func() {
- _, err := io.Copy(cc, c)
- errc <- err
- }()
- go func() {
- _, err := io.Copy(c, clientSrc)
- errc <- err
- }()
- <-errc
- })
-}
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build go1.19
+
+// HTTP proxy code
+
+package main
+
+import (
+ "context"
+ "io"
+ "net"
+ "net/http"
+ "net/http/httputil"
+ "strings"
+)
+
+// httpProxyHandler returns an HTTP proxy http.Handler using the
+// provided backend dialer.
+func httpProxyHandler(dialer func(ctx context.Context, netw, addr string) (net.Conn, error)) http.Handler {
+ rp := &httputil.ReverseProxy{
+ Director: func(r *http.Request) {}, // no change
+ Transport: &http.Transport{
+ DialContext: dialer,
+ },
+ }
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "CONNECT" {
+ backURL := r.RequestURI
+ if strings.HasPrefix(backURL, "/") || backURL == "*" {
+ http.Error(w, "bogus RequestURI; must be absolute URL or CONNECT", 400)
+ return
+ }
+ rp.ServeHTTP(w, r)
+ return
+ }
+
+ // CONNECT support:
+
+ dst := r.RequestURI
+ c, err := dialer(r.Context(), "tcp", dst)
+ if err != nil {
+ w.Header().Set("Tailscale-Connect-Error", err.Error())
+ http.Error(w, err.Error(), 500)
+ return
+ }
+ defer c.Close()
+
+ cc, ccbuf, err := w.(http.Hijacker).Hijack()
+ if err != nil {
+ http.Error(w, err.Error(), 500)
+ return
+ }
+ defer cc.Close()
+
+ io.WriteString(cc, "HTTP/1.1 200 OK\r\n\r\n")
+
+ var clientSrc io.Reader = ccbuf
+ if ccbuf.Reader.Buffered() == 0 {
+ // In the common case (with no
+ // buffered data), read directly from
+ // the underlying client connection to
+ // save some memory, letting the
+ // bufio.Reader/Writer get GC'ed.
+ clientSrc = cc
+ }
+
+ errc := make(chan error, 1)
+ go func() {
+ _, err := io.Copy(cc, c)
+ errc <- err
+ }()
+ go func() {
+ _, err := io.Copy(c, clientSrc)
+ errc <- err
+ }()
+ <-errc
+ })
+}
diff --git a/cmd/tailscaled/sigpipe.go b/cmd/tailscaled/sigpipe.go
index 2fcdab2a4..695a88024 100644
--- a/cmd/tailscaled/sigpipe.go
+++ b/cmd/tailscaled/sigpipe.go
@@ -1,12 +1,12 @@
-// Copyright (c) Tailscale Inc & AUTHORS
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build go1.21 && !plan9
-
-package main
-
-import "syscall"
-
-func init() {
- sigPipe = syscall.SIGPIPE
-}
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build go1.21 && !plan9
+
+package main
+
+import "syscall"
+
+func init() {
+ sigPipe = syscall.SIGPIPE
+}
diff --git a/cmd/tailscaled/tailscaled.defaults b/cmd/tailscaled/tailscaled.defaults
index e8384a4f8..693a6190b 100644
--- a/cmd/tailscaled/tailscaled.defaults
+++ b/cmd/tailscaled/tailscaled.defaults
@@ -1,8 +1,8 @@
-# Set the port to listen on for incoming VPN packets.
-# Remote nodes will automatically be informed about the new port number,
-# but you might want to configure this in order to set external firewall
-# settings.
-PORT="41641"
-
-# Extra flags you might want to pass to tailscaled.
-FLAGS=""
+# Set the port to listen on for incoming VPN packets.
+# Remote nodes will automatically be informed about the new port number,
+# but you might want to configure this in order to set external firewall
+# settings.
+PORT="41641"
+
+# Extra flags you might want to pass to tailscaled.
+FLAGS=""
diff --git a/cmd/tailscaled/tailscaled.openrc b/cmd/tailscaled/tailscaled.openrc
index 309d70f23..6193247ce 100755
--- a/cmd/tailscaled/tailscaled.openrc
+++ b/cmd/tailscaled/tailscaled.openrc
@@ -1,25 +1,25 @@
-#!/sbin/openrc-run
-
-set -a
-source /etc/default/tailscaled
-set +a
-
-command="/usr/sbin/tailscaled"
-command_args="--state=/var/lib/tailscale/tailscaled.state --port=$PORT --socket=/var/run/tailscale/tailscaled.sock $FLAGS"
-command_background=true
-pidfile="/run/tailscaled.pid"
-start_stop_daemon_args="-1 /var/log/tailscaled.log -2 /var/log/tailscaled.log"
-
-depend() {
- need net
-}
-
-start_pre() {
- mkdir -p /var/run/tailscale
- mkdir -p /var/lib/tailscale
- $command --cleanup
-}
-
-stop_post() {
- $command --cleanup
-}
+#!/sbin/openrc-run
+
+set -a
+source /etc/default/tailscaled
+set +a
+
+command="/usr/sbin/tailscaled"
+command_args="--state=/var/lib/tailscale/tailscaled.state --port=$PORT --socket=/var/run/tailscale/tailscaled.sock $FLAGS"
+command_background=true
+pidfile="/run/tailscaled.pid"
+start_stop_daemon_args="-1 /var/log/tailscaled.log -2 /var/log/tailscaled.log"
+
+depend() {
+ need net
+}
+
+start_pre() {
+ mkdir -p /var/run/tailscale
+ mkdir -p /var/lib/tailscale
+ $command --cleanup
+}
+
+stop_post() {
+ $command --cleanup
+}
diff --git a/cmd/tailscaled/tailscaled_bird.go b/cmd/tailscaled/tailscaled_bird.go
index c76f77bec..885f552cb 100644
--- a/cmd/tailscaled/tailscaled_bird.go
+++ b/cmd/tailscaled/tailscaled_bird.go
@@ -1,17 +1,17 @@
-// Copyright (c) Tailscale Inc & AUTHORS
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build go1.19 && (linux || darwin || freebsd || openbsd) && !ts_omit_bird
-
-package main
-
-import (
- "tailscale.com/chirp"
- "tailscale.com/wgengine"
-)
-
-func init() {
- createBIRDClient = func(ctlSocket string) (wgengine.BIRDClient, error) {
- return chirp.New(ctlSocket)
- }
-}
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build go1.19 && (linux || darwin || freebsd || openbsd) && !ts_omit_bird
+
+package main
+
+import (
+ "tailscale.com/chirp"
+ "tailscale.com/wgengine"
+)
+
+func init() {
+ createBIRDClient = func(ctlSocket string) (wgengine.BIRDClient, error) {
+ return chirp.New(ctlSocket)
+ }
+}
diff --git a/cmd/tailscaled/tailscaled_notwindows.go b/cmd/tailscaled/tailscaled_notwindows.go
index d5361cf28..b0a7c1598 100644
--- a/cmd/tailscaled/tailscaled_notwindows.go
+++ b/cmd/tailscaled/tailscaled_notwindows.go
@@ -1,14 +1,14 @@
-// Copyright (c) Tailscale Inc & AUTHORS
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build !windows && go1.19
-
-package main // import "tailscale.com/cmd/tailscaled"
-
-import "tailscale.com/logpolicy"
-
-func isWindowsService() bool { return false }
-
-func runWindowsService(pol *logpolicy.Policy) error { panic("unreachable") }
-
-func beWindowsSubprocess() bool { return false }
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build !windows && go1.19
+
+package main // import "tailscale.com/cmd/tailscaled"
+
+import "tailscale.com/logpolicy"
+
+func isWindowsService() bool { return false }
+
+func runWindowsService(pol *logpolicy.Policy) error { panic("unreachable") }
+
+func beWindowsSubprocess() bool { return false }
diff --git a/cmd/tailscaled/windows-manifest.xml b/cmd/tailscaled/windows-manifest.xml
index 6c5f46058..5eaa54fa5 100644
--- a/cmd/tailscaled/windows-manifest.xml
+++ b/cmd/tailscaled/windows-manifest.xml
@@ -1,13 +1,13 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
-
- <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
- <application>
- <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!-- Windows 7 -->
- <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> <!-- Windows 8 -->
- <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> <!-- Windows 8.1 -->
- <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <!-- Windows 10 -->
- </application>
- </compatibility>
-
-</assembly>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!-- Windows 7 -->
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> <!-- Windows 8 -->
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> <!-- Windows 8.1 -->
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <!-- Windows 10 -->
+ </application>
+ </compatibility>
+
+</assembly>
diff --git a/cmd/tailscaled/with_cli.go b/cmd/tailscaled/with_cli.go
index a8554eb8c..f191fdb45 100644
--- a/cmd/tailscaled/with_cli.go
+++ b/cmd/tailscaled/with_cli.go
@@ -1,23 +1,23 @@
-// Copyright (c) Tailscale Inc & AUTHORS
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build ts_include_cli
-
-package main
-
-import (
- "fmt"
- "os"
-
- "tailscale.com/cmd/tailscale/cli"
-)
-
-func init() {
- beCLI = func() {
- args := os.Args[1:]
- if err := cli.Run(args); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- }
-}
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build ts_include_cli
+
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "tailscale.com/cmd/tailscale/cli"
+)
+
+func init() {
+ beCLI = func() {
+ args := os.Args[1:]
+ if err := cli.Run(args); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ }
+}