diff --git a/cmd/tailscale/cli/cli_test.go b/cmd/tailscale/cli/cli_test.go index 2456c1e83..64b1ea923 100644 --- a/cmd/tailscale/cli/cli_test.go +++ b/cmd/tailscale/cli/cli_test.go @@ -145,7 +145,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) { flagSet: f("authkey"), curPrefs: ipn.NewPrefs(), mp: &ipn.MaskedPrefs{ - Prefs: *defaultPrefsFromUpArgs(t), + Prefs: *defaultPrefsFromUpArgs(t, "linux"), WantRunningSet: true, }, want: "", @@ -382,13 +382,8 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) { } } -func defaultPrefsFromUpArgs(t testing.TB) *ipn.Prefs { - upFlagSet.Parse(nil) // populates upArgs - if upFlagSet.Lookup("netfilter-mode") == nil && upArgs.netfilterMode == "" { - // This flag is not compiled on on-Linux platforms, - // but prefsFromUpArgs requires it be populated. - upArgs.netfilterMode = defaultNetfilterMode() - } +func defaultPrefsFromUpArgs(t testing.TB, goos string) *ipn.Prefs { + upArgs := defaultUpArgsByGOOS(goos) prefs, err := prefsFromUpArgs(upArgs, logger.Discard, new(ipnstate.Status), "linux") if err != nil { t.Fatalf("defaultPrefsFromUpArgs: %v", err) @@ -397,6 +392,12 @@ func defaultPrefsFromUpArgs(t testing.TB) *ipn.Prefs { return prefs } +func defaultUpArgsByGOOS(goos string) (args upArgsT) { + fs := newUpFlagSet(goos, &args) + fs.Parse(nil) // populates args + return +} + func TestPrefsFromUpArgs(t *testing.T) { tests := []struct { name string @@ -408,13 +409,29 @@ func TestPrefsFromUpArgs(t *testing.T) { wantWarn string }{ { - name: "zero", - goos: "windows", - args: upArgsT{}, + name: "default_linux", + goos: "linux", + args: defaultUpArgsByGOOS("linux"), want: &ipn.Prefs{ - WantRunning: true, - NoSNAT: true, - NetfilterMode: preftype.NetfilterOn, // silly, but default from ipn.NewPref currently + ControlURL: ipn.DefaultControlURL, + WantRunning: true, + NoSNAT: false, + NetfilterMode: preftype.NetfilterOn, + CorpDNS: true, + AllowSingleHosts: true, + }, + }, + { + name: "default_windows", + goos: "windows", + args: defaultUpArgsByGOOS("windows"), + want: &ipn.Prefs{ + ControlURL: ipn.DefaultControlURL, + WantRunning: true, + CorpDNS: true, + AllowSingleHosts: true, + NetfilterMode: preftype.NetfilterOn, + NoSNAT: true, }, }, { diff --git a/cmd/tailscale/cli/up.go b/cmd/tailscale/cli/up.go index c9556e192..26e16d5ce 100644 --- a/cmd/tailscale/cli/up.go +++ b/cmd/tailscale/cli/up.go @@ -52,7 +52,9 @@ flag is also used. Exec: runUp, } -var upFlagSet = (func() *flag.FlagSet { +var upFlagSet = newUpFlagSet(runtime.GOOS, &upArgs) + +func newUpFlagSet(goos string, upArgs *upArgsT) *flag.FlagSet { upf := flag.NewFlagSet("up", flag.ExitOnError) upf.BoolVar(&upArgs.forceReauth, "force-reauth", false, "force reauthentication") @@ -70,18 +72,18 @@ var upFlagSet = (func() *flag.FlagSet { upf.StringVar(&upArgs.hostname, "hostname", "", "hostname to use instead of the one provided by the OS") upf.StringVar(&upArgs.advertiseRoutes, "advertise-routes", "", "routes to advertise to other nodes (comma-separated, e.g. \"10.0.0.0/8,192.168.0.0/24\")") upf.BoolVar(&upArgs.advertiseDefaultRoute, "advertise-exit-node", false, "offer to be an exit node for internet traffic for the tailnet") - if safesocket.PlatformUsesPeerCreds() { + if safesocket.GOOSUsesPeerCreds(goos) { upf.StringVar(&upArgs.opUser, "operator", "", "Unix username to allow to operate on tailscaled without sudo") } - if runtime.GOOS == "linux" { + switch goos { + case "linux": upf.BoolVar(&upArgs.snat, "snat-subnet-routes", true, "source NAT traffic to local routes advertised with --advertise-routes") upf.StringVar(&upArgs.netfilterMode, "netfilter-mode", defaultNetfilterMode(), "netfilter mode (one of on, nodivert, off)") - } - if runtime.GOOS == "windows" { + case "windows": upf.BoolVar(&upArgs.forceDaemon, "unattended", false, "run in \"Unattended Mode\" where Tailscale keeps running even after the current GUI user logs out (Windows-only)") } return upf -})() +} func defaultNetfilterMode() string { if distro.Get() == distro.Synology { diff --git a/safesocket/safesocket.go b/safesocket/safesocket.go index 9f93117f3..f415bc11e 100644 --- a/safesocket/safesocket.go +++ b/safesocket/safesocket.go @@ -61,8 +61,12 @@ func LocalTCPPortAndToken() (port int, token string, err error) { // PlatformUsesPeerCreds reports whether the current platform uses peer credentials // to authenticate connections. -func PlatformUsesPeerCreds() bool { - switch runtime.GOOS { +func PlatformUsesPeerCreds() bool { return GOOSUsesPeerCreds(runtime.GOOS) } + +// GOOSUsesPeerCreds is like PlatformUsesPeerCreds but takes a +// runtime.GOOS value instead of using the current one. +func GOOSUsesPeerCreds(goos string) bool { + switch goos { case "linux", "darwin", "freebsd": return true }