@@ -79,7 +79,7 @@ func newWithClientOrServer(servers []webrtc.ICEServer, client bool, opts *ConnOp
79
79
// This channel needs to be bufferred otherwise slow consumers
80
80
// of this will cause a connection failure.
81
81
localNegotiator : make (chan Negotiation , 8 ),
82
- remoteSessionDescription : make (chan webrtc.SessionDescription , 1 ),
82
+ remoteSessionDescription : make (chan webrtc.SessionDescription ),
83
83
pendingCandidatesToSend : make ([]webrtc.ICECandidateInit , 0 ),
84
84
}
85
85
if client {
@@ -124,8 +124,9 @@ type Conn struct {
124
124
dcFailedListeners atomic.Uint32
125
125
dcClosedWaitGroup sync.WaitGroup
126
126
127
- localNegotiator chan Negotiation
128
- remoteSessionDescription chan webrtc.SessionDescription
127
+ localNegotiator chan Negotiation
128
+ remoteSessionDescription chan webrtc.SessionDescription
129
+ remoteSessionDescriptionMutex sync.Mutex
129
130
130
131
pendingCandidatesToSend []webrtc.ICECandidateInit
131
132
pendingCandidatesToSendMutex sync.Mutex
@@ -329,9 +330,6 @@ func (c *Conn) negotiate() {
329
330
return
330
331
}
331
332
c .opts .Logger .Debug (context .Background (), "setting local description" , slog .F ("closed" , c .isClosed ()))
332
- if c .isClosed () {
333
- return
334
- }
335
333
c .closeMutex .Lock ()
336
334
err = c .rtc .SetLocalDescription (offer )
337
335
c .closeMutex .Unlock ()
@@ -353,6 +351,9 @@ func (c *Conn) negotiate() {
353
351
case sessionDescription = <- c .remoteSessionDescription :
354
352
}
355
353
354
+ // This prevents candidates from being added while
355
+ // the remote description is being set.
356
+ c .remoteSessionDescriptionMutex .Lock ()
356
357
c .opts .Logger .Debug (context .Background (), "setting remote description" )
357
358
c .closeMutex .Lock ()
358
359
err := c .rtc .SetRemoteDescription (sessionDescription )
@@ -361,17 +362,17 @@ func (c *Conn) negotiate() {
361
362
_ = c .CloseWithError (xerrors .Errorf ("set remote description (closed %v): %w" , c .isClosed (), err ))
362
363
return
363
364
}
365
+ c .remoteSessionDescriptionMutex .Unlock ()
364
366
365
367
if ! c .offerrer {
368
+ c .closeMutex .Lock ()
366
369
answer , err := c .rtc .CreateAnswer (& webrtc.AnswerOptions {})
370
+ c .closeMutex .Unlock ()
367
371
if err != nil {
368
372
_ = c .CloseWithError (xerrors .Errorf ("create answer: %w" , err ))
369
373
return
370
374
}
371
375
c .opts .Logger .Debug (context .Background (), "setting local description" , slog .F ("closed" , c .isClosed ()))
372
- if c .isClosed () {
373
- return
374
- }
375
376
c .closeMutex .Lock ()
376
377
err = c .rtc .SetLocalDescription (answer )
377
378
c .closeMutex .Unlock ()
@@ -418,10 +419,10 @@ func (c *Conn) AddRemoteNegotiation(negotiation Negotiation) error {
418
419
}
419
420
420
421
if len (negotiation .ICECandidates ) > 0 {
422
+ c .remoteSessionDescriptionMutex .Lock ()
423
+ defer c .remoteSessionDescriptionMutex .Unlock ()
421
424
c .opts .Logger .Debug (context .Background (), "adding remote negotiation with ice candidates" ,
422
425
slog .F ("count" , len (negotiation .ICECandidates )))
423
- c .closeMutex .Lock ()
424
- defer c .closeMutex .Unlock ()
425
426
for _ , iceCandidate := range negotiation .ICECandidates {
426
427
err := c .rtc .AddICECandidate (iceCandidate )
427
428
if err != nil {
0 commit comments