all: use Go 1.26 things, run most gofix modernizers

I omitted a lot of the min/max modernizers because they didn't
result in more clear code.

Some of it's older "for x := range 123".

Also: errors.AsType, any, fmt.Appendf, etc.

Updates #18682

Change-Id: I83a451577f33877f962766a5b65ce86f7696471c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2026-03-05 21:13:57 +00:00
committed by Brad Fitzpatrick
parent 4453cc5f53
commit bd2a2d53d3
168 changed files with 431 additions and 618 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ import (
func TestInversePrefix(t *testing.T) {
t.Parallel()
for i := range 256 {
for len := 0; len < 9; len++ {
for len := range 9 {
addr := i & (0xFF << (8 - len))
idx := prefixIndex(uint8(addr), len)
addr2, len2 := inversePrefixIndex(idx)
@@ -94,8 +94,7 @@ func TestCaptivePortalRequest(t *testing.T) {
now := time.Now()
d.clock = func() time.Time { return now }
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx := t.Context()
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
@@ -133,8 +132,7 @@ func TestCaptivePortalRequest(t *testing.T) {
func TestAgainstDERPHandler(t *testing.T) {
d := NewDetector(t.Logf)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx := t.Context()
s := httptest.NewServer(http.HandlerFunc(derpserver.ServeNoContent))
defer s.Close()
+1 -1
View File
@@ -380,7 +380,7 @@ func isLibnssResolveUsed(env newOSConfigEnv) error {
if err != nil {
return fmt.Errorf("reading /etc/resolv.conf: %w", err)
}
for _, line := range strings.Split(string(bs), "\n") {
for line := range strings.SplitSeq(string(bs), "\n") {
fields := strings.Fields(line)
if len(fields) < 2 || fields[0] != "hosts:" {
continue
+1 -1
View File
@@ -82,7 +82,7 @@ func (m openresolvManager) GetBaseConfig() (OSConfig, error) {
// Remove the "tailscale" snippet from the list.
args := []string{"-l"}
for _, f := range strings.Split(strings.TrimSpace(string(bs)), " ") {
for f := range strings.SplitSeq(strings.TrimSpace(string(bs)), " ") {
if f == "tailscale" {
continue
}
+1 -2
View File
@@ -727,8 +727,7 @@ func (f *forwarder) send(ctx context.Context, fq *forwardQuery, rr resolverAndDe
}
// If we got a truncated UDP response, return that instead of an error.
var trErr truncatedResponseError
if errors.As(err, &trErr) {
if trErr, ok := errors.AsType[truncatedResponseError](err); ok {
return trErr.res, nil
}
return nil, err
+6 -10
View File
@@ -328,7 +328,7 @@ func runDNSServer(tb testing.TB, opts *testDNSServerOptions, response []byte, on
udpLn *net.UDPConn
err error
)
for try := 0; try < tries; try++ {
for range tries {
if tcpLn != nil {
tcpLn.Close()
tcpLn = nil
@@ -392,9 +392,7 @@ func runDNSServer(tb testing.TB, opts *testDNSServerOptions, response []byte, on
var wg sync.WaitGroup
if opts == nil || !opts.SkipTCP {
wg.Add(1)
go func() {
defer wg.Done()
wg.Go(func() {
for {
conn, err := tcpLn.Accept()
if err != nil {
@@ -402,7 +400,7 @@ func runDNSServer(tb testing.TB, opts *testDNSServerOptions, response []byte, on
}
go handleConn(conn)
}
}()
})
}
handleUDP := func(addr netip.AddrPort, req []byte) {
@@ -413,9 +411,7 @@ func runDNSServer(tb testing.TB, opts *testDNSServerOptions, response []byte, on
}
if opts == nil || !opts.SkipUDP {
wg.Add(1)
go func() {
defer wg.Done()
wg.Go(func() {
for {
buf := make([]byte, 65535)
n, addr, err := udpLn.ReadFromUDPAddrPort(buf)
@@ -425,7 +421,7 @@ func runDNSServer(tb testing.TB, opts *testDNSServerOptions, response []byte, on
buf = buf[:n]
go handleUDP(addr, buf)
}
}()
})
}
tb.Cleanup(func() {
@@ -684,7 +680,7 @@ func makeResponseOfSize(tb testing.TB, domain string, targetSize int, includeOPT
var response []byte
var err error
for attempt := 0; attempt < 10; attempt++ {
for range 10 {
testBuilder := dns.NewBuilder(nil, dns.Header{
Response: true,
Authoritative: true,
+2 -2
View File
@@ -16,7 +16,7 @@ import (
"net/netip"
"os"
"runtime"
"sort"
"slices"
"strconv"
"strings"
"sync"
@@ -172,7 +172,7 @@ func WriteRoutes(w *bufio.Writer, routes map[dnsname.FQDN][]*dnstype.Resolver) {
}
kk = append(kk, k)
}
sort.Slice(kk, func(i, j int) bool { return kk[i] < kk[j] })
slices.Sort(kk)
w.WriteByte('{')
for i, k := range kk {
if i > 0 {
+1 -2
View File
@@ -172,8 +172,7 @@ func (fs wslFS) Truncate(name string) error { return fs.WriteFile(name, nil, 064
func (fs wslFS) ReadFile(name string) ([]byte, error) {
b, err := wslCombinedOutput(fs.cmd("cat", "--", name))
var ee *exec.ExitError
if errors.As(err, &ee) && ee.ExitCode() == 1 {
if ee, ok := errors.AsType[*exec.ExitError](err); ok && ee.ExitCode() == 1 {
return nil, os.ErrNotExist
}
return b, err
+5 -9
View File
@@ -545,7 +545,7 @@ func makeProbePlanInitial(dm *tailcfg.DERPMap, ifState *netmon.State) (plan prob
var p4 []probe
var p6 []probe
for try := 0; try < 3; try++ {
for try := range 3 {
n := reg.Nodes[try%len(reg.Nodes)]
delay := time.Duration(try) * defaultInitialRetransmitTime
if n.IPv4 != "none" && ((ifState.HaveV4 && nodeMight4(n)) || n.IsTestNode()) {
@@ -975,13 +975,11 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap, opts *GetRe
// need to close the underlying Pinger after a timeout
// or when all ICMP probes are done, regardless of
// whether the HTTPS probes have finished.
wg.Add(1)
go func() {
defer wg.Done()
wg.Go(func() {
if err := c.measureAllICMPLatency(ctx, rs, need); err != nil {
c.logf("[v1] measureAllICMPLatency: %v", err)
}
}()
})
}
wg.Add(len(need))
c.logf("netcheck: UDP is blocked, trying HTTPS")
@@ -1072,9 +1070,7 @@ func (c *Client) runHTTPOnlyChecks(ctx context.Context, last *Report, rs *report
if len(rg.Nodes) == 0 {
continue
}
wg.Add(1)
go func() {
defer wg.Done()
wg.Go(func() {
node := rg.Nodes[0]
req, _ := http.NewRequestWithContext(ctx, "HEAD", "https://"+node.HostName+"/derp/probe", nil)
// One warm-up one to get HTTP connection set
@@ -1099,7 +1095,7 @@ func (c *Client) runHTTPOnlyChecks(ctx context.Context, last *Report, rs *report
}
d := c.timeNow().Sub(t0)
rs.addNodeLatency(node, netip.AddrPort{}, d)
}()
})
}
wg.Wait()
return nil
+3 -6
View File
@@ -42,8 +42,7 @@ func TestBasic(t *testing.T) {
c := newTestClient(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx := t.Context()
if err := c.Standalone(ctx, "127.0.0.1:0"); err != nil {
t.Fatal(err)
@@ -124,8 +123,7 @@ func TestWorksWhenUDPBlocked(t *testing.T) {
c := newTestClient(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx := t.Context()
r, err := c.GetReport(ctx, dm, nil)
if err != nil {
@@ -1038,8 +1036,7 @@ func TestNoUDPNilGetReportOpts(t *testing.T) {
}
c := newTestClient(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx := t.Context()
r, err := c.GetReport(ctx, dm, nil)
if err != nil {
+1 -2
View File
@@ -12,8 +12,7 @@ import (
func init() {
shouldDisableUDPGSO = func(err error) bool {
var serr *os.SyscallError
if errors.As(err, &serr) {
if serr, ok := errors.AsType[*os.SyscallError](err); ok {
// EIO is returned by udp_send_skb() if the device driver does not
// have tx checksumming enabled, which is a hard requirement of
// UDP_SEGMENT. See:
+2 -5
View File
@@ -812,11 +812,8 @@ func (m *Monitor) HasCGNATInterface() (bool, error) {
if hasCGNATInterface || !i.IsUp() || isTailscaleInterface(i.Name, pfxs) {
return
}
for _, pfx := range pfxs {
if cgnatRange.Overlaps(pfx) {
hasCGNATInterface = true
break
}
if slices.ContainsFunc(pfxs, cgnatRange.Overlaps) {
hasCGNATInterface = true
}
})
if err != nil {
+2 -2
View File
@@ -41,8 +41,8 @@ func CalcAdvertiseRoutes(advertiseRoutes string, advertiseDefaultRoute bool) ([]
routeMap := map[netip.Prefix]bool{}
if advertiseRoutes != "" {
var default4, default6 bool
advroutes := strings.Split(advertiseRoutes, ",")
for _, s := range advroutes {
advroutes := strings.SplitSeq(advertiseRoutes, ",")
for s := range advroutes {
ipp, err := netip.ParsePrefix(s)
if err != nil {
return nil, fmt.Errorf("%q is not a valid IP address or CIDR prefix", s)
+3 -4
View File
@@ -21,6 +21,7 @@ import (
"io"
"log"
"net"
"slices"
"strconv"
"time"
@@ -488,10 +489,8 @@ func parseClientGreeting(r io.Reader, authMethod byte) error {
if err != nil {
return fmt.Errorf("could not read methods")
}
for _, m := range methods {
if m == authMethod {
return nil
}
if slices.Contains(methods, authMethod) {
return nil
}
return fmt.Errorf("no acceptable auth methods")
}
+4 -4
View File
@@ -180,11 +180,11 @@ func TestUDP(t *testing.T) {
const echoServerNumber = 3
echoServerListener := make([]net.PacketConn, echoServerNumber)
for i := 0; i < echoServerNumber; i++ {
for i := range echoServerNumber {
echoServerListener[i] = newUDPEchoServer()
}
defer func() {
for i := 0; i < echoServerNumber; i++ {
for i := range echoServerNumber {
_ = echoServerListener[i].Close()
}
}()
@@ -277,10 +277,10 @@ func TestUDP(t *testing.T) {
}
defer socks5UDPConn.Close()
for i := 0; i < echoServerNumber; i++ {
for i := range echoServerNumber {
port := echoServerListener[i].LocalAddr().(*net.UDPAddr).Port
addr := socksAddr{addrType: ipv4, addr: "127.0.0.1", port: uint16(port)}
requestBody := []byte(fmt.Sprintf("Test %d", i))
requestBody := fmt.Appendf(nil, "Test %d", i)
responseBody := sendUDPAndWaitResponse(socks5UDPConn, addr, requestBody)
if !bytes.Equal(requestBody, responseBody) {
t.Fatalf("got: %q want: %q", responseBody, requestBody)
+1 -2
View File
@@ -60,8 +60,7 @@ func TestSTUNServer(t *testing.T) {
func BenchmarkServerSTUN(b *testing.B) {
b.ReportAllocs()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx := b.Context()
s := New(ctx)
s.Listen("localhost:0")
+2 -2
View File
@@ -1406,11 +1406,11 @@ func (t *Wrapper) InjectInboundPacketBuffer(pkt *netstack_PacketBuffer, buffs []
return err
}
}
for i := 0; i < n; i++ {
for i := range n {
buffs[i] = buffs[i][:PacketStartOffset+sizes[i]]
}
defer func() {
for i := 0; i < n; i++ {
for i := range n {
buffs[i] = buffs[i][:cap(buffs[i])]
}
}()
+5 -5
View File
@@ -95,7 +95,7 @@ func tcp4syn(src, dst string, sport, dport uint16) []byte {
func nets(nets ...string) (ret []netip.Prefix) {
for _, s := range nets {
if i := strings.IndexByte(s, '/'); i == -1 {
if found := strings.Contains(s, "/"); !found {
ip, err := netip.ParseAddr(s)
if err != nil {
panic(err)
@@ -122,13 +122,13 @@ func ports(s string) filter.PortRange {
}
var fs, ls string
i := strings.IndexByte(s, '-')
if i == -1 {
before, after, ok := strings.Cut(s, "-")
if !ok {
fs = s
ls = fs
} else {
fs = s[:i]
ls = s[i+1:]
fs = before
ls = after
}
first, err := strconv.ParseInt(fs, 10, 16)
if err != nil {
+1 -1
View File
@@ -977,7 +977,7 @@ func (e ErrServerNotReady) Error() string {
// For now, we favor simplicity and reducing VNI re-use over more complex
// ephemeral port (VNI) selection algorithms.
func (s *Server) getNextVNILocked() (uint32, error) {
for i := uint32(0); i < totalPossibleVNI; i++ {
for range totalPossibleVNI {
vni := s.nextVNI
if vni == maxVNI {
s.nextVNI = minVNI
+2 -2
View File
@@ -265,7 +265,7 @@ func TestServer(t *testing.T) {
tcB := newTestClient(t, endpoint.VNI, tcBServerEndpointAddr, discoB, discoA.Public(), endpoint.ServerDisco)
defer tcB.close()
for i := 0; i < 2; i++ {
for range 2 {
// We handshake both clients twice to guarantee server-side
// packet reading goroutines, which are independent across
// address families, have seen an answer from both clients
@@ -345,7 +345,7 @@ func TestServer_getNextVNILocked(t *testing.T) {
s := &Server{
nextVNI: minVNI,
}
for i := uint64(0); i < uint64(totalPossibleVNI); i++ {
for range uint64(totalPossibleVNI) {
vni, err := s.getNextVNILocked()
if err != nil { // using quicktest here triples test time
t.Fatal(err)