Skip to content

Commit

Permalink
Fix detached datachannels handling
Browse files Browse the repository at this point in the history
#2696 introduced removing
datachannels from the sctptransport for better garbage collection.

That PR introduced a race condition for data channels created before
connection establishment. When an out of band negotiated data channel,
created before peerconnection establishment is detached, there's a race
between the data channel being removed from `r.dataChannels` and it
being copied in to the existing data channel slice in the
acceptDataChannels goroutine.

This PR fixes this race by copying the slice before any datachannels
could be detached.
  • Loading branch information
sukunrt committed Dec 23, 2024
1 parent fbf79c1 commit 59fc492
Showing 1 changed file with 4 additions and 6 deletions.
10 changes: 4 additions & 6 deletions sctptransport.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func (r *SCTPTransport) Start(_ SCTPCapabilities) error {
r.dataChannelsOpened += openedDCCount
r.lock.Unlock()

go r.acceptDataChannels(sctpAssociation)
go r.acceptDataChannels(sctpAssociation, dataChannels)

return nil
}
Expand All @@ -163,10 +163,9 @@ func (r *SCTPTransport) Stop() error {
return nil
}

func (r *SCTPTransport) acceptDataChannels(a *sctp.Association) {
r.lock.RLock()
dataChannels := make([]*datachannel.DataChannel, 0, len(r.dataChannels))
for _, dc := range r.dataChannels {
func (r *SCTPTransport) acceptDataChannels(a *sctp.Association, existingDataChannels []*DataChannel) {
dataChannels := make([]*datachannel.DataChannel, 0, len(existingDataChannels))
for _, dc := range existingDataChannels {
dc.mu.Lock()
isNil := dc.dataChannel == nil
dc.mu.Unlock()
Expand All @@ -175,7 +174,6 @@ func (r *SCTPTransport) acceptDataChannels(a *sctp.Association) {
}
dataChannels = append(dataChannels, dc.dataChannel)
}
r.lock.RUnlock()

ACCEPT:
for {
Expand Down

0 comments on commit 59fc492

Please sign in to comment.