From 844d991baf3c03807cbd5beea5af146b6d2a245a Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 2 Mar 2020 15:02:34 -0800 Subject: [PATCH] netcheck: add Report.Clone, return cloned report to avoid races on late replies --- netcheck/netcheck.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/netcheck/netcheck.go b/netcheck/netcheck.go index b8d416f39..f0bfdef9b 100644 --- a/netcheck/netcheck.go +++ b/netcheck/netcheck.go @@ -28,6 +28,22 @@ type Report struct { MappingVariesByDestIP opt.Bool // for IPv4 HairPinning opt.Bool // for IPv4 DERPLatency map[string]time.Duration // keyed by STUN host:port + + // TODO: update Clone when adding new fields +} + +func (r *Report) Clone() *Report { + if r == nil { + return nil + } + r2 := *r + if r2.DERPLatency != nil { + r2.DERPLatency = map[string]time.Duration{} + for k, v := range r.DERPLatency { + r2.DERPLatency[k] = v + } + } + return &r2 } func GetReport(ctx context.Context, logf logger.Logf) (*Report, error) { @@ -159,7 +175,7 @@ func GetReport(ctx context.Context, logf logger.Logf) (*Report, error) { } mu.Lock() - defer mu.Unlock() // unnecessary, but feels weird without + defer mu.Unlock() var checkHairpinning bool @@ -186,5 +202,5 @@ func GetReport(ctx context.Context, logf logger.Logf) (*Report, error) { } } - return ret, nil + return ret.Clone(), nil }