mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 19:15:34 +00:00
net/netcheck: fix race condition initializting RegionLatency maps.
Under some conditions, code would try to look things up in the maps before the first call to updateLatency. I don't see any reason to delay initialization of the maps, so let's just init them right away when creating the Report instance. Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
This commit is contained in:
parent
5eb09c8f5e
commit
7cd9ff3dde
@ -518,17 +518,17 @@ func (rs *reportState) addNodeLatency(node *tailcfg.DERPNode, ipp netaddr.IPPort
|
||||
ret := rs.report
|
||||
|
||||
ret.UDP = true
|
||||
updateLatency(&ret.RegionLatency, node.RegionID, d)
|
||||
updateLatency(ret.RegionLatency, node.RegionID, d)
|
||||
|
||||
switch {
|
||||
case ipp.IP.Is6():
|
||||
updateLatency(&ret.RegionV6Latency, node.RegionID, d)
|
||||
updateLatency(ret.RegionV6Latency, node.RegionID, d)
|
||||
ret.IPv6 = true
|
||||
ret.GlobalV6 = ipPortStr
|
||||
// TODO: track MappingVariesByDestIP for IPv6
|
||||
// too? Would be sad if so, but who knows.
|
||||
case ipp.IP.Is4():
|
||||
updateLatency(&ret.RegionV4Latency, node.RegionID, d)
|
||||
updateLatency(ret.RegionV4Latency, node.RegionID, d)
|
||||
if rs.gotEP4 == "" {
|
||||
rs.gotEP4 = ipPortStr
|
||||
ret.GlobalV4 = ipPortStr
|
||||
@ -543,6 +543,14 @@ func (rs *reportState) addNodeLatency(node *tailcfg.DERPNode, ipp netaddr.IPPort
|
||||
}
|
||||
}
|
||||
|
||||
func newReport() *Report {
|
||||
return &Report{
|
||||
RegionLatency: make(map[int]time.Duration),
|
||||
RegionV4Latency: make(map[int]time.Duration),
|
||||
RegionV6Latency: make(map[int]time.Duration),
|
||||
}
|
||||
}
|
||||
|
||||
// GetReport gets a report.
|
||||
//
|
||||
// It may not be called concurrently with itself.
|
||||
@ -564,7 +572,7 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap) (*Report, e
|
||||
}
|
||||
rs := &reportState{
|
||||
c: c,
|
||||
report: new(Report),
|
||||
report: newReport(),
|
||||
inFlight: map[stun.TxID]func(netaddr.IPPort){},
|
||||
hairTX: stun.NewTxID(), // random payload
|
||||
gotHairSTUN: make(chan *net.UDPAddr, 1),
|
||||
@ -806,11 +814,7 @@ func (c *Client) addReportHistoryAndSetPreferredDERP(r *Report) {
|
||||
}
|
||||
}
|
||||
|
||||
func updateLatency(mp *map[int]time.Duration, regionID int, d time.Duration) {
|
||||
if *mp == nil {
|
||||
*mp = make(map[int]time.Duration)
|
||||
}
|
||||
m := *mp
|
||||
func updateLatency(m map[int]time.Duration, regionID int, d time.Duration) {
|
||||
if prev, ok := m[regionID]; !ok || d < prev {
|
||||
m[regionID] = d
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ func TestWorksWhenUDPBlocked(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := new(Report)
|
||||
want := newReport()
|
||||
|
||||
if !reflect.DeepEqual(r, want) {
|
||||
t.Errorf("mismatch\n got: %+v\nwant: %+v\n", r, want)
|
||||
|
Loading…
Reference in New Issue
Block a user