@@ -120,8 +120,9 @@ type Conn struct {
120
120
localSessionDescriptionChannel chan webrtc.SessionDescription
121
121
remoteSessionDescriptionChannel chan webrtc.SessionDescription
122
122
123
- pendingCandidates []webrtc.ICECandidateInit
124
- pendingCandidatesMutex sync.Mutex
123
+ pendingCandidates []webrtc.ICECandidateInit
124
+ pendingCandidatesMutex sync.Mutex
125
+ pendingCandidatesFlushed bool
125
126
126
127
pingChannelID uint16
127
128
pingEchoChannelID uint16
@@ -144,7 +145,7 @@ func (c *Conn) init() error {
144
145
c .pendingCandidatesMutex .Lock ()
145
146
defer c .pendingCandidatesMutex .Unlock ()
146
147
147
- if c . rtc . RemoteDescription () == nil {
148
+ if ! c . pendingCandidatesFlushed {
148
149
c .opts .Logger .Debug (context .Background (), "adding local candidate to buffer" )
149
150
c .pendingCandidates = append (c .pendingCandidates , iceCandidate .ToJSON ())
150
151
return
@@ -280,8 +281,6 @@ func (c *Conn) negotiate() {
280
281
case remoteDescription = <- c .remoteSessionDescriptionChannel :
281
282
}
282
283
283
- // Must lock new candidates from being sent while the description is being flushed.
284
- c .pendingCandidatesMutex .Lock ()
285
284
err := c .rtc .SetRemoteDescription (remoteDescription )
286
285
if err != nil {
287
286
c .pendingCandidatesMutex .Unlock ()
@@ -294,13 +293,8 @@ func (c *Conn) negotiate() {
294
293
// time. If candidates flush before this point, a connection could fail.
295
294
c .flushPendingCandidates ()
296
295
}
297
- c .pendingCandidatesMutex .Unlock ()
298
296
299
297
if ! c .offerrer {
300
- // Lock new candidates from processing until we set the local description.
301
- c .pendingCandidatesMutex .Lock ()
302
- defer c .pendingCandidatesMutex .Unlock ()
303
-
304
298
answer , err := c .rtc .CreateAnswer (& webrtc.AnswerOptions {})
305
299
if err != nil {
306
300
_ = c .CloseWithError (xerrors .Errorf ("create answer: %w" , err ))
@@ -328,15 +322,18 @@ func (c *Conn) negotiate() {
328
322
// flushPendingCandidates writes all local candidates to the candidate send channel.
329
323
// The localCandidateChannel is expected to be serviced, otherwise this could block.
330
324
func (c * Conn ) flushPendingCandidates () {
331
- for _ , localCandidate := range c .pendingCandidates {
325
+ c .pendingCandidatesMutex .Lock ()
326
+ defer c .pendingCandidatesMutex .Unlock ()
327
+ for _ , pendingCandidate := range c .pendingCandidates {
332
328
c .opts .Logger .Debug (context .Background (), "flushing local candidate" )
333
329
select {
334
330
case <- c .closed :
335
331
return
336
- case c .localCandidateChannel <- localCandidate :
332
+ case c .localCandidateChannel <- pendingCandidate :
337
333
}
338
334
}
339
335
c .pendingCandidates = make ([]webrtc.ICECandidateInit , 0 )
336
+ c .pendingCandidatesFlushed = true
340
337
c .opts .Logger .Debug (context .Background (), "flushed candidates" )
341
338
}
342
339
0 commit comments