diff --git a/bits.go b/bits.go index c91cbb61..5a0eaad5 100644 --- a/bits.go +++ b/bits.go @@ -79,10 +79,7 @@ func (b *Bits) clearRange(startPos, count uint64) uint64 { // handle the potential partial word before pos becomes u64 aligned word := pos >> 6 bit := pos & 63 - take := min(uint64(64)-bit, remaining) - if take > b.length-pos { - take = b.length - pos - } + take := min(min(uint64(64)-bit, remaining), b.length-pos) var mask uint64 if take == 64 { mask = math.MaxUint64 diff --git a/cert/sign_test.go b/cert/sign_test.go index bf4c9c0d..46d149e3 100644 --- a/cert/sign_test.go +++ b/cert/sign_test.go @@ -120,7 +120,7 @@ func TestCertificate_SignP256_AlwaysNormalized(t *testing.T) { pub := elliptic.Marshal(elliptic.P256(), priv.PublicKey.X, priv.PublicKey.Y) rawPriv := priv.D.FillBytes(make([]byte, 32)) - for i := 0; i < 1000; i++ { + for i := range 1000 { if i&1 == 1 { tbs.Version = Version1 } else { diff --git a/cmd/nebula-cert/ca.go b/cmd/nebula-cert/ca.go index 0ec82d71..178d0a83 100644 --- a/cmd/nebula-cert/ca.go +++ b/cmd/nebula-cert/ca.go @@ -151,7 +151,7 @@ func ca(args []string, out io.Writer, errOut io.Writer, pr PasswordReader) error var groups []string if *cf.groups != "" { - for _, rg := range strings.Split(*cf.groups, ",") { + for rg := range strings.SplitSeq(*cf.groups, ",") { g := strings.TrimSpace(rg) if g != "" { groups = append(groups, g) @@ -171,7 +171,7 @@ func ca(args []string, out io.Writer, errOut io.Writer, pr PasswordReader) error } if *cf.networks != "" { - for _, rs := range strings.Split(*cf.networks, ",") { + for rs := range strings.SplitSeq(*cf.networks, ",") { rs := strings.Trim(rs, " ") if rs != "" { n, err := netip.ParsePrefix(rs) @@ -193,7 +193,7 @@ func ca(args []string, out io.Writer, errOut io.Writer, pr PasswordReader) error } if *cf.unsafeNetworks != "" { - for _, rs := range strings.Split(*cf.unsafeNetworks, ",") { + for rs := range strings.SplitSeq(*cf.unsafeNetworks, ",") { rs := strings.Trim(rs, " ") if rs != "" { n, err := netip.ParsePrefix(rs) @@ -221,7 +221,7 @@ func ca(args []string, out io.Writer, errOut io.Writer, pr PasswordReader) error if !isP11 && *cf.encryption { passphrase = []byte(os.Getenv("NEBULA_CA_PASSPHRASE")) if len(passphrase) == 0 { - for i := 0; i < 5; i++ { + for range 5 { errOut.Write([]byte("Enter passphrase: ")) passphrase, err = pr.ReadPassword() diff --git a/cmd/nebula-cert/ca_test.go b/cmd/nebula-cert/ca_test.go index e2389ceb..0201a3f8 100644 --- a/cmd/nebula-cert/ca_test.go +++ b/cmd/nebula-cert/ca_test.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package main diff --git a/cmd/nebula-cert/sign.go b/cmd/nebula-cert/sign.go index 27ea051d..10ff3121 100644 --- a/cmd/nebula-cert/sign.go +++ b/cmd/nebula-cert/sign.go @@ -146,7 +146,7 @@ func signCert(args []string, out io.Writer, errOut io.Writer, pr PasswordReader) passphrase = []byte(os.Getenv("NEBULA_CA_PASSPHRASE")) if len(passphrase) == 0 { // ask for a passphrase until we get one - for i := 0; i < 5; i++ { + for range 5 { errOut.Write([]byte("Enter passphrase: ")) passphrase, err = pr.ReadPassword() @@ -203,7 +203,7 @@ func signCert(args []string, out io.Writer, errOut io.Writer, pr PasswordReader) } if *sf.networks != "" { - for _, rs := range strings.Split(*sf.networks, ",") { + for rs := range strings.SplitSeq(*sf.networks, ",") { rs := strings.Trim(rs, " ") if rs != "" { n, err := netip.ParsePrefix(rs) @@ -228,7 +228,7 @@ func signCert(args []string, out io.Writer, errOut io.Writer, pr PasswordReader) } if *sf.unsafeNetworks != "" { - for _, rs := range strings.Split(*sf.unsafeNetworks, ",") { + for rs := range strings.SplitSeq(*sf.unsafeNetworks, ",") { rs := strings.Trim(rs, " ") if rs != "" { n, err := netip.ParsePrefix(rs) @@ -247,7 +247,7 @@ func signCert(args []string, out io.Writer, errOut io.Writer, pr PasswordReader) var groups []string if *sf.groups != "" { - for _, rg := range strings.Split(*sf.groups, ",") { + for rg := range strings.SplitSeq(*sf.groups, ",") { g := strings.TrimSpace(rg) if g != "" { groups = append(groups, g) diff --git a/cmd/nebula-cert/sign_test.go b/cmd/nebula-cert/sign_test.go index 64d5c7d9..10388ca8 100644 --- a/cmd/nebula-cert/sign_test.go +++ b/cmd/nebula-cert/sign_test.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package main diff --git a/cmd/nebula-service/logs_generic.go b/cmd/nebula-service/logs_generic.go index cc06b4c5..498e96cc 100644 --- a/cmd/nebula-service/logs_generic.go +++ b/cmd/nebula-service/logs_generic.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package main diff --git a/cmd/nebula/notify_notlinux.go b/cmd/nebula/notify_notlinux.go index 48cfe949..70063ef7 100644 --- a/cmd/nebula/notify_notlinux.go +++ b/cmd/nebula/notify_notlinux.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux package main diff --git a/config/config.go b/config/config.go index 5bf994a1..79cdce0f 100644 --- a/config/config.go +++ b/config/config.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log/slog" + "maps" "math" "os" "os/signal" @@ -154,9 +155,7 @@ func (c *C) ReloadConfig() { defer c.reloadLock.Unlock() c.oldSettings = make(map[string]any) - for k, v := range c.Settings { - c.oldSettings[k] = v - } + maps.Copy(c.oldSettings, c.Settings) err := c.Load(c.path) if err != nil { @@ -177,9 +176,7 @@ func (c *C) ReloadConfigString(raw string) error { defer c.reloadLock.Unlock() c.oldSettings = make(map[string]any) - for k, v := range c.Settings { - c.oldSettings[k] = v - } + maps.Copy(c.oldSettings, c.Settings) err := c.LoadString(raw) if err != nil { @@ -216,7 +213,7 @@ func (c *C) GetStringSlice(k string, d []string) []string { } v := make([]string, len(rv)) - for i := 0; i < len(v); i++ { + for i := range v { v[i] = fmt.Sprintf("%v", rv[i]) } @@ -310,8 +307,8 @@ func (c *C) IsSet(k string) bool { } func (c *C) get(k string, v any) any { - parts := strings.Split(k, ".") - for _, p := range parts { + parts := strings.SplitSeq(k, ".") + for p := range parts { m, ok := v.(map[string]any) if !ok { return nil diff --git a/e2e/echo_test.go b/e2e/echo_test.go index 5e1299b2..945c7b12 100644 --- a/e2e/echo_test.go +++ b/e2e/echo_test.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package e2e diff --git a/e2e/handshake_manager_test.go b/e2e/handshake_manager_test.go index b06564d1..472b5fe6 100644 --- a/e2e/handshake_manager_test.go +++ b/e2e/handshake_manager_test.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package e2e diff --git a/e2e/handshakes_test.go b/e2e/handshakes_test.go index 0c0bdf44..aef2e8d1 100644 --- a/e2e/handshakes_test.go +++ b/e2e/handshakes_test.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package e2e diff --git a/e2e/helpers_test.go b/e2e/helpers_test.go index 1691aeab..8a82af2f 100644 --- a/e2e/helpers_test.go +++ b/e2e/helpers_test.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package e2e diff --git a/e2e/leak_test.go b/e2e/leak_test.go index 576d67a8..0f0074d6 100644 --- a/e2e/leak_test.go +++ b/e2e/leak_test.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package e2e diff --git a/e2e/rebind_test.go b/e2e/rebind_test.go index 06b4702d..29dd9f8e 100644 --- a/e2e/rebind_test.go +++ b/e2e/rebind_test.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package e2e diff --git a/e2e/recovery_timing_test.go b/e2e/recovery_timing_test.go index 0fe356c8..a5a67b52 100644 --- a/e2e/recovery_timing_test.go +++ b/e2e/recovery_timing_test.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package e2e diff --git a/e2e/router/hostmap.go b/e2e/router/hostmap.go index f2805d0c..e42f9862 100644 --- a/e2e/router/hostmap.go +++ b/e2e/router/hostmap.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package router diff --git a/e2e/router/router.go b/e2e/router/router.go index c5f69118..0a29f042 100644 --- a/e2e/router/router.go +++ b/e2e/router/router.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package router diff --git a/e2e/sshd_test.go b/e2e/sshd_test.go index e91f1bd0..d2b49c67 100644 --- a/e2e/sshd_test.go +++ b/e2e/sshd_test.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package e2e diff --git a/e2e/tunnels_test.go b/e2e/tunnels_test.go index 7874cc79..7831b7dd 100644 --- a/e2e/tunnels_test.go +++ b/e2e/tunnels_test.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package e2e diff --git a/firewall/cache_test.go b/firewall/cache_test.go index 3baf2326..2c8ad089 100644 --- a/firewall/cache_test.go +++ b/firewall/cache_test.go @@ -22,7 +22,7 @@ func newFixedTicker(t *testing.T, l *slog.Logger, cacheLen int) *ConntrackCacheT l: l, cache: make(ConntrackCache, cacheLen), } - for i := 0; i < cacheLen; i++ { + for i := range cacheLen { c.cache[Packet{LocalPort: uint16(i) + 1}] = struct{}{} } c.cacheTick.Store(1) // cacheV starts at 0, so Get() takes the reset path diff --git a/noiseutil/boring.go b/noiseutil/boring.go index c77fb573..9677ea95 100644 --- a/noiseutil/boring.go +++ b/noiseutil/boring.go @@ -1,5 +1,4 @@ //go:build boringcrypto -// +build boringcrypto package noiseutil diff --git a/noiseutil/boring_test.go b/noiseutil/boring_test.go index c15d431a..2be47dc8 100644 --- a/noiseutil/boring_test.go +++ b/noiseutil/boring_test.go @@ -1,5 +1,4 @@ //go:build boringcrypto -// +build boringcrypto package noiseutil diff --git a/overlay/batch/checksum_seed_test.go b/overlay/batch/checksum_seed_test.go index dfa19784..ce4fba77 100644 --- a/overlay/batch/checksum_seed_test.go +++ b/overlay/batch/checksum_seed_test.go @@ -127,7 +127,7 @@ func TestPseudoSumIPv6MatchesReference(t *testing.T) { func TestIPv4HdrChecksumMatchesReference(t *testing.T) { rng := rand.New(rand.NewSource(0x1791)) for _, hdrLen := range []int{20, 24, 40, 60} { - for trial := 0; trial < 200; trial++ { + for trial := range 200 { hdr := make([]byte, hdrLen) rng.Read(hdr) hdr[0] = 0x40 | byte(hdrLen/4) @@ -156,7 +156,7 @@ func TestIPv4HdrChecksumMatchesReference(t *testing.T) { // the way a receiver does (pseudo-header + L4 must sum to all-ones). func TestChecksumSeedReceiverAcceptance(t *testing.T) { rng := rand.New(rand.NewSource(0x1826)) - for trial := 0; trial < 200; trial++ { + for trial := range 200 { src := [4]byte{byte(rng.Intn(256)), byte(rng.Intn(256)), byte(rng.Intn(256)), byte(rng.Intn(256))} dst := [4]byte{byte(rng.Intn(256)), byte(rng.Intn(256)), byte(rng.Intn(256)), byte(rng.Intn(256))} payLen := rng.Intn(1500) diff --git a/overlay/batch/tcp_coalesce_test.go b/overlay/batch/tcp_coalesce_test.go index 9c6c4791..54cc4299 100644 --- a/overlay/batch/tcp_coalesce_test.go +++ b/overlay/batch/tcp_coalesce_test.go @@ -540,7 +540,7 @@ func TestCoalescerCapBySegments(t *testing.T) { c := newTestTCPCoalescer(t, w) pay := make([]byte, 512) seq := uint32(1000) - for i := 0; i < tcpCoalesceMaxSegs+5; i++ { + for range tcpCoalesceMaxSegs + 5 { if err := c.Commit(buildTCPv4(seq, tcpAck, pay)); err != nil { t.Fatal(err) } diff --git a/overlay/batch/tx_batch_test.go b/overlay/batch/tx_batch_test.go index 9a2a75b4..aad16e9c 100644 --- a/overlay/batch/tx_batch_test.go +++ b/overlay/batch/tx_batch_test.go @@ -28,7 +28,7 @@ func TestSendBatchReserveCommitFlush(t *testing.T) { b := NewSendBatch(fw, 4, 32) ap := netip.MustParseAddrPort("10.0.0.1:4242") - for i := 0; i < 4; i++ { + for i := range 4 { slot := b.Reserve(32) if cap(slot) != 32 { t.Fatalf("slot %d: cap=%d want 32", i, cap(slot)) @@ -72,7 +72,7 @@ func TestSendBatchSlotsDoNotOverlap(t *testing.T) { b := NewSendBatch(fw, 3, 8) ap := netip.MustParseAddrPort("10.0.0.1:80") - for i := 0; i < 3; i++ { + for i := range 3 { s := b.Reserve(8) pkt := append(s[:0], byte(0xA0+i), byte(0xB0+i)) b.Commit(pkt, ap) diff --git a/overlay/batch/udp_coalesce_test.go b/overlay/batch/udp_coalesce_test.go index c2be8e49..e1719434 100644 --- a/overlay/batch/udp_coalesce_test.go +++ b/overlay/batch/udp_coalesce_test.go @@ -129,7 +129,7 @@ func TestUDPCoalescerCoalescesEqualSized(t *testing.T) { w := &fakeTunWriter{gsoEnabled: true} c := newTestUDPCoalescer(t, w) pay := make([]byte, 1200) - for i := 0; i < 3; i++ { + for range 3 { if err := c.Commit(buildUDPv4(1000, 53, pay)); err != nil { t.Fatal(err) } @@ -259,7 +259,7 @@ func TestUDPCoalescerCapsAtMaxSegs(t *testing.T) { w := &fakeTunWriter{gsoEnabled: true} c := newTestUDPCoalescer(t, w) pay := make([]byte, 100) - for i := 0; i < udpCoalesceMaxSegs+5; i++ { + for range udpCoalesceMaxSegs + 5 { if err := c.Commit(buildUDPv4(1000, 53, pay)); err != nil { t.Fatal(err) } @@ -317,7 +317,7 @@ func TestUDPCoalescerIPv6Coalesces(t *testing.T) { w := &fakeTunWriter{gsoEnabled: true} c := newTestUDPCoalescer(t, w) pay := make([]byte, 1200) - for i := 0; i < 3; i++ { + for range 3 { if err := c.Commit(buildUDPv6(1000, 53, pay)); err != nil { t.Fatal(err) } diff --git a/overlay/checksum/checksum_test.go b/overlay/checksum/checksum_test.go index c3c39b20..8105e4bc 100644 --- a/overlay/checksum/checksum_test.go +++ b/overlay/checksum/checksum_test.go @@ -151,7 +151,7 @@ func TestChecksumTailPaths(t *testing.T) { offsets := []int{0, 1, 3, 7, 15} // mix of aligned and odd starts for k := 0; k <= maxK; k++ { - for tail := 0; tail < 64; tail++ { + for tail := range 64 { length := 64*k + tail for _, seed := range seeds { for _, off := range offsets { diff --git a/overlay/network_category_windows.go b/overlay/network_category_windows.go index cbf87f00..985a80ca 100644 --- a/overlay/network_category_windows.go +++ b/overlay/network_category_windows.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package overlay diff --git a/overlay/network_category_windows_test.go b/overlay/network_category_windows_test.go index c679f8c4..452c5ff8 100644 --- a/overlay/network_category_windows_test.go +++ b/overlay/network_category_windows_test.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package overlay diff --git a/overlay/tio/blockon_linux.go b/overlay/tio/blockon_linux.go index adea9d1b..4e89064a 100644 --- a/overlay/tio/blockon_linux.go +++ b/overlay/tio/blockon_linux.go @@ -1,5 +1,4 @@ //go:build linux && !android -// +build linux,!android package tio diff --git a/overlay/tio/queueset_gso_linux.go b/overlay/tio/queueset_gso_linux.go index 4a26193d..8d404533 100644 --- a/overlay/tio/queueset_gso_linux.go +++ b/overlay/tio/queueset_gso_linux.go @@ -1,5 +1,4 @@ //go:build linux && !android -// +build linux,!android package tio diff --git a/overlay/tio/queueset_poll_linux.go b/overlay/tio/queueset_poll_linux.go index f73deef2..d05b5cb3 100644 --- a/overlay/tio/queueset_poll_linux.go +++ b/overlay/tio/queueset_poll_linux.go @@ -1,5 +1,4 @@ //go:build linux && !android -// +build linux,!android package tio diff --git a/overlay/tio/tio_gso_linux.go b/overlay/tio/tio_gso_linux.go index 320ebf50..e5fd6d59 100644 --- a/overlay/tio/tio_gso_linux.go +++ b/overlay/tio/tio_gso_linux.go @@ -1,5 +1,4 @@ //go:build linux && !android -// +build linux,!android package tio diff --git a/overlay/tio/tio_poll_linux.go b/overlay/tio/tio_poll_linux.go index 50280f28..9d8088c8 100644 --- a/overlay/tio/tio_poll_linux.go +++ b/overlay/tio/tio_poll_linux.go @@ -1,5 +1,4 @@ //go:build linux && !android -// +build linux,!android package tio diff --git a/overlay/tio/tun_file_linux_test.go b/overlay/tio/tun_file_linux_test.go index 670da94f..1e8499f0 100644 --- a/overlay/tio/tun_file_linux_test.go +++ b/overlay/tio/tun_file_linux_test.go @@ -1,5 +1,4 @@ //go:build linux && !android && !e2e_testing -// +build linux,!android,!e2e_testing package tio @@ -117,17 +116,15 @@ func TestPoll_ConcurrentWrite_NoRace(t *testing.T) { }() var wg sync.WaitGroup - for w := 0; w < writers; w++ { - wg.Add(1) - go func() { - defer wg.Done() - for i := 0; i < perWriter; i++ { + for range writers { + wg.Go(func() { + for range perWriter { if _, werr := p.Write(payload); werr != nil { t.Errorf("write: %v", werr) return } } - }() + }) } wg.Wait() diff --git a/overlay/tio/tun_linux_offload.go b/overlay/tio/tun_linux_offload.go index 2eb54b90..7c99cd18 100644 --- a/overlay/tio/tun_linux_offload.go +++ b/overlay/tio/tun_linux_offload.go @@ -1,5 +1,4 @@ //go:build linux && !android -// +build linux,!android package tio diff --git a/overlay/tio/tun_linux_offload_test.go b/overlay/tio/tun_linux_offload_test.go index 84d44b49..e107b017 100644 --- a/overlay/tio/tun_linux_offload_test.go +++ b/overlay/tio/tun_linux_offload_test.go @@ -1,5 +1,4 @@ //go:build linux && !android && !e2e_testing -// +build linux,!android,!e2e_testing package tio @@ -137,7 +136,7 @@ func buildTSOv4(t *testing.T, payLen, mss int) ([]byte, virtio.Hdr) { binary.BigEndian.PutUint16(pkt[34:36], 65535) // window // payload - for i := 0; i < payLen; i++ { + for i := range payLen { pkt[ipLen+tcpLen+i] = byte(i & 0xff) } return pkt, virtio.NewHeader( @@ -257,7 +256,7 @@ func TestSegmentTCPv6(t *testing.T) { pkt[53] = 0x19 // FIN | ACK | PSH — exercise FIN clearing too binary.BigEndian.PutUint16(pkt[54:56], 65535) - for i := 0; i < payLen; i++ { + for i := range payLen { pkt[ipLen+tcpLen+i] = byte(i) } @@ -361,7 +360,7 @@ func buildUSOv4(t *testing.T, payLen, gsoSize int) ([]byte, virtio.Hdr) { binary.BigEndian.PutUint16(pkt[22:24], 53) // dport binary.BigEndian.PutUint16(pkt[24:26], uint16(udpLen+payLen)) // superpacket length - for i := 0; i < payLen; i++ { + for i := range payLen { pkt[ipLen+udpLen+i] = byte(i & 0xff) } @@ -473,7 +472,7 @@ func TestSegmentUDPv6(t *testing.T) { // Superpacket-wide length, as the kernel supplies it; see buildUSOv4. binary.BigEndian.PutUint16(pkt[44:46], uint16(udpLen+payLen)) - for i := 0; i < payLen; i++ { + for i := range payLen { pkt[ipLen+udpLen+i] = byte(i) } @@ -772,7 +771,7 @@ func buildTSOv6(payLen, gso int) []byte { pkt[53] = 0x10 // ACK only binary.BigEndian.PutUint16(pkt[54:56], 65535) - for i := 0; i < payLen; i++ { + for i := range payLen { pkt[ipLen+tcpLen+i] = byte(i) } return pkt diff --git a/overlay/tio/virtio/header_linux.go b/overlay/tio/virtio/header_linux.go index b3528f03..2c330047 100644 --- a/overlay/tio/virtio/header_linux.go +++ b/overlay/tio/virtio/header_linux.go @@ -1,5 +1,4 @@ //go:build linux && !android -// +build linux,!android package virtio diff --git a/overlay/tio/virtio/segment_linux.go b/overlay/tio/virtio/segment_linux.go index 0509b600..9c66fa6c 100644 --- a/overlay/tio/virtio/segment_linux.go +++ b/overlay/tio/virtio/segment_linux.go @@ -1,5 +1,4 @@ //go:build linux && !android -// +build linux,!android // Package virtio implements the pure validation, header-correction, and // per-segment slicing logic for kernel-supplied TSO/USO superpackets on @@ -254,12 +253,9 @@ func SegmentTCP(pkt []byte, hdrLenU, csumStartU, gsoSizeU uint16, yield func(seg var savedHdr [maxSegHdrLen]byte copy(savedHdr[:headerLen], pkt[:headerLen]) - for i := 0; i < numSeg; i++ { + for i := range numSeg { segStart := i * gsoSize - segEnd := segStart + gsoSize - if segEnd > payLen { - segEnd = payLen - } + segEnd := min(segStart+gsoSize, payLen) segPayLen := segEnd - segStart segLen := headerLen + segPayLen headerOff := i * gsoSize @@ -359,12 +355,9 @@ func SegmentUDP(pkt []byte, hdrLenU, csumStartU, gsoSizeU uint16, yield func(seg var savedHdr [maxSegHdrLen]byte copy(savedHdr[:headerLen], pkt[:headerLen]) - for i := 0; i < numSeg; i++ { + for i := range numSeg { segStart := i * gsoSize - segEnd := segStart + gsoSize - if segEnd > payLen { - segEnd = payLen - } + segEnd := min(segStart+gsoSize, payLen) segPayLen := segEnd - segStart segLen := headerLen + segPayLen headerOff := i * gsoSize diff --git a/overlay/tio/virtio/segment_linux_test.go b/overlay/tio/virtio/segment_linux_test.go index e7d29997..ae048560 100644 --- a/overlay/tio/virtio/segment_linux_test.go +++ b/overlay/tio/virtio/segment_linux_test.go @@ -1,5 +1,4 @@ //go:build linux && !android -// +build linux,!android package virtio @@ -58,7 +57,7 @@ func buildTCPv4Super(payLen int) (pkt []byte, hdrLen, csumStart uint16) { pkt[33] = 0x18 // ACK | PSH binary.BigEndian.PutUint16(pkt[34:36], 65535) // window - for i := 0; i < payLen; i++ { + for i := range payLen { pkt[ipLen+tcpLen+i] = byte(i & 0xff) } return pkt, ipLen + tcpLen, ipLen @@ -82,7 +81,7 @@ func buildUDPv4Super(payLen int) (pkt []byte, hdrLen, csumStart uint16) { binary.BigEndian.PutUint16(pkt[20:22], 12345) // sport binary.BigEndian.PutUint16(pkt[22:24], 53) // dport - for i := 0; i < payLen; i++ { + for i := range payLen { pkt[ipLen+udpLen+i] = byte(i & 0xff) } return pkt, ipLen + udpLen, ipLen @@ -188,7 +187,7 @@ func TestSegmentTCPHeaderNotCorrupted(t *testing.T) { // Payload bytes must be the original contiguous slice. segPayLen := len(seg) - int(hdrLen) wantPay := make([]byte, segPayLen) - for k := 0; k < segPayLen; k++ { + for k := range segPayLen { wantPay[k] = byte((off + k) & 0xff) } if !bytes.Equal(seg[hdrLen:], wantPay) { @@ -317,7 +316,7 @@ func TestSegmentUDPHeaderNotCorrupted(t *testing.T) { } wantPay := make([]byte, segPayLen) - for k := 0; k < segPayLen; k++ { + for k := range segPayLen { wantPay[k] = byte((off + k) & 0xff) } if !bytes.Equal(seg[hdrLen:], wantPay) { @@ -365,7 +364,7 @@ func buildUDPv4Single(payload []byte) (pkt []byte, hdr Hdr) { // 0xffff, because all-zero is the reserved "no checksum" encoding that IPv6 rejects outright. func TestFinishChecksumUDPZeroStoresAllOnes(t *testing.T) { var payload []byte - for i := 0; i < 0x10000; i++ { + for i := range 0x10000 { p := []byte{byte(i >> 8), byte(i)} pkt, hdr := buildUDPv4Single(p) cs, co := int(hdr.CsumStart), int(hdr.CsumOffset) @@ -544,7 +543,7 @@ func TestBaseSumsMatchZeroingReference(t *testing.T) { t.Run("ipv4", func(t *testing.T) { for ihl := ipv4HeaderMinLen; ihl <= ipv4HeaderMaxLen; ihl += 4 { - for iter := 0; iter < 5000; iter++ { + for range 5000 { pkt := make([]byte, ihl) for i := range pkt { pkt[i] = randByte(&state) @@ -574,7 +573,7 @@ func TestBaseSumsMatchZeroingReference(t *testing.T) { for dataOff := 5; dataOff <= 15; dataOff++ { tcpLen := dataOff * 4 headerLen := csumStart + tcpLen - for iter := 0; iter < 5000; iter++ { + for range 5000 { pkt := make([]byte, headerLen+64) for i := range pkt { pkt[i] = randByte(&state) diff --git a/overlay/tun.go b/overlay/tun.go index 3af1e189..39f27dd4 100644 --- a/overlay/tun.go +++ b/overlay/tun.go @@ -93,14 +93,14 @@ func prefixToMask(prefix netip.Prefix) netip.Addr { } func flipBytes(b []byte) []byte { - for i := 0; i < len(b); i++ { + for i := range b { b[i] ^= 0xFF } return b } func orBytes(a []byte, b []byte) []byte { ret := make([]byte, len(a)) - for i := 0; i < len(a); i++ { + for i := range a { ret[i] = a[i] | b[i] } return ret diff --git a/overlay/tun_android.go b/overlay/tun_android.go index f7ab417a..c7d5829b 100644 --- a/overlay/tun_android.go +++ b/overlay/tun_android.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package overlay diff --git a/overlay/tun_bypass_windows_386.go b/overlay/tun_bypass_windows_386.go index 366430b0..d8878b60 100644 --- a/overlay/tun_bypass_windows_386.go +++ b/overlay/tun_bypass_windows_386.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package overlay diff --git a/overlay/tun_darwin.go b/overlay/tun_darwin.go index 1076b687..bb5528e3 100644 --- a/overlay/tun_darwin.go +++ b/overlay/tun_darwin.go @@ -1,5 +1,4 @@ //go:build !ios && !e2e_testing -// +build !ios,!e2e_testing package overlay diff --git a/overlay/tun_freebsd.go b/overlay/tun_freebsd.go index e6479001..e2d6df10 100644 --- a/overlay/tun_freebsd.go +++ b/overlay/tun_freebsd.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package overlay diff --git a/overlay/tun_ios.go b/overlay/tun_ios.go index 56603b02..23005185 100644 --- a/overlay/tun_ios.go +++ b/overlay/tun_ios.go @@ -1,5 +1,4 @@ //go:build ios && !e2e_testing -// +build ios,!e2e_testing package overlay diff --git a/overlay/tun_linux.go b/overlay/tun_linux.go index 82d632d3..7e7e0981 100644 --- a/overlay/tun_linux.go +++ b/overlay/tun_linux.go @@ -1,5 +1,4 @@ //go:build !android && !e2e_testing -// +build !android,!e2e_testing package overlay @@ -548,7 +547,7 @@ func (t *tun) setDefaultRoute(cidr netip.Prefix) error { if err != nil { t.l.Warn("Failed to set default route MTU, retrying", "error", err, "cidr", cidr) //retry twice more -- on some systems there appears to be a race condition where if we set routes too soon, netlink says `invalid argument` - for i := 0; i < 2; i++ { + for range 2 { time.Sleep(100 * time.Millisecond) err = netlink.RouteReplace(&nr) if err == nil { diff --git a/overlay/tun_linux_test.go b/overlay/tun_linux_test.go index e074ee0a..f835ca83 100644 --- a/overlay/tun_linux_test.go +++ b/overlay/tun_linux_test.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package overlay diff --git a/overlay/tun_netbsd.go b/overlay/tun_netbsd.go index 97691543..d69ea67a 100644 --- a/overlay/tun_netbsd.go +++ b/overlay/tun_netbsd.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package overlay diff --git a/overlay/tun_notwin.go b/overlay/tun_notwin.go index 2fab9274..686321e0 100644 --- a/overlay/tun_notwin.go +++ b/overlay/tun_notwin.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package overlay diff --git a/overlay/tun_openbsd.go b/overlay/tun_openbsd.go index 23816b0d..da752e50 100644 --- a/overlay/tun_openbsd.go +++ b/overlay/tun_openbsd.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package overlay diff --git a/overlay/tun_tester.go b/overlay/tun_tester.go index 4b2685e0..39d911ec 100644 --- a/overlay/tun_tester.go +++ b/overlay/tun_tester.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package overlay diff --git a/overlay/tun_windows.go b/overlay/tun_windows.go index 6be85ffc..3493e2c5 100644 --- a/overlay/tun_windows.go +++ b/overlay/tun_windows.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package overlay diff --git a/overlay/user_test.go b/overlay/user_test.go index 9e0e9c9c..0d01dbf4 100644 --- a/overlay/user_test.go +++ b/overlay/user_test.go @@ -108,7 +108,7 @@ func TestUserDeviceReadersConcurrentRace(t *testing.T) { var wg sync.WaitGroup run := func(idx int) { defer wg.Done() - for i := 0; i < iterations; i++ { + for range iterations { pkts, err := readers[idx].Read() if err != nil { errs <- err @@ -136,7 +136,7 @@ func TestUserDeviceReadersConcurrentRace(t *testing.T) { // waiting reader's private buffer, so reusing buf between writes is safe. go func() { buf := make([]byte, 32) - for i := 0; i < 2*iterations; i++ { + for i := range 2 * iterations { for j := range buf { buf[j] = byte(i + j) } diff --git a/routing/balance_test.go b/routing/balance_test.go index bbfcb226..3fb64a47 100644 --- a/routing/balance_test.go +++ b/routing/balance_test.go @@ -27,7 +27,7 @@ func TestPacketsAreBalancedEqually(t *testing.T) { gw3count := 0 iterationCount := uint16(65535) - for i := uint16(0); i < iterationCount; i++ { + for i := range iterationCount { packet := firewall.Packet{ LocalAddr: netip.MustParseAddr("192.168.1.1"), RemoteAddr: netip.MustParseAddr("10.0.0.1"), @@ -74,7 +74,7 @@ func TestPacketsAreBalancedByPriority(t *testing.T) { gw2count := 0 iterationCount := uint16(65535) - for i := uint16(0); i < iterationCount; i++ { + for i := range iterationCount { packet := firewall.Packet{ LocalAddr: netip.MustParseAddr("192.168.1.1"), RemoteAddr: netip.MustParseAddr("10.0.0.1"), @@ -115,7 +115,7 @@ func TestBalancePacketDistributsRandomlyAndReturnsFalseIfBucketsNotCalculated(t gw1count := 0 gw2count := 0 - for i := uint16(0); i < iterationCount; i++ { + for i := range iterationCount { packet := firewall.Packet{ LocalAddr: netip.MustParseAddr("192.168.1.1"), RemoteAddr: netip.MustParseAddr("10.0.0.1"), diff --git a/routing/gateway.go b/routing/gateway.go index 88cf0933..413249b1 100644 --- a/routing/gateway.go +++ b/routing/gateway.go @@ -3,6 +3,7 @@ package routing import ( "fmt" "net/netip" + "strings" ) const ( @@ -13,14 +14,14 @@ const ( type Gateways []Gateway func (g Gateways) String() string { - str := "" + var str strings.Builder for i, gw := range g { - str += gw.String() + str.WriteString(gw.String()) if i < len(g)-1 { - str += ", " + str.WriteString(", ") } } - return str + return str.String() } type Gateway struct { diff --git a/test/assert.go b/test/assert.go index 1856877e..37a24674 100644 --- a/test/assert.go +++ b/test/assert.go @@ -25,7 +25,7 @@ func AssertDeepCopyEqual(t *testing.T, a any, b any) { } func traverseDeepCopy(t *testing.T, v1 reflect.Value, v2 reflect.Value, name string) bool { - if v1.Type() == v2.Type() && v1.Type() == reflect.TypeOf(netip.Addr{}) { + if v1.Type() == v2.Type() && v1.Type() == reflect.TypeFor[netip.Addr]() { // Ignore netip.Addr types since they reuse an interned global value return false } @@ -72,7 +72,7 @@ func traverseDeepCopy(t *testing.T, v1 reflect.Value, v2 reflect.Value, name str } return traverseDeepCopy(t, v1.Elem(), v2.Elem(), name) - case reflect.Ptr: + case reflect.Pointer: local := reflect.ValueOf(time.Local).Pointer() if local == v1.Pointer() && local == v2.Pointer() { return true diff --git a/udp/netchange_darwin.go b/udp/netchange_darwin.go index 483165e9..ac67ea79 100644 --- a/udp/netchange_darwin.go +++ b/udp/netchange_darwin.go @@ -1,5 +1,4 @@ //go:build darwin && !ios && !e2e_testing -// +build darwin,!ios,!e2e_testing package udp diff --git a/udp/netchange_darwin_test.go b/udp/netchange_darwin_test.go index a6d25c83..64176094 100644 --- a/udp/netchange_darwin_test.go +++ b/udp/netchange_darwin_test.go @@ -1,5 +1,4 @@ //go:build darwin && !ios && !e2e_testing -// +build darwin,!ios,!e2e_testing package udp diff --git a/udp/netchange_generic.go b/udp/netchange_generic.go index de5cc3a6..00cc9214 100644 --- a/udp/netchange_generic.go +++ b/udp/netchange_generic.go @@ -1,5 +1,4 @@ //go:build !darwin || ios || e2e_testing -// +build !darwin ios e2e_testing package udp diff --git a/udp/udp_android.go b/udp/udp_android.go index 9de6de2c..5db12ab1 100644 --- a/udp/udp_android.go +++ b/udp/udp_android.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package udp diff --git a/udp/udp_bypass_windows_386.go b/udp/udp_bypass_windows_386.go index fa5a6eec..073881fc 100644 --- a/udp/udp_bypass_windows_386.go +++ b/udp/udp_bypass_windows_386.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package udp diff --git a/udp/udp_darwin.go b/udp/udp_darwin.go index 6d89d61b..2bb0cf0d 100644 --- a/udp/udp_darwin.go +++ b/udp/udp_darwin.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package udp diff --git a/udp/udp_linux.go b/udp/udp_linux.go index fca713e5..cc834131 100644 --- a/udp/udp_linux.go +++ b/udp/udp_linux.go @@ -294,10 +294,7 @@ func deliverSegments(r EncReader, from netip.AddrPort, payload []byte, segSize i return } for off := 0; off < len(payload); off += segSize { - end := off + segSize - if end > len(payload) { - end = len(payload) - } + end := min(off+segSize, len(payload)) r(from, payload[off:end:end]) } } @@ -479,7 +476,7 @@ func NewUDPStatsEmitter(udpConns []Conn) func() { return func() { for i, gauges := range udpGauges { if err := udpConns[i].(*StdConn).getMemInfo(&meminfo); err == nil { - for j := 0; j < unix.SK_MEMINFO_VARS; j++ { + for j := range unix.SK_MEMINFO_VARS { gauges[j].Update(int64(meminfo[j])) } } diff --git a/udp/udp_linux_fixes_test.go b/udp/udp_linux_fixes_test.go index 8824b31f..ab8ae18f 100644 --- a/udp/udp_linux_fixes_test.go +++ b/udp/udp_linux_fixes_test.go @@ -107,7 +107,7 @@ func TestWriteBatchBadFamilyDeliversOthers(t *testing.T) { got := map[string]bool{} rx.SetReadDeadline(time.Now().Add(2 * time.Second)) buf := make([]byte, 64) - for i := 0; i < 2; i++ { + for i := range 2 { n, _, rerr := rx.ReadFromUDPAddrPort(buf) if rerr != nil { t.Fatalf("expected 2 delivered packets, read #%d failed: %v", i+1, rerr) @@ -161,7 +161,7 @@ func TestWriteBatchUnreachableDestDeliversOthers(t *testing.T) { got := map[string]bool{} rx.SetReadDeadline(time.Now().Add(2 * time.Second)) buf := make([]byte, 64) - for i := 0; i < 4; i++ { + for i := range 4 { n, _, rerr := rx.ReadFromUDPAddrPort(buf) if rerr != nil { t.Fatalf("expected 4 delivered packets, read #%d failed: %v (got so far: %v)", i+1, rerr, got) @@ -691,7 +691,7 @@ func TestGSOEngagesOnLoopback(t *testing.T) { // The kernel must deliver the original datagram boundaries and bytes. _ = rx.SetReadDeadline(time.Now().Add(5 * time.Second)) got := make([]byte, pktLen+1) - for i := 0; i < numPkts; i++ { + for i := range numPkts { n, _, err := rx.ReadFromUDP(got) if err != nil { t.Fatalf("rx read %d: %v", i, err) @@ -699,7 +699,7 @@ func TestGSOEngagesOnLoopback(t *testing.T) { if n != pktLen { t.Fatalf("rx read %d: len=%d want %d (kernel segmented at wrong boundary)", i, n, pktLen) } - for j := 0; j < n; j++ { + for j := range n { if got[j] != byte(i) { t.Fatalf("rx read %d: byte %d = %#x, want %#x", i, j, got[j], byte(i)) } diff --git a/udp/udp_linux_writebatch.go b/udp/udp_linux_writebatch.go index d53f3fb9..bd846629 100644 --- a/udp/udp_linux_writebatch.go +++ b/udp/udp_linux_writebatch.go @@ -112,7 +112,7 @@ func (w *batchWriter) prepareWriteMessages(n int, offloadsEnabled bool) { w.cmsg = make([]byte, n*w.cmsgSpace) - for k := 0; k < n; k++ { + for k := range n { base := k * w.cmsgSpace seg := (*unix.Cmsghdr)(unsafe.Pointer(&w.cmsg[base])) seg.Level = unix.SOL_UDP @@ -214,7 +214,7 @@ func (w *batchWriter) WriteBatch(bufs [][]byte, addrs []netip.AddrPort) (int, er break } - for k := 0; k < runLen; k++ { + for k := range runLen { b := bufs[i+k] if len(b) == 0 { w.iovs[iovIdx+k].Base = nil @@ -318,10 +318,7 @@ func (w *batchWriter) planRun(bufs [][]byte, addrs []netip.AddrPort, start, iovB return 1, segSize } dst := addrs[start] - maxLen := w.maxGSOSegments - if iovBudget < maxLen { - maxLen = iovBudget - } + maxLen := min(iovBudget, w.maxGSOSegments) runLen := 1 total := segSize for runLen < maxLen && start+runLen < len(bufs) { diff --git a/udp/udp_linux_writebatch_alloc_test.go b/udp/udp_linux_writebatch_alloc_test.go index e1d96530..190fd90b 100644 --- a/udp/udp_linux_writebatch_alloc_test.go +++ b/udp/udp_linux_writebatch_alloc_test.go @@ -64,13 +64,13 @@ func TestWriteBatchNoAllocs(t *testing.T) { addrs = append(addrs, dst) } // GSO-eligible run with a short tail. - for k := 0; k < 8; k++ { + for range 8 { add(payload, dstA) } add(short, dstA) add(payload, dstA) // Alternating destinations defeat coalescing entirely. - for k := 0; k < 4; k++ { + for k := range 4 { dst := dstA if k%2 == 0 { dst = dstB diff --git a/udp/udp_netbsd.go b/udp/udp_netbsd.go index b45222eb..31c8ce3d 100644 --- a/udp/udp_netbsd.go +++ b/udp/udp_netbsd.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package udp diff --git a/udp/udp_rio_windows.go b/udp/udp_rio_windows.go index b04770af..a229b080 100644 --- a/udp/udp_rio_windows.go +++ b/udp/udp_rio_windows.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing // Inspired by https://git.zx2c4.com/wireguard-go/tree/conn/bind_windows.go diff --git a/udp/udp_tester.go b/udp/udp_tester.go index af6b09be..db90b370 100644 --- a/udp/udp_tester.go +++ b/udp/udp_tester.go @@ -1,5 +1,4 @@ //go:build e2e_testing -// +build e2e_testing package udp diff --git a/udp/udp_windows.go b/udp/udp_windows.go index 57c14b59..aecbb18b 100644 --- a/udp/udp_windows.go +++ b/udp/udp_windows.go @@ -1,5 +1,4 @@ //go:build !e2e_testing -// +build !e2e_testing package udp diff --git a/util/cpupin_linux.go b/util/cpupin_linux.go index d975b4af..e395ddca 100644 --- a/util/cpupin_linux.go +++ b/util/cpupin_linux.go @@ -40,7 +40,7 @@ func AllowedCPUs() ([]int, error) { return nil, err } cpus := make([]int, 0, set.Count()) - for cpu := 0; cpu < len(set)*64; cpu++ { + for cpu := range len(set) * 64 { if set.IsSet(cpu) { cpus = append(cpus, cpu) }