Skip to content

Commit 0084573

Browse files
committed
chore: add setDERPMap to configMaps
1 parent dc740ac commit 0084573

File tree

3 files changed

+116
-3
lines changed

3 files changed

+116
-3
lines changed

tailnet/configmaps.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,24 @@ func (c *configMaps) setBlockEndpoints(blockEndpoints bool) {
253253
c.Broadcast()
254254
}
255255

256+
// setDERPMap sets the DERP map, triggering a configuration of the engine if it has changed.
257+
// c.L MUST NOT be held.
258+
func (c *configMaps) setDERPMap(derpMap *proto.DERPMap) {
259+
c.L.Lock()
260+
defer c.L.Unlock()
261+
eq, err := c.derpMap.Equal(derpMap)
262+
if err != nil {
263+
c.logger.Critical(context.Background(), "failed to compare DERP maps", slog.Error(err))
264+
return
265+
}
266+
if eq {
267+
return
268+
}
269+
c.derpMap = derpMap
270+
c.derpMapDirty = true
271+
c.Broadcast()
272+
}
273+
256274
// derMapLocked returns the current DERPMap. c.L must be held
257275
func (c *configMaps) derpMapLocked() *tailcfg.DERPMap {
258276
m := DERPMapFromProto(c.derpMap)

tailnet/configmaps_internal_test.go

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,88 @@ func TestConfigMaps_setBlockEndpoints_same(t *testing.T) {
571571
_ = testutil.RequireRecvCtx(ctx, t, done)
572572
}
573573

574+
func TestConfigMaps_setDERPMap_different(t *testing.T) {
575+
t.Parallel()
576+
ctx := testutil.Context(t, testutil.WaitShort)
577+
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
578+
fEng := newFakeEngineConfigurable()
579+
nodePrivateKey := key.NewNode()
580+
nodeID := tailcfg.NodeID(5)
581+
discoKey := key.NewDisco()
582+
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), nil)
583+
defer uut.close()
584+
585+
derpMap := &proto.DERPMap{
586+
HomeParams: &proto.DERPMap_HomeParams{RegionScore: map[int64]float64{1: 0.025}},
587+
Regions: map[int64]*proto.DERPMap_Region{
588+
1: {
589+
RegionCode: "AUH",
590+
Nodes: []*proto.DERPMap_Region_Node{
591+
{Name: "AUH0"},
592+
},
593+
},
594+
},
595+
}
596+
uut.setDERPMap(derpMap)
597+
598+
dm := testutil.RequireRecvCtx(ctx, t, fEng.setDERPMap)
599+
require.Len(t, dm.HomeParams.RegionScore, 1)
600+
require.Equal(t, dm.HomeParams.RegionScore[1], 0.025)
601+
require.Len(t, dm.Regions, 1)
602+
r1 := dm.Regions[1]
603+
require.Equal(t, "AUH", r1.RegionCode)
604+
require.Len(t, r1.Nodes, 1)
605+
require.Equal(t, "AUH0", r1.Nodes[0].Name)
606+
607+
done := make(chan struct{})
608+
go func() {
609+
defer close(done)
610+
uut.close()
611+
}()
612+
_ = testutil.RequireRecvCtx(ctx, t, done)
613+
}
614+
615+
func TestConfigMaps_setDERPMap_same(t *testing.T) {
616+
t.Parallel()
617+
ctx := testutil.Context(t, testutil.WaitShort)
618+
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
619+
fEng := newFakeEngineConfigurable()
620+
nodePrivateKey := key.NewNode()
621+
nodeID := tailcfg.NodeID(5)
622+
discoKey := key.NewDisco()
623+
uut := newConfigMaps(logger, fEng, nodeID, nodePrivateKey, discoKey.Public(), nil)
624+
defer uut.close()
625+
626+
// Given: DERP Map already set
627+
derpMap := &proto.DERPMap{
628+
HomeParams: &proto.DERPMap_HomeParams{RegionScore: map[int64]float64{1: 0.025}},
629+
Regions: map[int64]*proto.DERPMap_Region{
630+
1: {
631+
RegionCode: "AUH",
632+
Nodes: []*proto.DERPMap_Region_Node{
633+
{Name: "AUH0"},
634+
},
635+
},
636+
},
637+
}
638+
uut.L.Lock()
639+
uut.derpMap = derpMap
640+
uut.L.Unlock()
641+
642+
// Then: we don't configure
643+
requireNeverConfigures(ctx, t, &uut.phased)
644+
645+
// When we set the same DERP map
646+
uut.setDERPMap(derpMap)
647+
648+
done := make(chan struct{})
649+
go func() {
650+
defer close(done)
651+
uut.close()
652+
}()
653+
_ = testutil.RequireRecvCtx(ctx, t, done)
654+
}
655+
574656
func expectStatusWithHandshake(
575657
ctx context.Context, t testing.TB, fEng *fakeEngineConfigurable, k key.NodePublic, lastHandshake time.Time,
576658
) <-chan struct{} {
@@ -696,6 +778,7 @@ type fakeEngineConfigurable struct {
696778
setNetworkMap chan *netmap.NetworkMap
697779
reconfig chan reconfigCall
698780
filter chan *filter.Filter
781+
setDERPMap chan *tailcfg.DERPMap
699782

700783
// To fake these fields the test should read from status, do stuff to the
701784
// StatusBuilder, then write to statusDone
@@ -713,6 +796,7 @@ func newFakeEngineConfigurable() *fakeEngineConfigurable {
713796
setNetworkMap: make(chan *netmap.NetworkMap),
714797
reconfig: make(chan reconfigCall),
715798
filter: make(chan *filter.Filter),
799+
setDERPMap: make(chan *tailcfg.DERPMap),
716800
status: make(chan *ipnstate.StatusBuilder),
717801
statusDone: make(chan struct{}),
718802
}
@@ -727,9 +811,8 @@ func (f fakeEngineConfigurable) Reconfig(wg *wgcfg.Config, r *router.Config, _ *
727811
return nil
728812
}
729813

730-
func (fakeEngineConfigurable) SetDERPMap(*tailcfg.DERPMap) {
731-
// TODO implement me
732-
panic("implement me")
814+
func (f fakeEngineConfigurable) SetDERPMap(d *tailcfg.DERPMap) {
815+
f.setDERPMap <- d
733816
}
734817

735818
func (f fakeEngineConfigurable) SetFilter(flt *filter.Filter) {

tailnet/proto/compare.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,15 @@ func (s *Node) Equal(o *Node) (bool, error) {
1818
}
1919
return bytes.Equal(sBytes, oBytes), nil
2020
}
21+
22+
func (s *DERPMap) Equal(o *DERPMap) (bool, error) {
23+
sBytes, err := gProto.Marshal(s)
24+
if err != nil {
25+
return false, err
26+
}
27+
oBytes, err := gProto.Marshal(o)
28+
if err != nil {
29+
return false, err
30+
}
31+
return bytes.Equal(sBytes, oBytes), nil
32+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy