wgengine/magicsock,ipn/ipnlocal: store and load homeDERP from cache (#19491)
With netmap caching, the home DERP of the self node was neither saved to
the cache or loaded from it, making nodes not stick to a DERP when
starting without a connection to control.
Instead, make sure that when a cache is available, load that cache,
before looking for DERP servers. This is implemented by allowing a skip
of ReSTUN in setting the DERP map (we must have a DERP map before
setting the home DERP), so the DERP from cache will set itself and be
sticky until a connection to control is established.
Making DERP only change when connected to control is handled by existing
code from f072d017bd.
Updates #19490
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This commit is contained in:
@@ -203,7 +203,7 @@ func newMagicStackWithKey(t testing.TB, logf logger.Logf, ln nettype.PacketListe
|
||||
if err != nil {
|
||||
t.Fatalf("constructing magicsock: %v", err)
|
||||
}
|
||||
conn.SetDERPMap(derpMap)
|
||||
conn.SetDERPMap(derpMap, true)
|
||||
if err := conn.SetPrivateKey(privateKey); err != nil {
|
||||
t.Fatalf("setting private key in magicsock: %v", err)
|
||||
}
|
||||
@@ -435,7 +435,7 @@ func TestNewConn(t *testing.T) {
|
||||
t.Fatal("LocalPort returned 0")
|
||||
}
|
||||
|
||||
conn.SetDERPMap(stuntest.DERPMapOf(stunAddr.String()))
|
||||
conn.SetDERPMap(stuntest.DERPMapOf(stunAddr.String()), true)
|
||||
conn.SetPrivateKey(key.NewNode())
|
||||
|
||||
go func() {
|
||||
@@ -567,7 +567,7 @@ func TestDERPActiveFuncCalledAfterConnect(t *testing.T) {
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
conn.SetDERPMap(derpMap)
|
||||
conn.SetDERPMap(derpMap, true)
|
||||
if err := conn.SetPrivateKey(key.NewNode()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -3080,6 +3080,7 @@ func TestMaybeSetNearestDERP(t *testing.T) {
|
||||
old int
|
||||
reportDERP int
|
||||
connectedToControl bool
|
||||
force bool
|
||||
want int
|
||||
}{
|
||||
{
|
||||
@@ -3103,6 +3104,22 @@ func TestMaybeSetNearestDERP(t *testing.T) {
|
||||
connectedToControl: false, // not connected...
|
||||
want: 21, // ... but want to change to new DERP
|
||||
},
|
||||
{
|
||||
name: "force_not_connected_with_report_derp",
|
||||
old: 1,
|
||||
reportDERP: 21,
|
||||
connectedToControl: false,
|
||||
force: true,
|
||||
want: 21, // force bypasses the no-change-without-control guard
|
||||
},
|
||||
{
|
||||
name: "force_not_connected_no_derp_no_current",
|
||||
old: 0,
|
||||
reportDERP: 0,
|
||||
connectedToControl: false,
|
||||
force: true,
|
||||
want: 31, // force + no report DERP → deterministic fallback
|
||||
},
|
||||
{
|
||||
name: "not_connected_with_fallback_and_no_current",
|
||||
old: 0, // no current DERP
|
||||
@@ -3127,8 +3144,13 @@ func TestMaybeSetNearestDERP(t *testing.T) {
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ht := health.NewTracker(eventbustest.NewBus(t))
|
||||
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.myDerp = tt.old
|
||||
c.derpMap = derpMap
|
||||
c.health = ht
|
||||
@@ -3146,7 +3168,7 @@ func TestMaybeSetNearestDERP(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
got := c.maybeSetNearestDERP(report)
|
||||
got := c.maybeSetNearestDERP(report, tt.force)
|
||||
if got != tt.want {
|
||||
t.Errorf("got new DERP region %d, want %d", got, tt.want)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user