mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-12 05:37:32 +00:00
util/slicesx: add package for generic slice functions, use
Now that we're using rand.Shuffle in a few locations, create a generic shuffle function and use it instead. While we're at it, move the interleaveSlices function to the same package for use. Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I0b00920e5b3eea846b6cedc30bd34d978a049fd3
This commit is contained in:
@@ -24,6 +24,7 @@ import (
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/cloudenv"
|
||||
"tailscale.com/util/singleflight"
|
||||
"tailscale.com/util/slicesx"
|
||||
)
|
||||
|
||||
var zaddr netip.Addr
|
||||
@@ -577,7 +578,7 @@ func (dc *dialCall) raceDial(ctx context.Context, ips []netip.Addr) (net.Conn, e
|
||||
iv4 = append(iv4, ip)
|
||||
}
|
||||
}
|
||||
ips = interleaveSlices(iv6, iv4)
|
||||
ips = slicesx.Interleave(iv6, iv4)
|
||||
|
||||
go func() {
|
||||
for i, ip := range ips {
|
||||
@@ -636,21 +637,6 @@ func (dc *dialCall) raceDial(ctx context.Context, ips []netip.Addr) (net.Conn, e
|
||||
}
|
||||
}
|
||||
|
||||
// interleaveSlices combines two slices of the form [a, b, c] and [x, y, z]
|
||||
// into a slice with elements interleaved; i.e. [a, x, b, y, c, z].
|
||||
func interleaveSlices[T any](a, b []T) []T {
|
||||
var (
|
||||
i int
|
||||
ret = make([]T, 0, len(a)+len(b))
|
||||
)
|
||||
for i = 0; i < len(a) && i < len(b); i++ {
|
||||
ret = append(ret, a[i], b[i])
|
||||
}
|
||||
ret = append(ret, a[i:]...)
|
||||
ret = append(ret, b[i:]...)
|
||||
return ret
|
||||
}
|
||||
|
||||
func v4addrs(aa []netip.Addr) (ret []netip.Addr) {
|
||||
for _, a := range aa {
|
||||
a = a.Unmap()
|
||||
|
@@ -141,30 +141,6 @@ func TestResolverAllHostStaticResult(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterleaveSlices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
a, b []int
|
||||
want []int
|
||||
}{
|
||||
{name: "equal", a: []int{1, 3, 5}, b: []int{2, 4, 6}, want: []int{1, 2, 3, 4, 5, 6}},
|
||||
{name: "short_b", a: []int{1, 3, 5}, b: []int{2, 4}, want: []int{1, 2, 3, 4, 5}},
|
||||
{name: "short_a", a: []int{1, 3}, b: []int{2, 4, 6}, want: []int{1, 2, 3, 4, 6}},
|
||||
{name: "len_1", a: []int{1}, b: []int{2, 4, 6}, want: []int{1, 2, 4, 6}},
|
||||
{name: "nil_a", a: nil, b: []int{2, 4, 6}, want: []int{2, 4, 6}},
|
||||
{name: "nil_all", a: nil, b: nil, want: []int{}},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
merged := interleaveSlices(tc.a, tc.b)
|
||||
if !reflect.DeepEqual(merged, tc.want) {
|
||||
t.Errorf("got %v; want %v", merged, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldTryBootstrap(t *testing.T) {
|
||||
oldDebug := debug
|
||||
t.Cleanup(func() { debug = oldDebug })
|
||||
|
@@ -14,7 +14,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
@@ -31,6 +30,7 @@ import (
|
||||
"tailscale.com/syncs"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/slicesx"
|
||||
)
|
||||
|
||||
func Lookup(ctx context.Context, host string) ([]netip.Addr, error) {
|
||||
@@ -56,8 +56,8 @@ func Lookup(ctx context.Context, host string) ([]netip.Addr, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
rand.Shuffle(len(cands4), func(i, j int) { cands4[i], cands4[j] = cands4[j], cands4[i] })
|
||||
rand.Shuffle(len(cands6), func(i, j int) { cands6[i], cands6[j] = cands6[j], cands6[i] })
|
||||
slicesx.Shuffle(cands4)
|
||||
slicesx.Shuffle(cands6)
|
||||
|
||||
const maxCands = 6
|
||||
var cands []nameIP // up to maxCands alternating v4/v6 as long as we have both
|
||||
@@ -87,7 +87,7 @@ func Lookup(ctx context.Context, host string) ([]netip.Addr, error) {
|
||||
continue
|
||||
}
|
||||
if ips := dm[host]; len(ips) > 0 {
|
||||
rand.Shuffle(len(ips), func(i, j int) { ips[i], ips[j] = ips[j], ips[i] })
|
||||
slicesx.Shuffle(ips)
|
||||
logf("bootstrapDNS(%q, %q) for %q = %v", cand.dnsName, cand.ip, host, ips)
|
||||
return ips, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user