summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrew Lytvynov <awly@tailscale.com>2023-12-21 19:40:03 -0600
committerGitHub <noreply@github.com>2023-12-21 17:40:03 -0800
commit2716250ee823f21c984e2989c596bc2aaa495613 (patch)
tree1a9dd8d81885930dcdf79ea55b567e68850c4705
parentc9836b454d2388205bc71ff4c3c4c44ac4305604 (diff)
downloadtailscale-2716250ee823f21c984e2989c596bc2aaa495613.tar.xz
tailscale-2716250ee823f21c984e2989c596bc2aaa495613.zip
all: cleanup unused code, part 2 (#10670)
And enable U1000 check in staticcheck. Updates #cleanup Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
-rw-r--r--cmd/tailscale/cli/serve_v2.go8
-rw-r--r--cmd/tailscale/cli/serve_v2_test.go9
-rw-r--r--cmd/tailscale/cli/up.go12
-rw-r--r--cmd/tailscaled/depaware.txt2
-rw-r--r--cmd/testwrapper/args.go16
-rw-r--r--cmd/tsconnect/build.go20
-rw-r--r--control/controlbase/conn_test.go27
-rw-r--r--control/controlbase/noiseexplorer_test.go32
-rw-r--r--control/controlclient/auto.go16
-rw-r--r--control/controlclient/map.go42
-rw-r--r--derp/derp_server.go6
-rw-r--r--docs/webhooks/example.go4
-rw-r--r--doctor/permissions/permissions.go3
-rw-r--r--ipn/ipnauth/ipnauth.go11
-rw-r--r--ipn/ipnauth/ipnauth_windows.go2
-rw-r--r--ipn/ipnlocal/local.go9
-rw-r--r--ipn/ipnlocal/peerapi.go4
-rw-r--r--ipn/ipnlocal/peerapi_test.go1
-rw-r--r--ipn/ipnlocal/ssh.go9
-rw-r--r--net/art/stride_table.go9
-rw-r--r--net/art/stride_table_test.go6
-rw-r--r--net/art/table_test.go37
-rw-r--r--net/dns/direct.go55
-rw-r--r--net/dns/direct_linux.go49
-rw-r--r--net/dns/manager.go12
-rw-r--r--net/dns/manager_linux.go13
-rw-r--r--net/dns/manager_test.go27
-rw-r--r--net/dns/nm.go7
-rw-r--r--net/dns/recursive/recursive.go7
-rw-r--r--net/dns/resolved.go23
-rw-r--r--net/dns/resolver/tsdns.go9
-rw-r--r--net/dns/resolver/tsdns_test.go2
-rw-r--r--net/dnscache/dnscache.go2
-rw-r--r--net/netmon/netmon.go7
-rw-r--r--net/netmon/netmon_windows.go7
-rw-r--r--net/netutil/netutil.go6
-rw-r--r--net/routetable/routetable.go1
-rw-r--r--net/tstun/wrap.go5
-rw-r--r--portlist/netstat.go2
-rw-r--r--safesocket/pipe_windows.go8
-rw-r--r--staticcheck.conf1
-rw-r--r--tstest/integration/vms/opensuse_leap_15_1_test.go2
-rw-r--r--util/linuxfw/helpers.go2
-rw-r--r--util/linuxfw/linuxfw_unsupported.go2
-rw-r--r--util/winutil/restartmgr_windows.go1
-rw-r--r--util/winutil/subprocess_windows_test.go86
-rw-r--r--util/winutil/winutil_windows.go20
-rw-r--r--wgengine/magicsock/debugknobs.go4
-rw-r--r--wgengine/magicsock/magicsock.go4
-rw-r--r--wgengine/magicsock/peermtu_stubs.go25
-rw-r--r--wgengine/router/ifconfig_windows.go18
-rw-r--r--wgengine/router/router_test.go1
52 files changed, 115 insertions, 578 deletions
diff --git a/cmd/tailscale/cli/serve_v2.go b/cmd/tailscale/cli/serve_v2.go
index 0e0c37d84..e040c9de8 100644
--- a/cmd/tailscale/cli/serve_v2.go
+++ b/cmd/tailscale/cli/serve_v2.go
@@ -93,14 +93,6 @@ var infoMap = map[serveMode]commandInfo{
},
}
-func buildShortUsage(subcmd string) string {
- return strings.Join([]string{
- subcmd + " [flags] <target> [off]",
- subcmd + " status [--json]",
- subcmd + " reset",
- }, "\n ")
-}
-
// errHelpFunc is standard error text that prompts users to
// run `$subcmd --help` for information on how to use serve.
var errHelpFunc = func(m serveMode) error {
diff --git a/cmd/tailscale/cli/serve_v2_test.go b/cmd/tailscale/cli/serve_v2_test.go
index e795ff286..8634d5b83 100644
--- a/cmd/tailscale/cli/serve_v2_test.go
+++ b/cmd/tailscale/cli/serve_v2_test.go
@@ -27,7 +27,6 @@ func TestServeDevConfigMutations(t *testing.T) {
command []string // serve args; nil means no command to run (only reset)
want *ipn.ServeConfig // non-nil means we want a save of this value
wantErr func(error) (badErrMsg string) // nil means no error is wanted
- before func(t *testing.T)
}
// group is a group of steps that share the same
@@ -1224,14 +1223,6 @@ func TestMessageForPort(t *testing.T) {
}
}
-func unindent(s string) string {
- lines := strings.Split(s, "\n")
- for i, line := range lines {
- lines[i] = strings.TrimSpace(line)
- }
- return strings.Join(lines, "\n")
-}
-
func TestIsLegacyInvocation(t *testing.T) {
tests := []struct {
subcmd serveMode
diff --git a/cmd/tailscale/cli/up.go b/cmd/tailscale/cli/up.go
index 67d6a3483..955e3ccc0 100644
--- a/cmd/tailscale/cli/up.go
+++ b/cmd/tailscale/cli/up.go
@@ -1044,18 +1044,6 @@ func exitNodeIP(p *ipn.Prefs, st *ipnstate.Status) (ip netip.Addr) {
return
}
-func anyPeerAdvertisingRoutes(st *ipnstate.Status) bool {
- for _, ps := range st.Peer {
- if ps.PrimaryRoutes == nil {
- continue
- }
- if ps.PrimaryRoutes.Len() > 0 {
- return true
- }
- }
- return false
-}
-
func init() {
// Required to use our client API. We're fine with the instability since the
// client lives in the same repo as this code.
diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt
index b5ac27975..379af4fe3 100644
--- a/cmd/tailscaled/depaware.txt
+++ b/cmd/tailscaled/depaware.txt
@@ -283,7 +283,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
tailscale.com/net/netknob from tailscale.com/net/netns+
tailscale.com/net/netmon from tailscale.com/cmd/tailscaled+
tailscale.com/net/netns from tailscale.com/derp/derphttp+
- 💣 tailscale.com/net/netstat from tailscale.com/ipn/ipnauth+
+ W 💣 tailscale.com/net/netstat from tailscale.com/portlist
tailscale.com/net/netutil from tailscale.com/ipn/ipnlocal+
tailscale.com/net/packet from tailscale.com/net/tstun+
tailscale.com/net/packet/checksum from tailscale.com/net/tstun
diff --git a/cmd/testwrapper/args.go b/cmd/testwrapper/args.go
index 20c64e0e3..95157bc34 100644
--- a/cmd/testwrapper/args.go
+++ b/cmd/testwrapper/args.go
@@ -12,22 +12,6 @@ import (
"testing"
)
-// defaultTestArgs contains the default values for all flags in the testing
-// package. It is used to reset the flag values in testwrapper tests to allow
-// parsing the flags again.
-var defaultTestArgs map[string]string
-
-// initDefaultTestArgs initializes defaultTestArgs.
-func initDefaultTestArgs() {
- if defaultTestArgs != nil {
- return
- }
- defaultTestArgs = make(map[string]string)
- flag.CommandLine.VisitAll(func(f *flag.Flag) {
- defaultTestArgs[f.Name] = f.DefValue
- })
-}
-
// registerTestFlags registers all flags from the testing package with the
// provided flag set. It does so by calling testing.Init() and then iterating
// over all flags registered on flag.CommandLine.
diff --git a/cmd/tsconnect/build.go b/cmd/tsconnect/build.go
index e3384b664..364ebf536 100644
--- a/cmd/tsconnect/build.go
+++ b/cmd/tsconnect/build.go
@@ -83,26 +83,6 @@ func fixEsbuildMetadataPaths(metadataStr string) ([]byte, error) {
return json.Marshal(metadata)
}
-func cleanDist() error {
- log.Printf("Cleaning %s...\n", *distDir)
- files, err := os.ReadDir(*distDir)
- if err != nil {
- if os.IsNotExist(err) {
- return os.MkdirAll(*distDir, 0755)
- }
- return err
- }
-
- for _, file := range files {
- if file.Name() != "placeholder" {
- if err := os.Remove(filepath.Join(*distDir, file.Name())); err != nil {
- return err
- }
- }
- }
- return nil
-}
-
func precompressDist(fastCompression bool) error {
log.Printf("Pre-compressing files in %s/...\n", *distDir)
return precompress.PrecompressDir(*distDir, precompress.Options{
diff --git a/control/controlbase/conn_test.go b/control/controlbase/conn_test.go
index 079c57c6e..504d1dbf5 100644
--- a/control/controlbase/conn_test.go
+++ b/control/controlbase/conn_test.go
@@ -7,7 +7,6 @@ import (
"bufio"
"bytes"
"context"
- "crypto/rand"
"encoding/binary"
"fmt"
"io"
@@ -302,32 +301,6 @@ func TestConnMemoryOverhead(t *testing.T) {
}
}
-// mkConns creates synthetic Noise Conns wrapping the given net.Conns.
-// This function is for testing just the Conn transport logic without
-// having to muck about with Noise handshakes.
-func mkConns(s1, s2 net.Conn) (*Conn, *Conn) {
- var k1, k2 [chp.KeySize]byte
- if _, err := rand.Read(k1[:]); err != nil {
- panic(err)
- }
- if _, err := rand.Read(k2[:]); err != nil {
- panic(err)
- }
-
- ret1 := &Conn{
- conn: s1,
- tx: txState{cipher: newCHP(k1)},
- rx: rxState{cipher: newCHP(k2)},
- }
- ret2 := &Conn{
- conn: s2,
- tx: txState{cipher: newCHP(k2)},
- rx: rxState{cipher: newCHP(k1)},
- }
-
- return ret1, ret2
-}
-
type readSink struct {
r io.Reader
diff --git a/control/controlbase/noiseexplorer_test.go b/control/controlbase/noiseexplorer_test.go
index 7407ae533..76b6f79be 100644
--- a/control/controlbase/noiseexplorer_test.go
+++ b/control/controlbase/noiseexplorer_test.go
@@ -32,7 +32,6 @@ import (
"encoding/binary"
"hash"
"io"
- "math"
"golang.org/x/crypto/blake2s"
"golang.org/x/crypto/chacha20poly1305"
@@ -105,10 +104,6 @@ var minNonce = uint32(0)
* UTILITY FUNCTIONS *
* ---------------------------------------------------------------- */
-func getPublicKey(kp *keypair) [32]byte {
- return kp.public_key
-}
-
func isEmptyKey(k [32]byte) bool {
return subtle.ConstantTimeCompare(k[:], emptyKey[:]) == 1
}
@@ -162,12 +157,6 @@ func generateKeypair() keypair {
return generateKeypair()
}
-func generatePublicKey(private_key [32]byte) [32]byte {
- var public_key [32]byte
- curve25519.ScalarBaseMult(&public_key, &private_key)
- return public_key
-}
-
func encrypt(k [32]byte, n uint32, ad []byte, plaintext []byte) []byte {
var nonce [12]byte
var ciphertext []byte
@@ -246,12 +235,6 @@ func decryptWithAd(cs *cipherstate, ad []byte, ciphertext []byte) (*cipherstate,
return cs, plaintext, valid
}
-func reKey(cs *cipherstate) *cipherstate {
- e := encrypt(cs.k, math.MaxUint32, []byte{}, emptyKey[:])
- copy(cs.k[:], e)
- return cs
-}
-
/* SymmetricState */
func initializeSymmetric(protocolName []byte) symmetricstate {
@@ -273,19 +256,6 @@ func mixHash(ss *symmetricstate, data []byte) *symmetricstate {
return ss
}
-func mixKeyAndHash(ss *symmetricstate, ikm [32]byte) *symmetricstate {
- var tempH [32]byte
- var tempK [32]byte
- ss.ck, tempH, tempK = getHkdf(ss.ck, ikm[:])
- ss = mixHash(ss, tempH[:])
- ss.cs = initializeKey(tempK)
- return ss
-}
-
-func getHandshakeHash(ss *symmetricstate) [32]byte {
- return ss.h
-}
-
func encryptAndHash(ss *symmetricstate, plaintext []byte) (*symmetricstate, []byte) {
var ciphertext []byte
if hasKey(&ss.cs) {
@@ -471,5 +441,3 @@ func RecvMessage(session *noisesession, message *messagebuffer) (*noisesession,
session.mc = session.mc + 1
return session, plaintext, valid
}
-
-func main() {}
diff --git a/control/controlclient/auto.go b/control/controlclient/auto.go
index 1dc903376..86b03efa5 100644
--- a/control/controlclient/auto.go
+++ b/control/controlclient/auto.go
@@ -252,14 +252,6 @@ func (c *Auto) updateControl() {
}
}
-// cancelAuthCtx cancels the existing auth goroutine's context
-// & creates a new one, causing it to restart.
-func (c *Auto) cancelAuthCtx() {
- c.mu.Lock()
- defer c.mu.Unlock()
- c.cancelAuthCtxLocked()
-}
-
// cancelAuthCtxLocked is like cancelAuthCtx, but assumes the caller holds c.mu.
func (c *Auto) cancelAuthCtxLocked() {
if c.authCancel != nil {
@@ -271,14 +263,6 @@ func (c *Auto) cancelAuthCtxLocked() {
}
}
-// cancelMapCtx cancels the context for the existing mapPoll and liteUpdates
-// goroutines and creates a new one, causing them to restart.
-func (c *Auto) cancelMapCtx() {
- c.mu.Lock()
- defer c.mu.Unlock()
- c.cancelMapCtxLocked()
-}
-
// cancelMapCtxLocked is like cancelMapCtx, but assumes the caller holds c.mu.
func (c *Auto) cancelMapCtxLocked() {
if c.mapCancel != nil {
diff --git a/control/controlclient/map.go b/control/controlclient/map.go
index 90bf83213..8797ed0bb 100644
--- a/control/controlclient/map.go
+++ b/control/controlclient/map.go
@@ -8,7 +8,6 @@ import (
"encoding/json"
"fmt"
"net"
- "net/netip"
"reflect"
"slices"
"sort"
@@ -86,7 +85,6 @@ type mapSession struct {
lastDomainAuditLogID string
lastHealth []string
lastPopBrowserURL string
- stickyDebug tailcfg.Debug // accumulated opt.Bool values
lastTKAInfo *tailcfg.TKAInfo
lastNetmapSummary string // from NetworkMap.VeryConcise
}
@@ -790,43 +788,3 @@ func (ms *mapSession) netmap() *netmap.NetworkMap {
}
return nm
}
-
-func nodesSorted(v []*tailcfg.Node) bool {
- for i, n := range v {
- if i > 0 && n.ID <= v[i-1].ID {
- return false
- }
- }
- return true
-}
-
-func sortNodes(v []*tailcfg.Node) {
- sort.Slice(v, func(i, j int) bool { return v[i].ID < v[j].ID })
-}
-
-func cloneNodes(v1 []*tailcfg.Node) []*tailcfg.Node {
- if v1 == nil {
- return nil
- }
- v2 := make([]*tailcfg.Node, len(v1))
- for i, n := range v1 {
- v2[i] = n.Clone()
- }
- return v2
-}
-
-var debugSelfIPv6Only = envknob.RegisterBool("TS_DEBUG_SELF_V6_ONLY")
-
-func filterSelfAddresses(in []netip.Prefix) (ret []netip.Prefix) {
- switch {
- default:
- return in
- case debugSelfIPv6Only():
- for _, a := range in {
- if a.Addr().Is6() {
- ret = append(ret, a)
- }
- }
- return ret
- }
-}
diff --git a/derp/derp_server.go b/derp/derp_server.go
index cf42acdf7..2479ff5a5 100644
--- a/derp/derp_server.go
+++ b/derp/derp_server.go
@@ -753,12 +753,6 @@ func (s *Server) debugLogf(format string, v ...any) {
}
}
-// for testing
-var (
- timeSleep = time.Sleep
- timeNow = time.Now
-)
-
// run serves the client until there's an error.
// If the client hangs up or the server is closed, run returns nil, otherwise run returns an error.
func (c *sclient) run(ctx context.Context) error {
diff --git a/docs/webhooks/example.go b/docs/webhooks/example.go
index 6811a95e6..712028362 100644
--- a/docs/webhooks/example.go
+++ b/docs/webhooks/example.go
@@ -1,9 +1,9 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
-// Package webhooks provides example consumer code for Tailscale
+// Command webhooks provides example consumer code for Tailscale
// webhooks.
-package webhooks
+package main
import (
"crypto/hmac"
diff --git a/doctor/permissions/permissions.go b/doctor/permissions/permissions.go
index f9c0de950..77fe52626 100644
--- a/doctor/permissions/permissions.go
+++ b/doctor/permissions/permissions.go
@@ -26,6 +26,7 @@ func (Check) Run(_ context.Context, logf logger.Logf) error {
return permissionsImpl(logf)
}
+//lint:ignore U1000 used in non-windows implementations.
func formatUserID[T constraints.Integer](id T) string {
idStr := fmt.Sprint(id)
if uu, err := user.LookupId(idStr); err != nil {
@@ -35,6 +36,7 @@ func formatUserID[T constraints.Integer](id T) string {
}
}
+//lint:ignore U1000 used in non-windows implementations.
func formatGroupID[T constraints.Integer](id T) string {
idStr := fmt.Sprint(id)
if g, err := user.LookupGroupId(idStr); err != nil {
@@ -44,6 +46,7 @@ func formatGroupID[T constraints.Integer](id T) string {
}
}
+//lint:ignore U1000 used in non-windows implementations.
func formatGroups[T constraints.Integer](groups []T) string {
var buf strings.Builder
for i, group := range groups {
diff --git a/ipn/ipnauth/ipnauth.go b/ipn/ipnauth/ipnauth.go
index 5dc2e2768..7ae9ff3e4 100644
--- a/ipn/ipnauth/ipnauth.go
+++ b/ipn/ipnauth/ipnauth.go
@@ -9,7 +9,6 @@ import (
"fmt"
"io"
"net"
- "net/netip"
"os"
"os/user"
"runtime"
@@ -18,7 +17,6 @@ import (
"inet.af/peercred"
"tailscale.com/envknob"
"tailscale.com/ipn"
- "tailscale.com/net/netstat"
"tailscale.com/safesocket"
"tailscale.com/types/logger"
"tailscale.com/util/clientmetric"
@@ -207,12 +205,3 @@ func isLocalAdmin(uid string) (bool, error) {
}
return groupmember.IsMemberOfGroup(adminGroup, u.Username)
}
-
-func peerPid(entries []netstat.Entry, la, ra netip.AddrPort) int {
- for _, e := range entries {
- if e.Local == ra && e.Remote == la {
- return e.Pid
- }
- }
- return 0
-}
diff --git a/ipn/ipnauth/ipnauth_windows.go b/ipn/ipnauth/ipnauth_windows.go
index c38b6db0f..d3421a5dc 100644
--- a/ipn/ipnauth/ipnauth_windows.go
+++ b/ipn/ipnauth/ipnauth_windows.go
@@ -20,7 +20,7 @@ import (
// based on the user who owns the other end of the connection.
// If c is not backed by a named pipe, an error is returned.
func GetConnIdentity(logf logger.Logf, c net.Conn) (ci *ConnIdentity, err error) {
- ci = &ConnIdentity{conn: c}
+ ci = &ConnIdentity{conn: c, notWindows: false}
wcc, ok := c.(*safesocket.WindowsClientConn)
if !ok {
return nil, fmt.Errorf("not a WindowsClientConn: %T", c)
diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go
index 4f72a305e..fe17198c5 100644
--- a/ipn/ipnlocal/local.go
+++ b/ipn/ipnlocal/local.go
@@ -5324,15 +5324,6 @@ func (b *LocalBackend) DoNoiseRequest(req *http.Request) (*http.Response, error)
return cc.DoNoiseRequest(req)
}
-// tailscaleSSHEnabled reports whether Tailscale SSH is currently enabled based
-// on prefs. It returns false if there are no prefs set.
-func (b *LocalBackend) tailscaleSSHEnabled() bool {
- b.mu.Lock()
- defer b.mu.Unlock()
- p := b.pm.CurrentPrefs()
- return p.Valid() && p.RunSSH()
-}
-
func (b *LocalBackend) sshServerOrInit() (_ SSHServer, err error) {
b.mu.Lock()
defer b.mu.Unlock()
diff --git a/ipn/ipnlocal/peerapi.go b/ipn/ipnlocal/peerapi.go
index d1d511462..6e45ea7df 100644
--- a/ipn/ipnlocal/peerapi.go
+++ b/ipn/ipnlocal/peerapi.go
@@ -62,10 +62,6 @@ type peerAPIServer struct {
taildrop *taildrop.Manager
}
-var (
- errNilPeerAPIServer = errors.New("peerapi unavailable; not listening")
-)
-
func (s *peerAPIServer) listen(ip netip.Addr, ifState *interfaces.State) (ln net.Listener, err error) {
// Android for whatever reason often has problems creating the peerapi listener.
// But since we started intercepting it with netstack, it's not even important that
diff --git a/ipn/ipnlocal/peerapi_test.go b/ipn/ipnlocal/peerapi_test.go
index 74e1f4e25..074d11482 100644
--- a/ipn/ipnlocal/peerapi_test.go
+++ b/ipn/ipnlocal/peerapi_test.go
@@ -114,7 +114,6 @@ func hexAll(v string) string {
}
func TestHandlePeerAPI(t *testing.T) {
- const nodeFQDN = "self-node.tail-scale.ts.net."
tests := []struct {
name string
isSelf bool // the peer sending the request is owned by us
diff --git a/ipn/ipnlocal/ssh.go b/ipn/ipnlocal/ssh.go
index 19a23c030..7a6000a56 100644
--- a/ipn/ipnlocal/ssh.go
+++ b/ipn/ipnlocal/ssh.go
@@ -217,3 +217,12 @@ func (b *LocalBackend) getSSHHostKeyPublicStrings() (ret []string) {
}
return ret
}
+
+// tailscaleSSHEnabled reports whether Tailscale SSH is currently enabled based
+// on prefs. It returns false if there are no prefs set.
+func (b *LocalBackend) tailscaleSSHEnabled() bool {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+ p := b.pm.CurrentPrefs()
+ return p.Valid() && p.RunSSH()
+}
diff --git a/net/art/stride_table.go b/net/art/stride_table.go
index f18f76515..5ff0455fe 100644
--- a/net/art/stride_table.go
+++ b/net/art/stride_table.go
@@ -240,15 +240,6 @@ func (t *strideTable[T]) tableDebugString() string {
return ret.String()
}
-// treeDebugString returns the contents of t, formatted as a sparse tree. Each
-// line is one entry, indented such that it is contained by all its parents, and
-// non-overlapping with any of its siblings.
-func (t *strideTable[T]) treeDebugString() string {
- var ret bytes.Buffer
- t.treeDebugStringRec(&ret, 1, 0) // index of 0/0, and 0 indent
- return ret.String()
-}
-
func (t *strideTable[T]) treeDebugStringRec(w io.Writer, idx, indent int) {
addr, len := inversePrefixIndex(idx)
if t.hasPrefixRootedAt(idx) {
diff --git a/net/art/stride_table_test.go b/net/art/stride_table_test.go
index 82a7c915d..40700b175 100644
--- a/net/art/stride_table_test.go
+++ b/net/art/stride_table_test.go
@@ -348,12 +348,6 @@ func (t *slowTable[T]) String() string {
return ret.String()
}
-func (t *slowTable[T]) insert(addr uint8, prefixLen int, val T) {
- t.delete(addr, prefixLen) // no-op if prefix doesn't exist
-
- t.prefixes = append(t.prefixes, slowEntry[T]{addr, prefixLen, val})
-}
-
func (t *slowTable[T]) delete(addr uint8, prefixLen int) {
pfx := make([]slowEntry[T], 0, len(t.prefixes))
for _, e := range t.prefixes {
diff --git a/net/art/table_test.go b/net/art/table_test.go
index 9166c00e5..39b76e0af 100644
--- a/net/art/table_test.go
+++ b/net/art/table_test.go
@@ -968,8 +968,6 @@ func BenchmarkTableDelete(b *testing.B) {
})
}
-var addrSink netip.Addr
-
func BenchmarkTableGet(b *testing.B) {
forFamilyAndCount(b, func(b *testing.B, routes []slowPrefixEntry[int]) {
genAddr := randomAddr4
@@ -1106,18 +1104,6 @@ type slowPrefixEntry[T any] struct {
val T
}
-func (t *slowPrefixTable[T]) delete(pfx netip.Prefix) {
- pfx = pfx.Masked()
- ret := make([]slowPrefixEntry[T], 0, len(t.prefixes))
- for _, ent := range t.prefixes {
- if ent.pfx == pfx {
- continue
- }
- ret = append(ret, ent)
- }
- t.prefixes = ret
-}
-
func (t *slowPrefixTable[T]) insert(pfx netip.Prefix, val T) {
pfx = pfx.Masked()
for i, ent := range t.prefixes {
@@ -1230,26 +1216,3 @@ func roundFloat64(f float64) float64 {
}
return ret
}
-
-func minimize(pfxs []slowPrefixEntry[int], f func(skip map[netip.Prefix]bool) error) (map[netip.Prefix]bool, error) {
- if f(nil) == nil {
- return nil, nil
- }
-
- remove := map[netip.Prefix]bool{}
- for lastLen := -1; len(remove) != lastLen; lastLen = len(remove) {
- fmt.Println("len is ", len(remove))
- for i, pfx := range pfxs {
- if remove[pfx.pfx] {
- continue
- }
- remove[pfx.pfx] = true
- fmt.Printf("%d %d: trying without %s\n", i, len(remove), pfx.pfx)
- if f(remove) == nil {
- delete(remove, pfx.pfx)
- }
- }
- }
-
- return remove, f(remove)
-}
diff --git a/net/dns/direct.go b/net/dns/direct.go
index e9279d13a..501d42e85 100644
--- a/net/dns/direct.go
+++ b/net/dns/direct.go
@@ -20,7 +20,6 @@ import (
"sync"
"time"
- "tailscale.com/health"
"tailscale.com/net/dns/resolvconffile"
"tailscale.com/types/logger"
"tailscale.com/util/dnsname"
@@ -50,6 +49,8 @@ func readResolv(r io.Reader) (OSConfig, error) {
// resolvOwner returns the apparent owner of the resolv.conf
// configuration in bs - one of "resolvconf", "systemd-resolved" or
// "NetworkManager", or "" if no known owner was found.
+//
+//lint:ignore U1000 used in linux and freebsd code
func resolvOwner(bs []byte) string {
likely := ""
b := bytes.NewBuffer(bs)
@@ -130,11 +131,13 @@ type directManager struct {
ctx context.Context // valid until Close
ctxClose context.CancelFunc // closes ctx
- mu sync.Mutex
- wantResolvConf []byte // if non-nil, what we expect /etc/resolv.conf to contain
+ mu sync.Mutex
+ wantResolvConf []byte // if non-nil, what we expect /etc/resolv.conf to contain
+ //lint:ignore U1000 used in direct_linux.go
lastWarnContents []byte // last resolv.conf contents that we warned about
}
+//lint:ignore U1000 used in manager_{freebsd,openbsd}.go
func newDirectManager(logf logger.Logf) *directManager {
return newDirectManagerOnFS(logf, directFS{})
}
@@ -288,52 +291,6 @@ func (m *directManager) setWant(want []byte) {
m.wantResolvConf = want
}
-var warnTrample = health.NewWarnable()
-
-// checkForFileTrample checks whether /etc/resolv.conf has been trampled
-// by another program on the system. (e.g. a DHCP client)
-func (m *directManager) checkForFileTrample() {
- m.mu.Lock()
- want := m.wantResolvConf
- lastWarn := m.lastWarnContents
- m.mu.Unlock()
-
- if want == nil {
- return
- }
-
- cur, err := m.fs.ReadFile(resolvConf)
- if err != nil {
- m.logf("trample: read error: %v", err)
- return
- }
- if bytes.Equal(cur, want) {
- warnTrample.Set(nil)
- if lastWarn != nil {
- m.mu.Lock()
- m.lastWarnContents = nil
- m.mu.Unlock()
- m.logf("trample: resolv.conf again matches expected content")
- }
- return
- }
- if bytes.Equal(cur, lastWarn) {
- // We already logged about this, so not worth doing it again.
- return
- }
-
- m.mu.Lock()
- m.lastWarnContents = cur
- m.mu.Unlock()
-
- show := cur
- if len(show) > 1024 {
- show = show[:1024]
- }
- m.logf("trample: resolv.conf changed from what we expected. did some other program interfere? current contents: %q", show)
- warnTrample.Set(errors.New("Linux DNS config not ideal. /etc/resolv.conf overwritten. See https://tailscale.com/s/dns-fight"))
-}
-
func (m *directManager) SetDNS(config OSConfig) (err error) {
defer func() {
if err != nil && errors.Is(err, fs.ErrPermission) && runtime.GOOS == "linux" &&
diff --git a/net/dns/direct_linux.go b/net/dns/direct_linux.go
index 4a388c47b..ad5a2163a 100644
--- a/net/dns/direct_linux.go
+++ b/net/dns/direct_linux.go
@@ -4,9 +4,12 @@
package dns
import (
+ "bytes"
"context"
+ "errors"
"github.com/illarion/gonotify"
+ "tailscale.com/health"
)
func (m *directManager) runFileWatcher() {
@@ -55,6 +58,52 @@ func (m *directManager) runFileWatcher() {
}
}
+var warnTrample = health.NewWarnable()
+
+// checkForFileTrample checks whether /etc/resolv.conf has been trampled
+// by another program on the system. (e.g. a DHCP client)
+func (m *directManager) checkForFileTrample() {
+ m.mu.Lock()
+ want := m.wantResolvConf
+ lastWarn := m.lastWarnContents
+ m.mu.Unlock()
+
+ if want == nil {
+ return
+ }
+
+ cur, err := m.fs.ReadFile(resolvConf)
+ if err != nil {
+ m.logf("trample: read error: %v", err)
+ return
+ }
+ if bytes.Equal(cur, want) {
+ warnTrample.Set(nil)
+ if lastWarn != nil {
+ m.mu.Lock()
+ m.lastWarnContents = nil
+ m.mu.Unlock()
+ m.logf("trample: resolv.conf again matches expected content")
+ }
+ return
+ }
+ if bytes.Equal(cur, lastWarn) {
+ // We already logged about this, so not worth doing it again.
+ return
+ }
+
+ m.mu.Lock()
+ m.lastWarnContents = cur
+ m.mu.Unlock()
+
+ show := cur
+ if len(show) > 1024 {
+ show = show[:1024]
+ }
+ m.logf("trample: resolv.conf changed from what we expected. did some other program interfere? current contents: %q", show)
+ warnTrample.Set(errors.New("Linux DNS config not ideal. /etc/resolv.conf overwritten. See https://tailscale.com/s/dns-fight"))
+}
+
func (m *directManager) closeInotifyOnDone(ctx context.Context, in *gonotify.Inotify) {
<-ctx.Done()
in.Close()
diff --git a/net/dns/manager.go b/net/dns/manager.go
index ab94743db..69185909c 100644
--- a/net/dns/manager.go
+++ b/net/dns/manager.go
@@ -40,18 +40,6 @@ const maxActiveQueries = 256
// the lint exception is necessary and on others it is not,
// and plain ignore complains if the exception is unnecessary.
-// reconfigTimeout is the time interval within which Manager.{Up,Down} should complete.
-//
-// This is particularly useful because certain conditions can cause indefinite hangs
-// (such as improper dbus auth followed by contextless dbus.Object.Call).
-// Such operations should be wrapped in a timeout context.
-const reconfigTimeout = time.Second
-
-type response struct {
- pkt []byte
- to netip.AddrPort // response destination (request source)
-}
-
// Manager manages system DNS settings.
type Manager struct {
logf logger.Logf
diff --git a/net/dns/manager_linux.go b/net/dns/manager_linux.go
index 75662d672..b5d3d841c 100644
--- a/net/dns/manager_linux.go
+++ b/net/dns/manager_linux.go
@@ -69,13 +69,12 @@ func NewOSConfigurator(logf logger.Logf, interfaceName string) (ret OSConfigurat
// newOSConfigEnv are the funcs newOSConfigurator needs, pulled out for testing.
type newOSConfigEnv struct {
- fs wholeFileFS
- dbusPing func(string, string) error
- dbusReadString func(string, string, string, string) (string, error)
- nmIsUsingResolved func() error
- nmVersionBetween func(v1, v2 string) (safe bool, err error)
- resolvconfStyle func() string
- isResolvconfDebianVersion func() bool
+ fs wholeFileFS
+ dbusPing func(string, string) error
+ dbusReadString func(string, string, string, string) (string, error)
+ nmIsUsingResolved func() error
+ nmVersionBetween func(v1, v2 string) (safe bool, err error)
+ resolvconfStyle func() string
}
func dnsMode(logf logger.Logf, env newOSConfigEnv) (ret string, err error) {
diff --git a/net/dns/manager_test.go b/net/dns/manager_test.go
index e88b61322..65b86bab4 100644
--- a/net/dns/manager_test.go
+++ b/net/dns/manager_test.go
@@ -636,13 +636,6 @@ func mustIPs(strs ...string) (ret []netip.Addr) {
return ret
}
-func mustIPPs(strs ...string) (ret []netip.AddrPort) {
- for _, s := range strs {
- ret = append(ret, netip.MustParseAddrPort(s))
- }
- return ret
-}
-
func mustRes(strs ...string) (ret []*dnstype.Resolver) {
for _, s := range strs {
ret = append(ret, &dnstype.Resolver{Addr: s})
@@ -681,26 +674,6 @@ func hosts(strs ...string) (ret map[dnsname.FQDN][]netip.Addr) {
return ret
}
-func hostsR(strs ...string) (ret map[dnsname.FQDN][]dnstype.Resolver) {
- var key dnsname.FQDN
- ret = map[dnsname.FQDN][]dnstype.Resolver{}
- for _, s := range strs {
- if ip, err := netip.ParseAddr(s); err == nil {
- if key == "" {
- panic("IP provided before name")
- }
- ret[key] = append(ret[key], dnstype.Resolver{Addr: ip.String()})
- } else {
- fqdn, err := dnsname.ToFQDN(s)
- if err != nil {
- panic(err)
- }
- key = fqdn
- }
- }
- return ret
-}
-
func upstreams(strs ...string) (ret map[dnsname.FQDN][]*dnstype.Resolver) {
var key dnsname.FQDN
ret = map[dnsname.FQDN][]*dnstype.Resolver{}
diff --git a/net/dns/nm.go b/net/dns/nm.go
index 4d9fbca66..adb33cdb7 100644
--- a/net/dns/nm.go
+++ b/net/dns/nm.go
@@ -25,6 +25,13 @@ const (
lowerPriority = int32(200) // lower than all builtin auto priorities
)
+// reconfigTimeout is the time interval within which Manager.{Up,Down} should complete.
+//
+// This is particularly useful because certain conditions can cause indefinite hangs
+// (such as improper dbus auth followed by contextless dbus.Object.Call).
+// Such operations should be wrapped in a timeout context.
+const reconfigTimeout = time.Second
+
// nmManager uses the NetworkManager DBus API.
type nmManager struct {
interfaceName string
diff --git a/net/dns/recursive/recursive.go b/net/dns/recursive/recursive.go
index d0fb5d5c7..eb23004d8 100644
--- a/net/dns/recursive/recursive.go
+++ b/net/dns/recursive/recursive.go
@@ -163,13 +163,6 @@ func (r *Resolver) logf(format string, args ...any) {
r.Logf(format, args...)
}
-func (r *Resolver) dlogf(format string, args ...any) {
- if r.Logf == nil || !debug() {
- return
- }
- r.Logf(format, args...)
-}
-
func (r *Resolver) depthlogf(depth int, format string, args ...any) {
if r.Logf == nil || !debug() {
return
diff --git a/net/dns/resolved.go b/net/dns/resolved.go
index d524d2e80..2917ab5b3 100644
--- a/net/dns/resolved.go
+++ b/net/dns/resolved.go
@@ -7,7 +7,6 @@ package dns
import (
"context"
- "errors"
"fmt"
"net"
"strings"
@@ -17,32 +16,10 @@ import (
"golang.org/x/sys/unix"
"tailscale.com/health"
"tailscale.com/logtail/backoff"
- "tailscale.com/net/netaddr"
"tailscale.com/types/logger"
"tailscale.com/util/dnsname"
)
-// resolvedListenAddr is the listen address of the resolved stub resolver.
-//
-// We only consider resolved to be the system resolver if the stub resolver is;
-// that is, if this address is the sole nameserver in /etc/resolved.conf.
-// In other cases, resolved may be managing the system DNS configuration directly.
-// Then the nameserver list will be a concatenation of those for all
-// the interfaces that register their interest in being a default resolver with
-//
-// SetLinkDomains([]{{"~.", true}, ...})
-//
-// which includes at least the interface with the default route, i.e. not us.
-// This does not work for us: there is a possibility of getting NXDOMAIN
-// from the other nameservers before we are asked or get a chance to respond.
-// We consider this case as lacking resolved support and fall through to dnsDirect.
-//
-// While it may seem that we need to read a config option to get at this,
-// this address is, in fact, hard-coded into resolved.
-var resolvedListenAddr = netaddr.IPv4(127, 0, 0, 53)
-
-var errNotReady = errors.New("interface not ready")
-
// DBus entities we talk to.
//
// DBus is an RPC bus. In particular, the bus we're talking to is the
diff --git a/net/dns/resolver/tsdns.go b/net/dns/resolver/tsdns.go
index 97b8434cc..a73add0c9 100644
--- a/net/dns/resolver/tsdns.go
+++ b/net/dns/resolver/tsdns.go
@@ -189,8 +189,6 @@ type Resolver struct {
// closed signals all goroutines to stop.
closed chan struct{}
- // wg signals when all goroutines have stopped.
- wg sync.WaitGroup
// mu guards the following fields from being updated while used.
mu sync.Mutex
@@ -609,6 +607,7 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netip.Addr,
}
}
// Not authoritative, signal that forwarding is advisable.
+ metricDNSResolveLocalErrorRefused.Add(1)
return netip.Addr{}, dns.RCodeRefused
}
@@ -1248,6 +1247,7 @@ func (r *Resolver) respond(query []byte) ([]byte, error) {
resp := parser.response()
resp.Header.RCode = rcode
resp.IP = ip
+ metricDNSMagicDNSSuccessName.Add(1)
return marshalResponse(resp)
}
@@ -1305,9 +1305,8 @@ var (
metricDNSFwdErrorContext = clientmetric.NewCounter("dns_query_fwd_error_context")
metricDNSFwdErrorContextGotError = clientmetric.NewCounter("dns_query_fwd_error_context_got_error")
- metricDNSFwdErrorType = clientmetric.NewCounter("dns_query_fwd_error_type")
- metricDNSFwdErrorParseAddr = clientmetric.NewCounter("dns_query_fwd_error_parse_addr")
- metricDNSFwdTruncated = clientmetric.NewCounter("dns_query_fwd_truncated")
+ metricDNSFwdErrorType = clientmetric.NewCounter("dns_query_fwd_error_type")
+ metricDNSFwdTruncated = clientmetric.NewCounter("dns_query_fwd_truncated")
metricDNSFwdUDP = clientmetric.NewCounter("dns_query_fwd_udp") // on entry
metricDNSFwdUDPWrote = clientmetric.NewCounter("dns_query_fwd_udp_wrote") // sent UDP packet
diff --git a/net/dns/resolver/tsdns_test.go b/net/dns/resolver/tsdns_test.go
index 882462012..cbef27588 100644
--- a/net/dns/resolver/tsdns_test.go
+++ b/net/dns/resolver/tsdns_test.go
@@ -37,8 +37,6 @@ var (
testipv4Arpa = dnsname.FQDN("4.3.2.1.in-addr.arpa.")
testipv6Arpa = dnsname.FQDN("f.0.e.0.d.0.c.0.b.0.a.0.9.0.8.0.7.0.6.0.5.0.4.0.3.0.2.0.1.0.0.0.ip6.arpa.")
-
- magicDNSv4Port = netip.MustParseAddrPort("100.100.100.100:53")
)
var dnsCfg = Config{
diff --git a/net/dnscache/dnscache.go b/net/dnscache/dnscache.go
index e0d6af4c1..fc3191b34 100644
--- a/net/dnscache/dnscache.go
+++ b/net/dnscache/dnscache.go
@@ -656,8 +656,6 @@ func v6addrs(aa []netip.Addr) (ret []netip.Addr) {
return ret
}
-var errTLSHandshakeTimeout = errors.New("timeout doing TLS handshake")
-
// TLSDialer is like Dialer but returns a func suitable for using with net/http.Transport.DialTLSContext.
// It returns a *tls.Conn type on success.
// On TLS cert validation failure, it can invoke a backup DNS resolution strategy.
diff --git a/net/netmon/netmon.go b/net/netmon/netmon.go
index 94a5de72f..b0872034a 100644
--- a/net/netmon/netmon.go
+++ b/net/netmon/netmon.go
@@ -220,13 +220,6 @@ func (m *Monitor) RegisterRuleDeleteCallback(callback RuleDeleteCallback) (unreg
}
}
-// isActive reports whether this monitor has been started and not yet closed.
-func (m *Monitor) isActive() bool {
- m.mu.Lock()
- defer m.mu.Unlock()
- return m.started && !m.closed
-}
-
// Start starts the monitor.
// A monitor can only be started & closed once.
func (m *Monitor) Start() {
diff --git a/net/netmon/netmon_windows.go b/net/netmon/netmon_windows.go
index a45452390..ddf13a2e4 100644
--- a/net/netmon/netmon_windows.go
+++ b/net/netmon/netmon_windows.go
@@ -181,3 +181,10 @@ func (m *winMon) somethingChanged(evt string) {
return
}
}
+
+// isActive reports whether this monitor has been started and not yet closed.
+func (m *Monitor) isActive() bool {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+ return m.started && !m.closed
+}
diff --git a/net/netutil/netutil.go b/net/netutil/netutil.go
index 2a4e0d60e..bc64e8fdc 100644
--- a/net/netutil/netutil.go
+++ b/net/netutil/netutil.go
@@ -53,12 +53,6 @@ func (ln *oneConnListener) Close() error {
return nil
}
-type dummyListener struct{}
-
-func (dummyListener) Close() error { return nil }
-func (dummyListener) Addr() net.Addr { return dummyAddr("unused-address") }
-func (dummyListener) Accept() (c net.Conn, err error) { return nil, io.EOF }
-
type dummyAddr string
func (a dummyAddr) Network() string { return string(a) }
diff --git a/net/routetable/routetable.go b/net/routetable/routetable.go
index a065de436..2884706f1 100644
--- a/net/routetable/routetable.go
+++ b/net/routetable/routetable.go
@@ -15,6 +15,7 @@ import (
)
var (
+ //lint:ignore U1000 used in routetable_linux_test.go and routetable_bsd_test.go
defaultRouteIPv4 = RouteDestination{Prefix: netip.PrefixFrom(netip.IPv4Unspecified(), 0)}
//lint:ignore U1000 used in routetable_bsd_test.go
defaultRouteIPv6 = RouteDestination{Prefix: netip.PrefixFrom(netip.IPv6Unspecified(), 0)}
diff --git a/net/tstun/wrap.go b/net/tstun/wrap.go
index c459c367f..ac5442536 100644
--- a/net/tstun/wrap.go
+++ b/net/tstun/wrap.go
@@ -99,8 +99,9 @@ type Wrapper struct {
lastActivityAtomic mono.Time // time of last send or receive
destIPActivity syncs.AtomicValue[map[netip.Addr]func()]
- destMACAtomic syncs.AtomicValue[[6]byte]
- discoKey syncs.AtomicValue[key.DiscoPublic]
+ //lint:ignore U1000 used in tap_linux.go
+ destMACAtomic syncs.AtomicValue[[6]byte]
+ discoKey syncs.AtomicValue[key.DiscoPublic]
// timeNow, if non-nil, will be used to obtain the current time.
timeNow func() time.Time
diff --git a/portlist/netstat.go b/portlist/netstat.go
index c7801ccdc..5fdef675d 100644
--- a/portlist/netstat.go
+++ b/portlist/netstat.go
@@ -55,8 +55,6 @@ func isLoopbackAddr(s mem.RO) bool {
mem.HasPrefix(s, mem.S("::1."))
}
-type nothing struct{}
-
// appendParsePortsNetstat appends to base listening ports
// from "netstat" output, read from br. See TestParsePortsNetstat
// for example input lines.
diff --git a/safesocket/pipe_windows.go b/safesocket/pipe_windows.go
index dd6d521b6..eb78b2bc1 100644
--- a/safesocket/pipe_windows.go
+++ b/safesocket/pipe_windows.go
@@ -10,7 +10,6 @@ import (
"fmt"
"net"
"runtime"
- "syscall"
"time"
"github.com/tailscale/go-winio"
@@ -26,13 +25,6 @@ func connect(path string) (net.Conn, error) {
return winio.DialPipeAccessImpLevel(ctx, path, windows.GENERIC_READ|windows.GENERIC_WRITE, winio.PipeImpLevelIdentification)
}
-func setFlags(network, address string, c syscall.RawConn) error {
- return c.Control(func(fd uintptr) {
- syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET,
- syscall.SO_REUSEADDR, 1)
- })
-}
-
// windowsSDDL is the Security Descriptor set on the namedpipe.
// It provides read/write access to all users and the local system.
// It is a var for testing, do not change this value.
diff --git a/staticcheck.conf b/staticcheck.conf
index 1e51c7d56..876998489 100644
--- a/staticcheck.conf
+++ b/staticcheck.conf
@@ -14,4 +14,5 @@ checks = [
"QF1004", # Use `strings.ReplaceAll` instead of `strings.Replace` with `n == 1`
"QF1006", # Lift if+break into loop condition
+ "U1000", # catch unused code
]
diff --git a/tstest/integration/vms/opensuse_leap_15_1_test.go b/tstest/integration/vms/opensuse_leap_15_1_test.go
index be8690c45..7d3ac579e 100644
--- a/tstest/integration/vms/opensuse_leap_15_1_test.go
+++ b/tstest/integration/vms/opensuse_leap_15_1_test.go
@@ -1,6 +1,8 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
+//go:build !windows && !plan9
+
package vms
import (
diff --git a/util/linuxfw/helpers.go b/util/linuxfw/helpers.go
index 7526d68ed..5d76adac6 100644
--- a/util/linuxfw/helpers.go
+++ b/util/linuxfw/helpers.go
@@ -1,6 +1,8 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
+//go:build linux
+
package linuxfw
import (
diff --git a/util/linuxfw/linuxfw_unsupported.go b/util/linuxfw/linuxfw_unsupported.go
index 003d4bdff..7bfb4fd01 100644
--- a/util/linuxfw/linuxfw_unsupported.go
+++ b/util/linuxfw/linuxfw_unsupported.go
@@ -5,7 +5,7 @@
// support in upstream dependencies.
// TODO(#8502): add support for more architectures
-//go:build !linux || (linux && !(arm64 || amd64))
+//go:build linux && !(arm64 || amd64)
package linuxfw
diff --git a/util/winutil/restartmgr_windows.go b/util/winutil/restartmgr_windows.go
index 254b736b2..9fface9ca 100644
--- a/util/winutil/restartmgr_windows.go
+++ b/util/winutil/restartmgr_windows.go
@@ -112,6 +112,7 @@ const (
type _RM_APP_STATUS uint32
const (
+ //lint:ignore U1000 maps to a win32 API
_RmStatusUnknown _RM_APP_STATUS = 0x0
_RmStatusRunning _RM_APP_STATUS = 0x1
_RmStatusStopped _RM_APP_STATUS = 0x2
diff --git a/util/winutil/subprocess_windows_test.go b/util/winutil/subprocess_windows_test.go
index 4c6bb5977..f7c205d61 100644
--- a/util/winutil/subprocess_windows_test.go
+++ b/util/winutil/subprocess_windows_test.go
@@ -12,11 +12,9 @@ import (
"os/exec"
"path/filepath"
"runtime"
- "strconv"
"strings"
"sync"
"testing"
- "time"
)
// The code in this file is adapted from internal/testenv in the Go source tree
@@ -52,15 +50,6 @@ func pathToTestProg(t *testing.T, binary string) string {
return exe
}
-func runTestProg(t *testing.T, binary, name string, env ...string) string {
- exe, err := buildTestProg(t, binary, "-buildvcs=false")
- if err != nil {
- t.Fatal(err)
- }
-
- return runBuiltTestProg(t, exe, name, env...)
-}
-
func startTestProg(t *testing.T, binary, name string, env ...string) {
exe, err := buildTestProg(t, binary, "-buildvcs=false")
if err != nil {
@@ -70,16 +59,6 @@ func startTestProg(t *testing.T, binary, name string, env ...string) {
startBuiltTestProg(t, exe, name, env...)
}
-func runBuiltTestProg(t *testing.T, exe, name string, env ...string) string {
- cmd := exec.Command(exe, name)
- cmd.Env = append(cmd.Env, env...)
- if testing.Short() {
- cmd.Env = append(cmd.Env, "RUNTIME_TEST_SHORT=1")
- }
- out, _ := runWithTimeout(t, cmd)
- return string(out)
-}
-
func startBuiltTestProg(t *testing.T, exe, name string, env ...string) {
cmd := exec.Command(exe, name)
cmd.Env = append(cmd.Env, env...)
@@ -276,20 +255,6 @@ func mustHaveGoBuild(t testing.TB) {
}
}
-// hasGoRun reports whether the current system can run programs with “go run.”
-func hasGoRun() bool {
- // For now, having go run and having go build are the same.
- return hasGoBuild()
-}
-
-// mustHaveGoRun checks that the current system can run programs with “go run.”
-// If not, mustHaveGoRun calls t.Skip with an explanation.
-func mustHaveGoRun(t testing.TB) {
- if !hasGoRun() {
- t.Skipf("skipping test: 'go run' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
- }
-}
-
var (
gorootOnce sync.Once
gorootPath string
@@ -366,57 +331,6 @@ func findGOROOT() (string, error) {
return gorootPath, gorootErr
}
-// runWithTimeout runs cmd and returns its combined output. If the
-// subprocess exits with a non-zero status, it will log that status
-// and return a non-nil error, but this is not considered fatal.
-func runWithTimeout(t testing.TB, cmd *exec.Cmd) ([]byte, error) {
- args := cmd.Args
- if args == nil {
- args = []string{cmd.Path}
- }
-
- var b bytes.Buffer
- cmd.Stdout = &b
- cmd.Stderr = &b
- if err := cmd.Start(); err != nil {
- t.Fatalf("starting %s: %v", args, err)
- }
-
- // If the process doesn't complete within 1 minute,
- // assume it is hanging and kill it to get a stack trace.
- p := cmd.Process
- done := make(chan bool)
- go func() {
- scale := 2
- if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
- if sc, err := strconv.Atoi(s); err == nil {
- scale = sc
- }
- }
-
- select {
- case <-done:
- case <-time.After(time.Duration(scale) * time.Minute):
- p.Signal(os.Kill)
- // If SIGQUIT doesn't do it after a little
- // while, kill the process.
- select {
- case <-done:
- case <-time.After(time.Duration(scale) * 30 * time.Second):
- p.Signal(os.Kill)
- }
- }
- }()
-
- err := cmd.Wait()
- if err != nil {
- t.Logf("%s exit status: %v", args, err)
- }
- close(done)
-
- return b.Bytes(), err
-}
-
// start runs cmd asynchronously and returns immediately.
func start(t testing.TB, cmd *exec.Cmd) {
args := cmd.Args
diff --git a/util/winutil/winutil_windows.go b/util/winutil/winutil_windows.go
index 53f368343..5a8df5bb9 100644
--- a/util/winutil/winutil_windows.go
+++ b/util/winutil/winutil_windows.go
@@ -382,26 +382,6 @@ func CreateAppMutex(name string) (windows.Handle, error) {
return windows.CreateMutex(nil, false, windows.StringToUTF16Ptr(name))
}
-// getTokenInfoVariableLen obtains variable-length token information. Use
-// this function for information classes that output variable-length data.
-func getTokenInfoVariableLen[T any](token windows.Token, infoClass uint32) (*T, error) {
- var buf []byte
- var desiredLen uint32
-
- err := windows.GetTokenInformation(token, infoClass, nil, 0, &desiredLen)
-
- for err == windows.ERROR_INSUFFICIENT_BUFFER {
- buf = make([]byte, desiredLen)
- err = windows.GetTokenInformation(token, infoClass, unsafe.SliceData(buf), desiredLen, &desiredLen)
- }
-
- if err != nil {
- return nil, err
- }
-
- return (*T)(unsafe.Pointer(unsafe.SliceData(buf))), nil
-}
-
// getTokenInfoFixedLen obtains known fixed-length token information. Use this
// function for information classes that output enumerations, BOOLs, integers etc.
func getTokenInfoFixedLen[T any](token windows.Token, infoClass uint32) (result T, err error) {
diff --git a/wgengine/magicsock/debugknobs.go b/wgengine/magicsock/debugknobs.go
index 824c677f6..a8bbc61ff 100644
--- a/wgengine/magicsock/debugknobs.go
+++ b/wgengine/magicsock/debugknobs.go
@@ -53,8 +53,12 @@ var (
// discovery on UDP connections between peers. Currently (2023-09-05)
// this only turns on the don't fragment bit for the magicsock UDP
// sockets.
+ //
+ //lint:ignore U1000 used on Linux/Darwin only
debugEnablePMTUD = envknob.RegisterOptBool("TS_DEBUG_ENABLE_PMTUD")
// debugPMTUD prints extra debugging about peer MTU path discovery.
+ //
+ //lint:ignore U1000 used on Linux/Darwin only
debugPMTUD = envknob.RegisterBool("TS_DEBUG_PMTUD")
// Hey you! Adding a new debugknob? Make sure to stub it out in the
// debugknobs_stubs.go file too.
diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go
index ea4ebb05f..0d1a15a22 100644
--- a/wgengine/magicsock/magicsock.go
+++ b/wgengine/magicsock/magicsock.go
@@ -169,6 +169,8 @@ type Conn struct {
port atomic.Uint32
// peerMTUEnabled is whether path MTU discovery to peers is enabled.
+ //
+ //lint:ignore U1000 used on Linux/Darwin only
peerMTUEnabled atomic.Bool
// stats maintains per-connection counters.
@@ -2933,7 +2935,9 @@ var (
metricDERPHomeChange = clientmetric.NewCounter("derp_home_change")
// Disco packets received bpf read path
+ //lint:ignore U1000 used on Linux only
metricRecvDiscoPacketIPv4 = clientmetric.NewCounter("magicsock_disco_recv_bpf_ipv4")
+ //lint:ignore U1000 used on Linux only
metricRecvDiscoPacketIPv6 = clientmetric.NewCounter("magicsock_disco_recv_bpf_ipv6")
// metricMaxPeerMTUProbed is the largest peer path MTU we successfully probed.
diff --git a/wgengine/magicsock/peermtu_stubs.go b/wgengine/magicsock/peermtu_stubs.go
index 6981f28c3..4675e2501 100644
--- a/wgengine/magicsock/peermtu_stubs.go
+++ b/wgengine/magicsock/peermtu_stubs.go
@@ -5,31 +5,6 @@
package magicsock
-import (
- "errors"
-)
-
-// setDontFragment sets the don't fragment sockopt on the underlying connection
-// specified by network, which must be "udp4" or "udp6". See
-// https://datatracker.ietf.org/doc/html/rfc3542#section-11.2 for details on
-// IPv6 fragmentation.
-//
-// Return values:
-// - an error if peer MTU is not supported on this OS
-// - errNoActiveUDP if the underlying connection is not UDP
-// - otherwise, the result of setting the don't fragment bit
-func (c *Conn) setDontFragment(network string, enable bool) error {
- return errors.New("peer path MTU discovery not supported on this OS")
-}
-
-// getDontFragment gets the don't fragment setting on the underlying connection
-// specified by network, which must be "udp4" or "udp6". Returns true if the
-// underlying connection is UDP and the don't fragment bit is set, otherwise
-// false.
-func (c *Conn) getDontFragment(network string) (bool, error) {
- return false, nil
-}
-
func (c *Conn) DontFragSetting() (bool, error) {
return false, nil
}
diff --git a/wgengine/router/ifconfig_windows.go b/wgengine/router/ifconfig_windows.go
index ef098e542..414a8b708 100644
--- a/wgengine/router/ifconfig_windows.go
+++ b/wgengine/router/ifconfig_windows.go
@@ -9,7 +9,6 @@ import (
"errors"
"fmt"
"log"
- "net"
"net/netip"
"slices"
"sort"
@@ -28,8 +27,6 @@ import (
"tailscale.com/wgengine/winnet"
)
-var wintunLinkLocal = netip.MustParseAddr("fe80::99d0:ec2d:b2e7:536b")
-
// monitorDefaultRoutes subscribes to route change events and updates
// the Tailscale tunnel interface's MTU to match that of the
// underlying default route.
@@ -470,21 +467,6 @@ func configureInterface(cfg *Config, tun *tun.NativeTun) (retErr error) {
return errAcc
}
-// unwrapIP returns the shortest version of ip.
-func unwrapIP(ip net.IP) net.IP {
- if ip4 := ip.To4(); ip4 != nil {
- return ip4
- }
- return ip
-}
-
-func v4Mask(m net.IPMask) net.IPMask {
- if len(m) == 16 {
- return m[12:]
- }
- return m
-}
-
func netCompare(a, b netip.Prefix) int {
aip, bip := a.Addr().Unmap(), b.Addr().Unmap()
v := aip.Compare(bip)
diff --git a/wgengine/router/router_test.go b/wgengine/router/router_test.go
index 9c02a1bb4..0b20f8807 100644
--- a/wgengine/router/router_test.go
+++ b/wgengine/router/router_test.go
@@ -11,6 +11,7 @@ import (
"tailscale.com/types/preftype"
)
+//lint:ignore U1000 used in Windows/Linux tests only
func mustCIDRs(ss ...string) []netip.Prefix {
var ret []netip.Prefix
for _, s := range ss {