all: cleanup unused code, part 2 (#10670)
And enable U1000 check in staticcheck. Updates #cleanup Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
+6
-49
@@ -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" &&
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -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)}
|
||||
|
||||
+3
-2
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user