mirror of
https://github.com/tailscale/tailscale.git
synced 2026-09-23 12:05:15 -04:00
Historically, when DERP regions were switched away from strings to numeric identifiers in PR #14641, tailcfg.Node.HomeDERP was declared as an int instead of its own type. This PR declares a new tailcfg.DERPRegionID type, represented by an int64, and converts the following fields to use this type: - netcheck.Report.PreferredDERP - netcheck.Report.RegionLatency - netcheck.Report.RegionV4Latency - netcheck.Report.RegionV6Latency - tailcfg.DERPHomeParams.RegionScore - tailcfg.DERPMap.Regions - tailcfg.DERPNode.RegionID - tailcfg.DERPRegion.RegionID - tailcfg.NetInfo.PreferredDERP - tailcfg.Node.HomeDERP - tailcfg.PeerChange.DERPRegion - tailcfg.PingResponse.DERPRegionID Note that the original field was an int, while the new field is backed by an int64. This change makes DERPRegionID the same size on both 32-bit and 64-bit architectures. Fixes: #20165 Change-Id: Ic6f795a6d791dd16f756f246d5a02085443e212f Signed-off-by: Simon Law <sfllaw@tailscale.com>
133 lines
3.4 KiB
Go
133 lines
3.4 KiB
Go
// Copyright (c) Tailscale Inc & contributors
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package magicsock
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"tailscale.com/health"
|
|
"tailscale.com/net/netcheck"
|
|
"tailscale.com/tailcfg"
|
|
"tailscale.com/tstest"
|
|
"tailscale.com/util/eventbus"
|
|
"tailscale.com/util/eventbus/eventbustest"
|
|
)
|
|
|
|
func CheckDERPHeuristicTimes(t *testing.T) {
|
|
if netcheck.PreferredDERPFrameTime <= frameReceiveRecordRate {
|
|
t.Errorf("PreferredDERPFrameTime too low; should be at least frameReceiveRecordRate")
|
|
}
|
|
}
|
|
|
|
func TestForceSetNearestDERP(t *testing.T) {
|
|
derpMap := &tailcfg.DERPMap{
|
|
Regions: map[tailcfg.DERPRegionID]*tailcfg.DERPRegion{
|
|
7: {
|
|
RegionID: 7,
|
|
RegionCode: "test",
|
|
Nodes: []*tailcfg.DERPNode{
|
|
{
|
|
Name: "7a",
|
|
RegionID: 7,
|
|
HostName: "derp7.test.unused",
|
|
IPv4: "127.0.0.1",
|
|
IPv6: "none",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
// Force the real control health check so we can verify force=true bypasses it.
|
|
tstest.Replace(t, &checkControlHealthDuringNearestDERPInTests, true)
|
|
|
|
bus := eventbustest.NewBus(t)
|
|
ht := health.NewTracker(bus)
|
|
c := newConn(t.Logf)
|
|
ec := bus.Client("magicsock.Conn.Test")
|
|
c.eventClient = ec
|
|
c.homeDERPChangedPub = eventbus.Publish[HomeDERPChanged](ec)
|
|
c.eventBus = bus
|
|
c.derpMap = derpMap
|
|
c.health = ht
|
|
|
|
ht.SetOutOfPollNetMap()
|
|
|
|
tw := eventbustest.NewWatcher(t, bus)
|
|
|
|
got := c.ForceSetNearestDERP(7)
|
|
if got != 7 {
|
|
t.Fatalf("ForceSetNearestDERP(7) = %d, want 7", got)
|
|
}
|
|
if c.myDerp != 7 {
|
|
t.Errorf("c.myDerp = %d after ForceSetNearestDERP, want 7", c.myDerp)
|
|
}
|
|
|
|
if err := eventbustest.Expect(tw, func(e HomeDERPChanged) error {
|
|
if e.Old != 0 || e.New != 7 {
|
|
return fmt.Errorf("got HomeDERPChanged{Old:%d, New:%d}, want {Old:0, New:7}", e.Old, e.New)
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
t.Errorf("expected HomeDERPChanged event: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestSetDERPMapDoReStun(t *testing.T) {
|
|
derpMap1 := &tailcfg.DERPMap{
|
|
Regions: map[tailcfg.DERPRegionID]*tailcfg.DERPRegion{
|
|
1: {
|
|
RegionID: 1,
|
|
RegionCode: "cph",
|
|
Nodes: []*tailcfg.DERPNode{
|
|
{Name: "1a", RegionID: 1, HostName: "cph.test.unused", IPv4: "127.0.0.1", IPv6: "none"},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
derpMap2 := &tailcfg.DERPMap{
|
|
Regions: map[tailcfg.DERPRegionID]*tailcfg.DERPRegion{
|
|
2: {
|
|
RegionID: 2,
|
|
RegionCode: "inc",
|
|
Nodes: []*tailcfg.DERPNode{
|
|
{Name: "2a", RegionID: 2, HostName: "inc.test.unused", IPv4: "127.0.0.1", IPv6: "none"},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
var reSTUNCalls int
|
|
tstest.Replace(t, &reSTUNHookForTests, func(_ string) {
|
|
reSTUNCalls++
|
|
})
|
|
|
|
bus := eventbustest.NewBus(t)
|
|
ht := health.NewTracker(bus)
|
|
// Use WhileTestRunningLogger so the goroutine spawned by setDERPMap
|
|
// (which calls ReSTUN, which logs) doesn't race with test cleanup.
|
|
c := newConn(tstest.WhileTestRunningLogger(t))
|
|
ec := bus.Client("magicsock.Conn.Test")
|
|
c.eventClient = ec
|
|
c.homeDERPChangedPub = eventbus.Publish[HomeDERPChanged](ec)
|
|
c.eventBus = bus
|
|
c.health = ht
|
|
// With a zero private key and everHadKey=true, ReSTUN returns early without
|
|
// spawning updateEndpoints.
|
|
c.everHadKey = true
|
|
|
|
// SetDERPMapWithoutReSTUN should not trigger a ReSTUN.
|
|
c.SetDERPMapWithoutReSTUN(derpMap1)
|
|
if reSTUNCalls != 0 {
|
|
t.Errorf("SetDERPMapWithoutReSTUN: got %d ReSTUN calls, want 0", reSTUNCalls)
|
|
}
|
|
|
|
// SetDERPMap should trigger a ReSTUN.
|
|
c.SetDERPMap(derpMap2)
|
|
if reSTUNCalls != 1 {
|
|
t.Errorf("SetDERPMap: got %d ReSTUN calls, want 1", reSTUNCalls)
|
|
}
|
|
}
|