diff options
Diffstat (limited to 'cmd/tailscaled')
| -rw-r--r-- | cmd/tailscaled/childproc/childproc.go | 38 | ||||
| -rw-r--r-- | cmd/tailscaled/generate.go | 16 | ||||
| -rw-r--r-- | cmd/tailscaled/install_darwin.go | 398 | ||||
| -rw-r--r-- | cmd/tailscaled/install_windows.go | 248 | ||||
| -rw-r--r-- | cmd/tailscaled/proxy.go | 160 | ||||
| -rw-r--r-- | cmd/tailscaled/sigpipe.go | 24 | ||||
| -rw-r--r-- | cmd/tailscaled/tailscaled.defaults | 16 | ||||
| -rwxr-xr-x | cmd/tailscaled/tailscaled.openrc | 50 | ||||
| -rw-r--r-- | cmd/tailscaled/tailscaled_bird.go | 34 | ||||
| -rw-r--r-- | cmd/tailscaled/tailscaled_notwindows.go | 28 | ||||
| -rw-r--r-- | cmd/tailscaled/windows-manifest.xml | 26 | ||||
| -rw-r--r-- | cmd/tailscaled/with_cli.go | 46 |
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)
+ }
+ }
+}
|
