From 6be05e85f6da70cfd14f288b864695613d5b2b69 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 10 Apr 2022 18:30:13 +0100 Subject: [PATCH] fix race condition in AutoRelay candidate handling --- p2p/host/autorelay/relay_finder.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/p2p/host/autorelay/relay_finder.go b/p2p/host/autorelay/relay_finder.go index f803fcf7c9..bd51509410 100644 --- a/p2p/host/autorelay/relay_finder.go +++ b/p2p/host/autorelay/relay_finder.go @@ -281,12 +281,16 @@ func (rf *relayFinder) tryNode(ctx context.Context, pi peer.AddrInfo) (supportsR func (rf *relayFinder) handleNewCandidate(ctx context.Context) { rf.relayMx.Lock() - defer rf.relayMx.Unlock() - if len(rf.candidates) == 0 { + numRelays := len(rf.relays) + rf.relayMx.Unlock() + // We're already connected to our desired number of relays. Nothing to do here. + if numRelays == rf.conf.desiredRelays { return } - // We're already connected to our desired number of relays. Nothing to do here. - if len(rf.relays) == rf.conf.desiredRelays { + + rf.candidateMx.Lock() + defer rf.candidateMx.Unlock() + if len(rf.candidates) == 0 { return } @@ -468,12 +472,10 @@ func (rf *relayFinder) usingRelay(p peer.ID) bool { // selectCandidates returns an ordered slice of relay candidates. // Callers should attempt to obtain reservations with the candidates in this order. func (rf *relayFinder) selectCandidates() []*candidate { - rf.candidateMx.Lock() var candidates []*candidate for _, cand := range rf.candidates { candidates = append(candidates, cand) } - rf.candidateMx.Unlock() // TODO: better relay selection strategy; this just selects random relays, // but we should probably use ping latency as the selection metric @@ -541,7 +543,9 @@ func (rf *relayFinder) Start() error { func (rf *relayFinder) Stop() error { log.Debug("stopping relay finder") - rf.ctxCancel() + if rf.ctxCancel != nil { + rf.ctxCancel() + } rf.refCount.Wait() rf.ctxCancel = nil return nil