diff --git a/agent.go b/agent.go index a268382..d30281f 100644 --- a/agent.go +++ b/agent.go @@ -41,10 +41,10 @@ type Agent struct { afterRunFn []func(ctx context.Context) muAfterRun sync.Mutex - onConnectionStateChangeHdlr atomic.Value // func(ConnectionState) - onSelectedCandidatePairChangeHdlr atomic.Value // func(Candidate, Candidate) - onCandidateHdlr atomic.Value // func(Candidate) - onSuccessfulBindingResponseHdlr atomic.Value // func(Candidate) + onConnectionStateChangeHdlr atomic.Value // func(ConnectionState) + onSelectedCandidatePairChangeHdlr atomic.Value // func(Candidate, Candidate) + onCandidateHdlr atomic.Value // func(Candidate) + onSuccessfulSelectedPairBindingResponseHdlr atomic.Value // func(*Candidate) // State owned by the taskLoop onConnected chan struct{} diff --git a/agent_handlers.go b/agent_handlers.go index 427b438..7ceb6e7 100644 --- a/agent_handlers.go +++ b/agent_handlers.go @@ -23,9 +23,9 @@ func (a *Agent) OnCandidate(f func(Candidate)) error { return nil } -// OnSuccessfulBindingResponse sets a handler that is fired when a successful binding response is received -func (a *Agent) OnSuccessfulBindingResponse(f func(*CandidatePair)) error { - a.onSuccessfulBindingResponseHdlr.Store(f) +// OnSuccessfulSelectedPairBindingResponse sets a handler that is fired when a successful binding response is received for the selected candidate pair +func (a *Agent) OnSuccessfulSelectedPairBindingResponse(f func(*CandidatePair)) error { + a.onSuccessfulSelectedPairBindingResponseHdlr.Store(f) return nil } @@ -47,8 +47,8 @@ func (a *Agent) onConnectionStateChange(s ConnectionState) { } } -func (a *Agent) onSuccessfulBindingResponse(p *CandidatePair) { - if h, ok := a.onSuccessfulBindingResponseHdlr.Load().(func(*CandidatePair)); ok { +func (a *Agent) onSuccessfulSelectedPairBindingResponse(p *CandidatePair) { + if h, ok := a.onSuccessfulSelectedPairBindingResponseHdlr.Load().(func(*CandidatePair)); ok { h(p) } } diff --git a/candidatepair.go b/candidatepair.go index 4ebd56c..fd36366 100644 --- a/candidatepair.go +++ b/candidatepair.go @@ -110,12 +110,13 @@ func (p *CandidatePair) markBindingRequest(transactionID [12]byte) { p.lastBindingTransactionID = transactionID } -func (p *CandidatePair) markBindingResponse(transactionID [12]byte) { +func (p *CandidatePair) markBindingResponse(transactionID [12]byte) bool { if p.lastBindingRequest.IsZero() || transactionID != p.lastBindingTransactionID { - return + return false } p.latency = time.Since(p.lastBindingRequest) + return true } func (p *CandidatePair) Latency() time.Duration { diff --git a/selection.go b/selection.go index 53b4b36..bfbd5a9 100644 --- a/selection.go +++ b/selection.go @@ -139,14 +139,16 @@ func (s *controllingSelector) HandleSuccessResponse(m *stun.Message, local, remo return } - p.markBindingResponse(m.TransactionID) - s.agent.onSuccessfulBindingResponse(p) - p.state = CandidatePairStateSucceeded s.log.Tracef("Found valid candidate pair: %s", p) if pendingRequest.isUseCandidate && s.agent.getSelectedPair() == nil { s.agent.setSelectedPair(p) } + + ok = p.markBindingResponse(m.TransactionID) + if ok && s.agent.getSelectedPair() == p { + s.agent.onSuccessfulSelectedPairBindingResponse(p) + } } func (s *controllingSelector) PingCandidate(local, remote Candidate) { @@ -233,8 +235,10 @@ func (s *controlledSelector) HandleSuccessResponse(m *stun.Message, local, remot return } - p.markBindingResponse(m.TransactionID) - s.agent.onSuccessfulBindingResponse(p) + ok = p.markBindingResponse(m.TransactionID) + if ok { + s.agent.onSuccessfulSelectedPairBindingResponse(p) + } p.state = CandidatePairStateSucceeded s.log.Tracef("Found valid candidate pair: %s", p)