diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt index bf6772000..cc77202b6 100644 --- a/cmd/tailscaled/depaware.txt +++ b/cmd/tailscaled/depaware.txt @@ -19,7 +19,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de github.com/klauspost/compress/zstd/internal/xxhash from github.com/klauspost/compress/zstd L 💣 github.com/mdlayher/netlink from github.com/jsimonetti/rtnetlink+ L 💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+ - github.com/pborman/getopt/v2 from tailscale.com/cmd/tailscaled W 💣 github.com/tailscale/winipcfg-go from tailscale.com/net/interfaces+ 💣 github.com/tailscale/wireguard-go/conn from github.com/tailscale/wireguard-go/device+ 💣 github.com/tailscale/wireguard-go/device from tailscale.com/wgengine+ @@ -76,6 +75,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de DW tailscale.com/tempfork/osexec from tailscale.com/portlist W tailscale.com/tsconst from tailscale.com/net/interfaces tailscale.com/types/empty from tailscale.com/control/controlclient+ + tailscale.com/types/flagtype from tailscale.com/cmd/tailscaled tailscale.com/types/key from tailscale.com/derp+ tailscale.com/types/logger from tailscale.com/cmd/tailscaled+ tailscale.com/types/nettype from tailscale.com/wgengine/magicsock @@ -181,7 +181,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de encoding/pem from crypto/tls+ errors from bufio+ expvar from tailscale.com/derp+ - L flag from tailscale.com/net/netns + flag from tailscale.com/cmd/tailscaled+ fmt from compress/flate+ hash from compress/zlib+ hash/adler32 from compress/zlib diff --git a/cmd/tailscaled/tailscaled.go b/cmd/tailscaled/tailscaled.go index a9226c0ee..995277cd4 100644 --- a/cmd/tailscaled/tailscaled.go +++ b/cmd/tailscaled/tailscaled.go @@ -11,6 +11,7 @@ package main // import "tailscale.com/cmd/tailscaled" import ( "context" + "flag" "log" "net/http" "net/http/pprof" @@ -22,10 +23,10 @@ import ( "time" "github.com/apenwarr/fixconsole" - "github.com/pborman/getopt/v2" "tailscale.com/ipn/ipnserver" "tailscale.com/logpolicy" "tailscale.com/paths" + "tailscale.com/types/flagtype" "tailscale.com/types/logger" "tailscale.com/wgengine" "tailscale.com/wgengine/magicsock" @@ -71,28 +72,22 @@ func main() { debug.SetGCPercent(10) } - // Set default values for getopt. - args.tunname = defaultTunName() - args.port = magicsock.DefaultPort - args.statepath = paths.DefaultTailscaledStateFile() - args.socketpath = paths.DefaultTailscaledSocket() - - getopt.FlagLong(&args.cleanup, "cleanup", 0, "clean up system state and exit") - getopt.FlagLong(&args.fake, "fake", 0, "fake tunnel+routing instead of tuntap") - getopt.FlagLong(&args.debug, "debug", 0, "address of debug server") - getopt.FlagLong(&args.tunname, "tun", 0, "tunnel interface name") - getopt.FlagLong(&args.port, "port", 'p', "WireGuard port (0=autoselect)") - getopt.FlagLong(&args.statepath, "state", 0, "path of state file") - getopt.FlagLong(&args.socketpath, "socket", 's', "path of the service unix socket") + flag.BoolVar(&args.cleanup, "cleanup", false, "clean up system state and exit") + flag.BoolVar(&args.fake, "fake", false, "use userspace fake tunnel+routing instead of kernel TUN interface") + flag.StringVar(&args.debug, "debug", "", "listen address ([ip]:port) of optional debug server") + flag.StringVar(&args.tunname, "tun", defaultTunName(), "tunnel interface name") + flag.Var(flagtype.PortValue(&args.port, magicsock.DefaultPort), "port", "UDP port to listen on for WireGuard and peer-to-peer traffic; 0 means automatically select") + flag.StringVar(&args.statepath, "state", paths.DefaultTailscaledStateFile(), "path of state file") + flag.StringVar(&args.socketpath, "socket", paths.DefaultTailscaledSocket(), "path of the service unix socket") err := fixconsole.FixConsoleIfNeeded() if err != nil { log.Fatalf("fixConsoleOutput: %v", err) } - getopt.Parse() - if len(getopt.Args()) > 0 { - log.Fatalf("too many non-flag arguments: %#v", getopt.Args()[0]) + flag.Parse() + if flag.NArg() > 0 { + log.Fatalf("tailscaled does not take non-flag arguments: %q", flag.Args()) } if args.statepath == "" { @@ -136,7 +131,7 @@ func run() error { var e wgengine.Engine if args.fake { - e, err = wgengine.NewFakeUserspaceEngine(logf, 0) + e, err = wgengine.NewFakeUserspaceEngine(logf, args.port) } else { e, err = wgengine.NewUserspaceEngine(logf, args.tunname, args.port) } diff --git a/types/flagtype/flagtype.go b/types/flagtype/flagtype.go new file mode 100644 index 000000000..ceab09869 --- /dev/null +++ b/types/flagtype/flagtype.go @@ -0,0 +1,41 @@ +// Copyright (c) 2020 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 flagtype defines flag.Value types. +package flagtype + +import ( + "errors" + "flag" + "fmt" + "math" + "strconv" + "strings" +) + +type portValue struct{ n *uint16 } + +func PortValue(dst *uint16, defaultPort uint16) flag.Value { + *dst = defaultPort + return portValue{dst} +} + +func (p portValue) String() string { return fmt.Sprint(p.n) } +func (p portValue) Set(v string) error { + if v == "" { + return errors.New("can't be the empty string") + } + if strings.Contains(v, ":") { + return errors.New("expecting just a port number, without a colon") + } + n, err := strconv.ParseUint(v, 10, 64) // use 64 instead of 16 to return nicer error message + if err != nil { + return fmt.Errorf("not a valid number") + } + if n > math.MaxUint16 { + return errors.New("out of range for port number") + } + *p.n = uint16(n) + return nil +}