mirror of
https://github.com/juanfont/headscale.git
synced 2026-07-08 00:50:20 +09:00
derp: clone regions when merging DERP maps
In-place node shuffling aliased regions shared with the served map.
This commit is contained in:
committed by
Kristoffer Dalby
parent
0921972f96
commit
e413919810
@@ -6,7 +6,6 @@ import (
|
||||
"encoding/json"
|
||||
"hash/crc64"
|
||||
"io"
|
||||
"maps"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -85,7 +84,12 @@ func mergeDERPMaps(derpMaps []*tailcfg.DERPMap) *tailcfg.DERPMap {
|
||||
}
|
||||
|
||||
for _, derpMap := range derpMaps {
|
||||
maps.Copy(result.Regions, derpMap.Regions)
|
||||
// Clone each region: copying the pointer would let a later in-place
|
||||
// shuffle (shuffleRegionNoClone) alias regions shared with the source
|
||||
// map or a previously served map, racing concurrent readers.
|
||||
for id, region := range derpMap.Regions {
|
||||
result.Regions[id] = region.Clone()
|
||||
}
|
||||
}
|
||||
|
||||
for id, region := range result.Regions {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package derp
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"tailscale.com/tailcfg"
|
||||
)
|
||||
|
||||
// TestMergeDERPMapsClonesRegions ensures merged DERP maps own their regions
|
||||
// rather than aliasing the source pointers, so a later in-place node shuffle
|
||||
// cannot mutate a shared or previously served map.
|
||||
func TestMergeDERPMapsClonesRegions(t *testing.T) {
|
||||
src := &tailcfg.DERPMap{
|
||||
Regions: map[int]*tailcfg.DERPRegion{
|
||||
1: {RegionID: 1, Nodes: []*tailcfg.DERPNode{{Name: "a"}, {Name: "b"}}},
|
||||
},
|
||||
}
|
||||
|
||||
merged := mergeDERPMaps([]*tailcfg.DERPMap{src})
|
||||
|
||||
assert.NotSame(t, src.Regions[1], merged.Regions[1],
|
||||
"merged region must not alias the source region pointer")
|
||||
|
||||
merged.Regions[1].Nodes[0] = &tailcfg.DERPNode{Name: "mutated"}
|
||||
assert.Equal(t, "a", src.Regions[1].Nodes[0].Name,
|
||||
"source region was mutated through a shared pointer")
|
||||
}
|
||||
Reference in New Issue
Block a user