mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 19:15:34 +00:00
envknob: add new package for all the strconv.ParseBool(os.Getenv(..))
A new package can also later record/report which knobs are checked and set. It also makes the code cleaner & easier to grep for env knobs. Change-Id: Id8a123ab7539f1fadbd27e0cbeac79c2e4f09751 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
6feb8f4c51
commit
41fd4eab5c
@ -16,7 +16,6 @@
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
@ -26,6 +25,7 @@
|
|||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/client/tailscale"
|
"tailscale.com/client/tailscale"
|
||||||
"tailscale.com/client/tailscale/apitype"
|
"tailscale.com/client/tailscale/apitype"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
@ -148,7 +148,7 @@ func runCp(ctx context.Context, args []string) error {
|
|||||||
name = filepath.Base(fileArg)
|
name = filepath.Base(fileArg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if slow, _ := strconv.ParseBool(os.Getenv("TS_DEBUG_SLOW_PUSH")); slow {
|
if envknob.Bool("TS_DEBUG_SLOW_PUSH") {
|
||||||
fileContents = &slowReader{r: fileContents}
|
fileContents = &slowReader{r: fileContents}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,13 @@
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/peterbourgon/ff/v3/ffcli"
|
"github.com/peterbourgon/ff/v3/ffcli"
|
||||||
"tailscale.com/client/tailscale"
|
"tailscale.com/client/tailscale"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/net/netcheck"
|
"tailscale.com/net/netcheck"
|
||||||
"tailscale.com/net/portmapper"
|
"tailscale.com/net/portmapper"
|
||||||
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
func runNetcheck(ctx context.Context, args []string) error {
|
func runNetcheck(ctx context.Context, args []string) error {
|
||||||
c := &netcheck.Client{
|
c := &netcheck.Client{
|
||||||
UDPBindAddr: os.Getenv("TS_DEBUG_NETCHECK_UDP_BIND"),
|
UDPBindAddr: envknob.String("TS_DEBUG_NETCHECK_UDP_BIND"),
|
||||||
PortMapper: portmapper.NewClient(logger.WithPrefix(log.Printf, "portmap: "), nil),
|
PortMapper: portmapper.NewClient(logger.WithPrefix(log.Printf, "portmap: "), nil),
|
||||||
}
|
}
|
||||||
if netcheckArgs.verbose {
|
if netcheckArgs.verbose {
|
||||||
|
@ -38,6 +38,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
|||||||
tailscale.com/derp/derphttp from tailscale.com/net/netcheck
|
tailscale.com/derp/derphttp from tailscale.com/net/netcheck
|
||||||
L tailscale.com/derp/wsconn from tailscale.com/derp/derphttp
|
L tailscale.com/derp/wsconn from tailscale.com/derp/derphttp
|
||||||
tailscale.com/disco from tailscale.com/derp
|
tailscale.com/disco from tailscale.com/derp
|
||||||
|
tailscale.com/envknob from tailscale.com/cmd/tailscale/cli+
|
||||||
tailscale.com/hostinfo from tailscale.com/net/interfaces
|
tailscale.com/hostinfo from tailscale.com/net/interfaces
|
||||||
tailscale.com/ipn from tailscale.com/cmd/tailscale/cli+
|
tailscale.com/ipn from tailscale.com/cmd/tailscale/cli+
|
||||||
tailscale.com/ipn/ipnstate from tailscale.com/cmd/tailscale/cli+
|
tailscale.com/ipn/ipnstate from tailscale.com/cmd/tailscale/cli+
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/derp/derphttp"
|
"tailscale.com/derp/derphttp"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/portmapper"
|
"tailscale.com/net/portmapper"
|
||||||
@ -224,7 +225,7 @@ func debugPortmap(ctx context.Context) error {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
portmapper.VerboseLogs = true
|
portmapper.VerboseLogs = true
|
||||||
switch os.Getenv("TS_DEBUG_PORTMAP_TYPE") {
|
switch envknob.String("TS_DEBUG_PORTMAP_TYPE") {
|
||||||
case "":
|
case "":
|
||||||
case "pmp":
|
case "pmp":
|
||||||
portmapper.DisablePCP = true
|
portmapper.DisablePCP = true
|
||||||
|
@ -171,6 +171,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/derp/derphttp from tailscale.com/cmd/tailscaled+
|
tailscale.com/derp/derphttp from tailscale.com/cmd/tailscaled+
|
||||||
L tailscale.com/derp/wsconn from tailscale.com/derp/derphttp
|
L tailscale.com/derp/wsconn from tailscale.com/derp/derphttp
|
||||||
tailscale.com/disco from tailscale.com/derp+
|
tailscale.com/disco from tailscale.com/derp+
|
||||||
|
tailscale.com/envknob from tailscale.com/cmd/tailscaled+
|
||||||
tailscale.com/health from tailscale.com/control/controlclient+
|
tailscale.com/health from tailscale.com/control/controlclient+
|
||||||
tailscale.com/hostinfo from tailscale.com/control/controlclient+
|
tailscale.com/hostinfo from tailscale.com/control/controlclient+
|
||||||
tailscale.com/ipn from tailscale.com/client/tailscale+
|
tailscale.com/ipn from tailscale.com/client/tailscale+
|
||||||
|
@ -23,12 +23,12 @@
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/ipn/ipnserver"
|
"tailscale.com/ipn/ipnserver"
|
||||||
"tailscale.com/logpolicy"
|
"tailscale.com/logpolicy"
|
||||||
@ -224,7 +224,7 @@ func statePathOrDefault() string {
|
|||||||
func ipnServerOpts() (o ipnserver.Options) {
|
func ipnServerOpts() (o ipnserver.Options) {
|
||||||
// Allow changing the OS-specific IPN behavior for tests
|
// Allow changing the OS-specific IPN behavior for tests
|
||||||
// so we can e.g. test Windows-specific behaviors on Linux.
|
// so we can e.g. test Windows-specific behaviors on Linux.
|
||||||
goos := os.Getenv("TS_DEBUG_TAILSCALED_IPN_GOOS")
|
goos := envknob.String("TS_DEBUG_TAILSCALED_IPN_GOOS")
|
||||||
if goos == "" {
|
if goos == "" {
|
||||||
goos = runtime.GOOS
|
goos = runtime.GOOS
|
||||||
}
|
}
|
||||||
@ -272,13 +272,13 @@ func run() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var logf logger.Logf = log.Printf
|
var logf logger.Logf = log.Printf
|
||||||
if v, _ := strconv.ParseBool(os.Getenv("TS_DEBUG_MEMORY")); v {
|
if envknob.Bool("TS_DEBUG_MEMORY") {
|
||||||
logf = logger.RusagePrefixLog(logf)
|
logf = logger.RusagePrefixLog(logf)
|
||||||
}
|
}
|
||||||
logf = logger.RateLimitedFn(logf, 5*time.Second, 5, 100)
|
logf = logger.RateLimitedFn(logf, 5*time.Second, 5, 100)
|
||||||
|
|
||||||
if args.cleanup {
|
if args.cleanup {
|
||||||
if os.Getenv("TS_PLEASE_PANIC") != "" {
|
if envknob.Bool("TS_PLEASE_PANIC") {
|
||||||
panic("TS_PLEASE_PANIC asked us to panic")
|
panic("TS_PLEASE_PANIC asked us to panic")
|
||||||
}
|
}
|
||||||
dns.Cleanup(logf, args.tunname)
|
dns.Cleanup(logf, args.tunname)
|
||||||
@ -431,11 +431,7 @@ func createEngine(logf logger.Logf, linkMon *monitor.Mon, dialer *tsdial.Dialer)
|
|||||||
var wrapNetstack = shouldWrapNetstack()
|
var wrapNetstack = shouldWrapNetstack()
|
||||||
|
|
||||||
func shouldWrapNetstack() bool {
|
func shouldWrapNetstack() bool {
|
||||||
if e := os.Getenv("TS_DEBUG_WRAP_NETSTACK"); e != "" {
|
if v, ok := envknob.LookupBool("TS_DEBUG_WRAP_NETSTACK"); ok {
|
||||||
v, err := strconv.ParseBool(e)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("invalid TS_DEBUG_WRAP_NETSTACK value: %v", err)
|
|
||||||
}
|
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
if distro.Get() == distro.Synology {
|
if distro.Get() == distro.Synology {
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
"golang.org/x/sys/windows/svc"
|
"golang.org/x/sys/windows/svc"
|
||||||
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/ipn/ipnserver"
|
"tailscale.com/ipn/ipnserver"
|
||||||
"tailscale.com/logpolicy"
|
"tailscale.com/logpolicy"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
@ -314,7 +315,7 @@ type engineOrError struct {
|
|||||||
// not called concurrently and is not called again once it
|
// not called concurrently and is not called again once it
|
||||||
// successfully returns an engine.
|
// successfully returns an engine.
|
||||||
getEngine := func() (wgengine.Engine, error) {
|
getEngine := func() (wgengine.Engine, error) {
|
||||||
if msg := os.Getenv("TS_DEBUG_WIN_FAIL"); msg != "" {
|
if msg := envknob.String("TS_DEBUG_WIN_FAIL"); msg != "" {
|
||||||
return nil, fmt.Errorf("pretending to be a service failure: %v", msg)
|
return nil, fmt.Errorf("pretending to be a service failure: %v", msg)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@ -30,6 +29,7 @@
|
|||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/control/controlknobs"
|
"tailscale.com/control/controlknobs"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/health"
|
"tailscale.com/health"
|
||||||
"tailscale.com/hostinfo"
|
"tailscale.com/hostinfo"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
@ -874,8 +874,8 @@ func decode(res *http.Response, v interface{}, serverKey key.MachinePublic, mkey
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
debugMap, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_MAP"))
|
debugMap = envknob.Bool("TS_DEBUG_MAP")
|
||||||
debugRegister, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_REGISTER"))
|
debugRegister = envknob.Bool("TS_DEBUG_REGISTER")
|
||||||
)
|
)
|
||||||
|
|
||||||
var jsonEscapedZero = []byte(`\u0000`)
|
var jsonEscapedZero = []byte(`\u0000`)
|
||||||
@ -985,26 +985,14 @@ type debug struct {
|
|||||||
|
|
||||||
func initDebug() debug {
|
func initDebug() debug {
|
||||||
return debug{
|
return debug{
|
||||||
NetMap: envBool("TS_DEBUG_NETMAP"),
|
NetMap: envknob.Bool("TS_DEBUG_NETMAP"),
|
||||||
ProxyDNS: envBool("TS_DEBUG_PROXY_DNS"),
|
ProxyDNS: envknob.Bool("TS_DEBUG_PROXY_DNS"),
|
||||||
StripEndpoints: envBool("TS_DEBUG_STRIP_ENDPOINTS"),
|
StripEndpoints: envknob.Bool("TS_DEBUG_STRIP_ENDPOINTS"),
|
||||||
StripCaps: envBool("TS_DEBUG_STRIP_CAPS"),
|
StripCaps: envknob.Bool("TS_DEBUG_STRIP_CAPS"),
|
||||||
Disco: os.Getenv("TS_DEBUG_USE_DISCO") == "" || envBool("TS_DEBUG_USE_DISCO"),
|
Disco: envknob.BoolDefaultTrue("TS_DEBUG_USE_DISCO"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func envBool(k string) bool {
|
|
||||||
e := os.Getenv(k)
|
|
||||||
if e == "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
v, err := strconv.ParseBool(e)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("invalid non-bool %q for env var %q", e, k))
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
var clockNow = time.Now
|
var clockNow = time.Now
|
||||||
|
|
||||||
// opt.Bool configs from control.
|
// opt.Bool configs from control.
|
||||||
|
@ -6,11 +6,10 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@ -289,7 +288,7 @@ func cloneNodes(v1 []*tailcfg.Node) []*tailcfg.Node {
|
|||||||
return v2
|
return v2
|
||||||
}
|
}
|
||||||
|
|
||||||
var debugSelfIPv6Only, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_SELF_V6_ONLY"))
|
var debugSelfIPv6Only = envknob.Bool("TS_DEBUG_SELF_V6_ONLY")
|
||||||
|
|
||||||
func filterSelfAddresses(in []netaddr.IPPrefix) (ret []netaddr.IPPrefix) {
|
func filterSelfAddresses(in []netaddr.IPPrefix) (ret []netaddr.IPPrefix) {
|
||||||
switch {
|
switch {
|
||||||
|
@ -7,9 +7,7 @@
|
|||||||
package controlknobs
|
package controlknobs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"tailscale.com/envknob"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"tailscale.com/syncs"
|
"tailscale.com/syncs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,8 +15,7 @@
|
|||||||
var disableUPnP syncs.AtomicBool
|
var disableUPnP syncs.AtomicBool
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
v, _ := strconv.ParseBool(os.Getenv("TS_DISABLE_UPNP"))
|
SetDisableUPnP(envknob.Bool("TS_DISABLE_UPNP"))
|
||||||
SetDisableUPnP(v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisableUPnP reports the last reported value from control
|
// DisableUPnP reports the last reported value from control
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -40,6 +39,7 @@
|
|||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/client/tailscale"
|
"tailscale.com/client/tailscale"
|
||||||
"tailscale.com/disco"
|
"tailscale.com/disco"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/metrics"
|
"tailscale.com/metrics"
|
||||||
"tailscale.com/syncs"
|
"tailscale.com/syncs"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
@ -48,14 +48,14 @@
|
|||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
var debug, _ = strconv.ParseBool(os.Getenv("DERP_DEBUG_LOGS"))
|
var debug = envknob.Bool("DERP_DEBUG_LOGS")
|
||||||
|
|
||||||
// verboseDropKeys is the set of destination public keys that should
|
// verboseDropKeys is the set of destination public keys that should
|
||||||
// verbosely log whenever DERP drops a packet.
|
// verbosely log whenever DERP drops a packet.
|
||||||
var verboseDropKeys = map[key.NodePublic]bool{}
|
var verboseDropKeys = map[key.NodePublic]bool{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
keys := os.Getenv("TS_DEBUG_VERBOSE_DROPS")
|
keys := envknob.String("TS_DEBUG_VERBOSE_DROPS")
|
||||||
if keys == "" {
|
if keys == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,7 @@
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -33,6 +31,7 @@
|
|||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/derp"
|
"tailscale.com/derp"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/net/dnscache"
|
"tailscale.com/net/dnscache"
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/net/tlsdial"
|
"tailscale.com/net/tlsdial"
|
||||||
@ -190,8 +189,7 @@ func useWebsockets() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if dialWebsocketFunc != nil {
|
if dialWebsocketFunc != nil {
|
||||||
v, _ := strconv.ParseBool(os.Getenv("TS_DEBUG_DERP_WS_CLIENT"))
|
return envknob.Bool("TS_DEBUG_DERP_WS_CLIENT")
|
||||||
return v
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
102
envknob/envknob.go
Normal file
102
envknob/envknob.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// Copyright (c) 2022 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 envknob provides access to environment-variable tweakable
|
||||||
|
// debug settings.
|
||||||
|
//
|
||||||
|
// These are primarily knobs used by Tailscale developers during
|
||||||
|
// development or by users when instructed to by Tailscale developers
|
||||||
|
// when debugging something. They are not a stable interface and may
|
||||||
|
// be removed or any time.
|
||||||
|
//
|
||||||
|
// A related package, control/controlknobs, are knobs that can be
|
||||||
|
// changed at runtime by the control plane. Sometimes both are used:
|
||||||
|
// an envknob for the default/explicit value, else falling back
|
||||||
|
// to the controlknob value.
|
||||||
|
package envknob
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"tailscale.com/types/opt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the named environment variable, using os.Getenv.
|
||||||
|
//
|
||||||
|
// In the future it will also track usage for reporting on debug pages.
|
||||||
|
func String(envVar string) string {
|
||||||
|
return os.Getenv(envVar)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool returns the boolean value of the named environment variable.
|
||||||
|
// If the variable is not set, it returns false.
|
||||||
|
// An invalid value exits the binary with a failure.
|
||||||
|
func Bool(envVar string) bool {
|
||||||
|
return boolOr(envVar, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolDefaultTrue is like Bool, but returns true by default if the
|
||||||
|
// environment variable isn't present.
|
||||||
|
func BoolDefaultTrue(envVar string) bool {
|
||||||
|
return boolOr(envVar, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func boolOr(envVar string, implicitValue bool) bool {
|
||||||
|
val := os.Getenv(envVar)
|
||||||
|
if val == "" {
|
||||||
|
return implicitValue
|
||||||
|
}
|
||||||
|
b, err := strconv.ParseBool(val)
|
||||||
|
if err == nil {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
log.Fatalf("invalid environment variable %s value %q: %v", envVar, val, err)
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupBool returns the boolean value of the named environment value.
|
||||||
|
// The ok result is whether a value was set.
|
||||||
|
// If the value isn't a valid int, it exits the program with a failure.
|
||||||
|
func LookupBool(envVar string) (v bool, ok bool) {
|
||||||
|
val := os.Getenv(envVar)
|
||||||
|
if val == "" {
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
b, err := strconv.ParseBool(val)
|
||||||
|
if err == nil {
|
||||||
|
return b, true
|
||||||
|
}
|
||||||
|
log.Fatalf("invalid environment variable %s value %q: %v", envVar, val, err)
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// OptBool is like Bool, but returns an opt.Bool, so the caller can
|
||||||
|
// distinguish between implicitly and explicitly false.
|
||||||
|
func OptBool(envVar string) opt.Bool {
|
||||||
|
b, ok := LookupBool(envVar)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var ret opt.Bool
|
||||||
|
ret.Set(b)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupInt returns the integer value of the named environment value.
|
||||||
|
// The ok result is whether a value was set.
|
||||||
|
// If the value isn't a valid int, it exits the program with a failure.
|
||||||
|
func LookupInt(envVar string) (v int, ok bool) {
|
||||||
|
val := os.Getenv(envVar)
|
||||||
|
if val == "" {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
v, err := strconv.Atoi(val)
|
||||||
|
if err == nil {
|
||||||
|
return v, true
|
||||||
|
}
|
||||||
|
log.Fatalf("invalid environment variable %s value %q: %v", envVar, val, err)
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
@ -10,13 +10,13 @@
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/util/multierr"
|
"tailscale.com/util/multierr"
|
||||||
)
|
)
|
||||||
@ -308,7 +308,7 @@ func OverallError() error {
|
|||||||
return overallErrorLocked()
|
return overallErrorLocked()
|
||||||
}
|
}
|
||||||
|
|
||||||
var fakeErrForTesting = os.Getenv("TS_DEBUG_FAKE_HEALTH_ERROR")
|
var fakeErrForTesting = envknob.String("TS_DEBUG_FAKE_HEALTH_ERROR")
|
||||||
|
|
||||||
func overallErrorLocked() error {
|
func overallErrorLocked() error {
|
||||||
if !anyInterfaceUp {
|
if !anyInterfaceUp {
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/client/tailscale/apitype"
|
"tailscale.com/client/tailscale/apitype"
|
||||||
"tailscale.com/control/controlclient"
|
"tailscale.com/control/controlclient"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/health"
|
"tailscale.com/health"
|
||||||
"tailscale.com/hostinfo"
|
"tailscale.com/hostinfo"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
@ -64,7 +65,7 @@
|
|||||||
var controlDebugFlags = getControlDebugFlags()
|
var controlDebugFlags = getControlDebugFlags()
|
||||||
|
|
||||||
func getControlDebugFlags() []string {
|
func getControlDebugFlags() []string {
|
||||||
if e := os.Getenv("TS_DEBUG_CONTROL_FLAGS"); e != "" {
|
if e := envknob.String("TS_DEBUG_CONTROL_FLAGS"); e != "" {
|
||||||
return strings.Split(e, ",")
|
return strings.Split(e, ",")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -1349,7 +1350,7 @@ func (b *LocalBackend) popBrowserAuthNow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For testing lazy machine key generation.
|
// For testing lazy machine key generation.
|
||||||
var panicOnMachineKeyGeneration, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_PANIC_MACHINE_KEY"))
|
var panicOnMachineKeyGeneration = envknob.Bool("TS_DEBUG_PANIC_MACHINE_KEY")
|
||||||
|
|
||||||
func (b *LocalBackend) createGetMachinePrivateKeyFunc() func() (key.MachinePrivate, error) {
|
func (b *LocalBackend) createGetMachinePrivateKeyFunc() func() (key.MachinePrivate, error) {
|
||||||
var cache atomic.Value
|
var cache atomic.Value
|
||||||
|
@ -29,12 +29,12 @@
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/crypto/acme"
|
"golang.org/x/crypto/acme"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
@ -63,7 +63,7 @@ func (h *Handler) certDir() (string, error) {
|
|||||||
return full, nil
|
return full, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var acmeDebug, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_ACME"))
|
var acmeDebug = envknob.Bool("TS_DEBUG_ACME")
|
||||||
|
|
||||||
func (h *Handler) serveCert(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) serveCert(w http.ResponseWriter, r *http.Request) {
|
||||||
if !h.PermitWrite {
|
if !h.PermitWrite {
|
||||||
|
@ -25,13 +25,13 @@
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
"tailscale.com/atomicfile"
|
"tailscale.com/atomicfile"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/log/filelogger"
|
"tailscale.com/log/filelogger"
|
||||||
"tailscale.com/logtail"
|
"tailscale.com/logtail"
|
||||||
"tailscale.com/logtail/filch"
|
"tailscale.com/logtail/filch"
|
||||||
@ -227,7 +227,7 @@ func runningUnderSystemd() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func redirectStderrToLogPanics() bool {
|
func redirectStderrToLogPanics() bool {
|
||||||
return runningUnderSystemd() || os.Getenv("TS_PLEASE_PANIC") != ""
|
return runningUnderSystemd() || envknob.Bool("TS_PLEASE_PANIC")
|
||||||
}
|
}
|
||||||
|
|
||||||
// winProgramDataAccessible reports whether the directory (assumed to
|
// winProgramDataAccessible reports whether the directory (assumed to
|
||||||
@ -405,7 +405,7 @@ func New(collection string) *Policy {
|
|||||||
} else {
|
} else {
|
||||||
lflags = log.LstdFlags
|
lflags = log.LstdFlags
|
||||||
}
|
}
|
||||||
if v, _ := strconv.ParseBool(os.Getenv("TS_DEBUG_LOG_TIME")); v {
|
if envknob.Bool("TS_DEBUG_LOG_TIME") {
|
||||||
lflags = log.LstdFlags | log.Lmicroseconds
|
lflags = log.LstdFlags | log.Lmicroseconds
|
||||||
}
|
}
|
||||||
if runningUnderSystemd() {
|
if runningUnderSystemd() {
|
||||||
@ -670,7 +670,7 @@ func NewLogtailTransport(host string) *http.Transport {
|
|||||||
// TODO(bradfitz): remove this debug knob once we've decided
|
// TODO(bradfitz): remove this debug knob once we've decided
|
||||||
// to upload via HTTP/1 or HTTP/2 (probably HTTP/1). Or we might just enforce
|
// to upload via HTTP/1 or HTTP/2 (probably HTTP/1). Or we might just enforce
|
||||||
// it server-side.
|
// it server-side.
|
||||||
if h1, _ := strconv.ParseBool(os.Getenv("TS_DEBUG_FORCE_H1_LOGS")); h1 {
|
if envknob.Bool("TS_DEBUG_FORCE_H1_LOGS") {
|
||||||
tr.TLSClientConfig = nil // DefaultTransport's was already initialized w/ h2
|
tr.TLSClientConfig = nil // DefaultTransport's was already initialized w/ h2
|
||||||
tr.ForceAttemptHTTP2 = false
|
tr.ForceAttemptHTTP2 = false
|
||||||
tr.TLSNextProto = map[string]func(authority string, c *tls.Conn) http.RoundTripper{}
|
tr.TLSNextProto = map[string]func(authority string, c *tls.Conn) http.RoundTripper{}
|
||||||
|
@ -7,10 +7,8 @@
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
@ -19,6 +17,7 @@
|
|||||||
"golang.org/x/sys/windows/registry"
|
"golang.org/x/sys/windows/registry"
|
||||||
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
@ -36,7 +35,7 @@
|
|||||||
versionKey = `SOFTWARE\Microsoft\Windows NT\CurrentVersion`
|
versionKey = `SOFTWARE\Microsoft\Windows NT\CurrentVersion`
|
||||||
)
|
)
|
||||||
|
|
||||||
var configureWSL, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_CONFIGURE_WSL"))
|
var configureWSL = envknob.Bool("TS_DEBUG_CONFIGURE_WSL")
|
||||||
|
|
||||||
type windowsManager struct {
|
type windowsManager struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
|
@ -15,14 +15,13 @@
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/sync/singleflight"
|
"golang.org/x/sync/singleflight"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/envknob"
|
||||||
)
|
)
|
||||||
|
|
||||||
var single = &Resolver{
|
var single = &Resolver{
|
||||||
@ -100,7 +99,7 @@ func (r *Resolver) ttl() time.Duration {
|
|||||||
return 10 * time.Minute
|
return 10 * time.Minute
|
||||||
}
|
}
|
||||||
|
|
||||||
var debug, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_DNS_CACHE"))
|
var debug = envknob.Bool("TS_DEBUG_DNS_CACHE")
|
||||||
|
|
||||||
// LookupIP returns the host's primary IP address (either IPv4 or
|
// LookupIP returns the host's primary IP address (either IPv4 or
|
||||||
// IPv6, but preferring IPv4) and optionally its IPv6 address, if
|
// IPv6, but preferring IPv4) and optionally its IPv6 address, if
|
||||||
|
@ -16,16 +16,15 @@
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tcnksm/go-httpstat"
|
"github.com/tcnksm/go-httpstat"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/derp/derphttp"
|
"tailscale.com/derp/derphttp"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/neterror"
|
"tailscale.com/net/neterror"
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
@ -40,7 +39,7 @@
|
|||||||
|
|
||||||
// Debugging and experimentation tweakables.
|
// Debugging and experimentation tweakables.
|
||||||
var (
|
var (
|
||||||
debugNetcheck, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_NETCHECK"))
|
debugNetcheck = envknob.Bool("TS_DEBUG_NETCHECK")
|
||||||
)
|
)
|
||||||
|
|
||||||
// The various default timeouts for things.
|
// The various default timeouts for things.
|
||||||
|
@ -17,10 +17,11 @@
|
|||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tailscale.com/envknob"
|
||||||
)
|
)
|
||||||
|
|
||||||
var counterFallbackOK int32 // atomic
|
var counterFallbackOK int32 // atomic
|
||||||
@ -31,7 +32,7 @@
|
|||||||
// See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
|
// See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
|
||||||
var sslKeyLogFile = os.Getenv("SSLKEYLOGFILE")
|
var sslKeyLogFile = os.Getenv("SSLKEYLOGFILE")
|
||||||
|
|
||||||
var debug, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_TLS_DIAL"))
|
var debug = envknob.Bool("TS_DEBUG_TLS_DIAL")
|
||||||
|
|
||||||
// Config returns a tls.Config for connecting to a server.
|
// Config returns a tls.Config for connecting to a server.
|
||||||
// If base is non-nil, it's cloned as the base config before
|
// If base is non-nil, it's cloned as the base config before
|
||||||
|
@ -11,13 +11,12 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,7 +31,7 @@
|
|||||||
var tunMTU = 1280
|
var tunMTU = 1280
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if mtu, _ := strconv.Atoi(os.Getenv("TS_DEBUG_MTU")); mtu != 0 {
|
if mtu, ok := envknob.LookupInt("TS_DEBUG_MTU"); ok {
|
||||||
tunMTU = mtu
|
tunMTU = mtu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"tailscale.com/envknob"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Port is a listening port on the machine.
|
// Port is a listening port on the machine.
|
||||||
@ -74,7 +74,7 @@ func (pl List) String() string {
|
|||||||
return strings.TrimRight(sb.String(), "\n")
|
return strings.TrimRight(sb.String(), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
var debugDisablePortlist, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_DISABLE_PORTLIST"))
|
var debugDisablePortlist = envknob.Bool("TS_DEBUG_DISABLE_PORTLIST")
|
||||||
|
|
||||||
func GetList(prev List) (List, error) {
|
func GetList(prev List) (List, error) {
|
||||||
if debugDisablePortlist {
|
if debugDisablePortlist {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
check_file() {
|
check_file() {
|
||||||
got=$1
|
got=$1
|
||||||
|
|
||||||
for year in `seq 2019 2021`; do
|
for year in `seq 2019 2022`; do
|
||||||
want=$(cat <<EOF
|
want=$(cat <<EOF
|
||||||
// Copyright (c) $year Tailscale Inc & AUTHORS All rights reserved.
|
// Copyright (c) $year Tailscale Inc & AUTHORS All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
_ "inet.af/netaddr"
|
_ "inet.af/netaddr"
|
||||||
_ "tailscale.com/chirp"
|
_ "tailscale.com/chirp"
|
||||||
_ "tailscale.com/derp/derphttp"
|
_ "tailscale.com/derp/derphttp"
|
||||||
|
_ "tailscale.com/envknob"
|
||||||
_ "tailscale.com/ipn"
|
_ "tailscale.com/ipn"
|
||||||
_ "tailscale.com/ipn/ipnserver"
|
_ "tailscale.com/ipn/ipnserver"
|
||||||
_ "tailscale.com/logpolicy"
|
_ "tailscale.com/logpolicy"
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
_ "inet.af/netaddr"
|
_ "inet.af/netaddr"
|
||||||
_ "tailscale.com/chirp"
|
_ "tailscale.com/chirp"
|
||||||
_ "tailscale.com/derp/derphttp"
|
_ "tailscale.com/derp/derphttp"
|
||||||
|
_ "tailscale.com/envknob"
|
||||||
_ "tailscale.com/ipn"
|
_ "tailscale.com/ipn"
|
||||||
_ "tailscale.com/ipn/ipnserver"
|
_ "tailscale.com/ipn/ipnserver"
|
||||||
_ "tailscale.com/logpolicy"
|
_ "tailscale.com/logpolicy"
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
_ "inet.af/netaddr"
|
_ "inet.af/netaddr"
|
||||||
_ "tailscale.com/chirp"
|
_ "tailscale.com/chirp"
|
||||||
_ "tailscale.com/derp/derphttp"
|
_ "tailscale.com/derp/derphttp"
|
||||||
|
_ "tailscale.com/envknob"
|
||||||
_ "tailscale.com/ipn"
|
_ "tailscale.com/ipn"
|
||||||
_ "tailscale.com/ipn/ipnserver"
|
_ "tailscale.com/ipn/ipnserver"
|
||||||
_ "tailscale.com/logpolicy"
|
_ "tailscale.com/logpolicy"
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
_ "inet.af/netaddr"
|
_ "inet.af/netaddr"
|
||||||
_ "tailscale.com/chirp"
|
_ "tailscale.com/chirp"
|
||||||
_ "tailscale.com/derp/derphttp"
|
_ "tailscale.com/derp/derphttp"
|
||||||
|
_ "tailscale.com/envknob"
|
||||||
_ "tailscale.com/ipn"
|
_ "tailscale.com/ipn"
|
||||||
_ "tailscale.com/ipn/ipnserver"
|
_ "tailscale.com/ipn/ipnserver"
|
||||||
_ "tailscale.com/logpolicy"
|
_ "tailscale.com/logpolicy"
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
_ "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
_ "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
||||||
_ "inet.af/netaddr"
|
_ "inet.af/netaddr"
|
||||||
_ "tailscale.com/derp/derphttp"
|
_ "tailscale.com/derp/derphttp"
|
||||||
|
_ "tailscale.com/envknob"
|
||||||
_ "tailscale.com/ipn"
|
_ "tailscale.com/ipn"
|
||||||
_ "tailscale.com/ipn/ipnserver"
|
_ "tailscale.com/ipn/ipnserver"
|
||||||
_ "tailscale.com/logpolicy"
|
_ "tailscale.com/logpolicy"
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/metrics"
|
"tailscale.com/metrics"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@ -70,12 +71,12 @@ func AllowDebugAccess(r *http.Request) bool {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if tsaddr.IsTailscaleIP(ip) || ip.IsLoopback() || ipStr == os.Getenv("TS_ALLOW_DEBUG_IP") {
|
if tsaddr.IsTailscaleIP(ip) || ip.IsLoopback() || ipStr == envknob.String("TS_ALLOW_DEBUG_IP") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if r.Method == "GET" {
|
if r.Method == "GET" {
|
||||||
urlKey := r.FormValue("debugkey")
|
urlKey := r.FormValue("debugkey")
|
||||||
keyPath := os.Getenv("TS_DEBUG_KEY_PATH")
|
keyPath := envknob.String("TS_DEBUG_KEY_PATH")
|
||||||
if urlKey != "" && keyPath != "" {
|
if urlKey != "" && keyPath != "" {
|
||||||
slurp, err := ioutil.ReadFile(keyPath)
|
slurp, err := ioutil.ReadFile(keyPath)
|
||||||
if err == nil && string(bytes.TrimSpace(slurp)) == urlKey {
|
if err == nil && string(bytes.TrimSpace(slurp)) == urlKey {
|
||||||
|
@ -14,12 +14,13 @@
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"tailscale.com/envknob"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logf is the basic Tailscale logger type: a printf-like func.
|
// Logf is the basic Tailscale logger type: a printf-like func.
|
||||||
@ -83,7 +84,7 @@ type limitData struct {
|
|||||||
ele *list.Element // list element used to access this string in the cache
|
ele *list.Element // list element used to access this string in the cache
|
||||||
}
|
}
|
||||||
|
|
||||||
var disableRateLimit = os.Getenv("TS_DEBUG_LOG_RATE") == "all"
|
var disableRateLimit = envknob.String("TS_DEBUG_LOG_RATE") == "all"
|
||||||
|
|
||||||
// rateFree are format string substrings that are exempt from rate limiting.
|
// rateFree are format string substrings that are exempt from rate limiting.
|
||||||
// Things should not be added to this unless they're already limited otherwise
|
// Things should not be added to this unless they're already limited otherwise
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/net/flowtrack"
|
"tailscale.com/net/flowtrack"
|
||||||
"tailscale.com/net/packet"
|
"tailscale.com/net/packet"
|
||||||
"tailscale.com/tstime/rate"
|
"tailscale.com/tstime/rate"
|
||||||
@ -225,7 +225,7 @@ func maybeHexdump(flag RunFlags, b []byte) string {
|
|||||||
// effectively disable the limits on the log rate by setting the limit
|
// effectively disable the limits on the log rate by setting the limit
|
||||||
// to 1 millisecond. This should capture everything.
|
// to 1 millisecond. This should capture everything.
|
||||||
func init() {
|
func init() {
|
||||||
if os.Getenv("TS_DEBUG_FILTER_RATE_LIMIT_LOGS") != "all" {
|
if envknob.String("TS_DEBUG_FILTER_RATE_LIMIT_LOGS") != "all" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
package magicsock
|
package magicsock
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"tailscale.com/envknob"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Various debugging and experimental tweakables, set by environment
|
// Various debugging and experimental tweakables, set by environment
|
||||||
@ -17,25 +16,23 @@
|
|||||||
var (
|
var (
|
||||||
// debugDisco prints verbose logs of active discovery events as
|
// debugDisco prints verbose logs of active discovery events as
|
||||||
// they happen.
|
// they happen.
|
||||||
debugDisco, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_DISCO"))
|
debugDisco = envknob.Bool("TS_DEBUG_DISCO")
|
||||||
// debugOmitLocalAddresses removes all local interface addresses
|
// debugOmitLocalAddresses removes all local interface addresses
|
||||||
// from magicsock's discovered local endpoints. Used in some tests.
|
// from magicsock's discovered local endpoints. Used in some tests.
|
||||||
debugOmitLocalAddresses, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_OMIT_LOCAL_ADDRS"))
|
debugOmitLocalAddresses = envknob.Bool("TS_DEBUG_OMIT_LOCAL_ADDRS")
|
||||||
// debugUseDerpRoute temporarily (2020-03-22) controls whether DERP
|
// debugUseDerpRoute temporarily (2020-03-22) controls whether DERP
|
||||||
// reverse routing is enabled (Issue 150). It will become always true
|
// reverse routing is enabled (Issue 150).
|
||||||
// later.
|
debugUseDerpRoute = envknob.OptBool("TS_DEBUG_ENABLE_DERP_ROUTE")
|
||||||
debugUseDerpRouteEnv = os.Getenv("TS_DEBUG_ENABLE_DERP_ROUTE")
|
|
||||||
debugUseDerpRoute, _ = strconv.ParseBool(debugUseDerpRouteEnv)
|
|
||||||
// logDerpVerbose logs all received DERP packets, including their
|
// logDerpVerbose logs all received DERP packets, including their
|
||||||
// full payload.
|
// full payload.
|
||||||
logDerpVerbose, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_DERP"))
|
logDerpVerbose = envknob.Bool("TS_DEBUG_DERP")
|
||||||
// debugReSTUNStopOnIdle unconditionally enables the "shut down
|
// debugReSTUNStopOnIdle unconditionally enables the "shut down
|
||||||
// STUN if magicsock is idle" behavior that normally only triggers
|
// STUN if magicsock is idle" behavior that normally only triggers
|
||||||
// on mobile devices, lowers the shutdown interval, and logs more
|
// on mobile devices, lowers the shutdown interval, and logs more
|
||||||
// verbosely about idle measurements.
|
// verbosely about idle measurements.
|
||||||
debugReSTUNStopOnIdle, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_RESTUN_STOP_ON_IDLE"))
|
debugReSTUNStopOnIdle = envknob.Bool("TS_DEBUG_RESTUN_STOP_ON_IDLE")
|
||||||
// debugAlwaysDERP disables the use of UDP, forcing all peer communication over DERP.
|
// debugAlwaysDERP disables the use of UDP, forcing all peer communication over DERP.
|
||||||
debugAlwaysDERP, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_ALWAYS_USE_DERP"))
|
debugAlwaysDERP = envknob.Bool("TS_DEBUG_ALWAYS_USE_DERP")
|
||||||
)
|
)
|
||||||
|
|
||||||
// inTest reports whether the running program is a test that set the
|
// inTest reports whether the running program is a test that set the
|
||||||
@ -44,7 +41,4 @@
|
|||||||
// Unlike the other debug tweakables above, this one needs to be
|
// Unlike the other debug tweakables above, this one needs to be
|
||||||
// checked every time at runtime, because tests set this after program
|
// checked every time at runtime, because tests set this after program
|
||||||
// startup.
|
// startup.
|
||||||
func inTest() bool {
|
func inTest() bool { return envknob.Bool("IN_TS_TEST") }
|
||||||
inTest, _ := strconv.ParseBool(os.Getenv("IN_TS_TEST"))
|
|
||||||
return inTest
|
|
||||||
}
|
|
||||||
|
@ -61,8 +61,8 @@
|
|||||||
// useDerpRoute reports whether magicsock should enable the DERP
|
// useDerpRoute reports whether magicsock should enable the DERP
|
||||||
// return path optimization (Issue 150).
|
// return path optimization (Issue 150).
|
||||||
func useDerpRoute() bool {
|
func useDerpRoute() bool {
|
||||||
if debugUseDerpRouteEnv != "" {
|
if b, ok := debugUseDerpRoute.Get(); ok {
|
||||||
return debugUseDerpRoute
|
return b
|
||||||
}
|
}
|
||||||
ob := controlclient.DERPRouteFlag()
|
ob := controlclient.DERPRouteFlag()
|
||||||
if v, ok := ob.Get(); ok {
|
if v, ok := ob.Get(); ok {
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
"inet.af/netstack/tcpip/transport/tcp"
|
"inet.af/netstack/tcpip/transport/tcp"
|
||||||
"inet.af/netstack/tcpip/transport/udp"
|
"inet.af/netstack/tcpip/transport/udp"
|
||||||
"inet.af/netstack/waiter"
|
"inet.af/netstack/waiter"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/net/packet"
|
"tailscale.com/net/packet"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
@ -49,7 +50,7 @@
|
|||||||
|
|
||||||
const debugPackets = false
|
const debugPackets = false
|
||||||
|
|
||||||
var debugNetstack, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_NETSTACK"))
|
var debugNetstack = envknob.Bool("TS_DEBUG_NETSTACK")
|
||||||
|
|
||||||
// Impl contains the state for the netstack implementation,
|
// Impl contains the state for the netstack implementation,
|
||||||
// and implements wgengine.FakeImpl to act as a userspace network
|
// and implements wgengine.FakeImpl to act as a userspace network
|
||||||
|
@ -6,9 +6,7 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
@ -22,17 +20,6 @@
|
|||||||
|
|
||||||
const tcpTimeoutBeforeDebug = 5 * time.Second
|
const tcpTimeoutBeforeDebug = 5 * time.Second
|
||||||
|
|
||||||
// debugConnectFailures reports whether the local node should track
|
|
||||||
// outgoing TCP connections and log which ones fail and why.
|
|
||||||
func debugConnectFailures() bool {
|
|
||||||
s := os.Getenv("TS_DEBUG_CONNECT_FAILURES")
|
|
||||||
if s == "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
v, _ := strconv.ParseBool(s)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
type pendingOpenFlow struct {
|
type pendingOpenFlow struct {
|
||||||
timer *time.Timer // until giving up on the flow
|
timer *time.Timer // until giving up on the flow
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/syncs"
|
"tailscale.com/syncs"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@ -188,7 +189,7 @@ func useAmbientCaps() bool {
|
|||||||
return v >= 7
|
return v >= 7
|
||||||
}
|
}
|
||||||
|
|
||||||
var forceIPCommand, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_USE_IP_COMMAND"))
|
var forceIPCommand = envknob.Bool("TS_DEBUG_USE_IP_COMMAND")
|
||||||
|
|
||||||
// useIPCommand reports whether r should use the "ip" command (or its
|
// useIPCommand reports whether r should use the "ip" command (or its
|
||||||
// fake commandRunner for tests) instead of netlink.
|
// fake commandRunner for tests) instead of netlink.
|
||||||
|
@ -11,10 +11,8 @@
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@ -25,6 +23,7 @@
|
|||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/control/controlclient"
|
"tailscale.com/control/controlclient"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/health"
|
"tailscale.com/health"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
@ -366,7 +365,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
|||||||
}
|
}
|
||||||
e.tundev.PreFilterOut = e.handleLocalPackets
|
e.tundev.PreFilterOut = e.handleLocalPackets
|
||||||
|
|
||||||
if debugConnectFailures() {
|
if envknob.BoolDefaultTrue("TS_DEBUG_CONNECT_FAILURES") {
|
||||||
if e.tundev.PreFilterIn != nil {
|
if e.tundev.PreFilterIn != nil {
|
||||||
return nil, errors.New("unexpected PreFilterIn already set")
|
return nil, errors.New("unexpected PreFilterIn already set")
|
||||||
}
|
}
|
||||||
@ -550,10 +549,7 @@ func (e *userspaceEngine) pollResolver() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var debugTrimWireguard = envknob.OptBool("TS_DEBUG_TRIM_WIREGUARD")
|
||||||
debugTrimWireguardEnv = os.Getenv("TS_DEBUG_TRIM_WIREGUARD")
|
|
||||||
debugTrimWireguard, _ = strconv.ParseBool(debugTrimWireguardEnv)
|
|
||||||
)
|
|
||||||
|
|
||||||
// forceFullWireguardConfig reports whether we should give wireguard
|
// forceFullWireguardConfig reports whether we should give wireguard
|
||||||
// our full network map, even for inactive peers
|
// our full network map, even for inactive peers
|
||||||
@ -563,8 +559,8 @@ func (e *userspaceEngine) pollResolver() {
|
|||||||
// and we haven't got enough time testing it.
|
// and we haven't got enough time testing it.
|
||||||
func forceFullWireguardConfig(numPeers int) bool {
|
func forceFullWireguardConfig(numPeers int) bool {
|
||||||
// Did the user explicitly enable trimmming via the environment variable knob?
|
// Did the user explicitly enable trimmming via the environment variable knob?
|
||||||
if debugTrimWireguardEnv != "" {
|
if b, ok := debugTrimWireguard.Get(); ok {
|
||||||
return !debugTrimWireguard
|
return !b
|
||||||
}
|
}
|
||||||
if opt := controlclient.TrimWGConfig(); opt != "" {
|
if opt := controlclient.TrimWGConfig(); opt != "" {
|
||||||
return !opt.EqualBool(true)
|
return !opt.EqualBool(true)
|
||||||
|
@ -6,13 +6,12 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
"tailscale.com/net/dns/resolver"
|
"tailscale.com/net/dns/resolver"
|
||||||
@ -32,7 +31,7 @@
|
|||||||
//
|
//
|
||||||
// If they do not, the watchdog crashes the process.
|
// If they do not, the watchdog crashes the process.
|
||||||
func NewWatchdog(e Engine) Engine {
|
func NewWatchdog(e Engine) Engine {
|
||||||
if v, _ := strconv.ParseBool(os.Getenv("TS_DEBUG_DISABLE_WATCHDOG")); v {
|
if envknob.Bool("TS_DEBUG_DISABLE_WATCHDOG") {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
return &watchdogEngine{
|
return &watchdogEngine{
|
||||||
|
Loading…
Reference in New Issue
Block a user