Commit 9b8d8686 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Fix a race between delUpConn and addLocal.

We could call addLocal after the remote was closed, which
would cause the local connection to remain forever.

Thanks to Ludovic Rateau.
parent 3d2089f4
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"io" "io"
"log" "log"
"math/bits" "math/bits"
"os"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
...@@ -461,6 +462,7 @@ type rtpUpConnection struct { ...@@ -461,6 +462,7 @@ type rtpUpConnection struct {
iceCandidates []*webrtc.ICECandidateInit iceCandidates []*webrtc.ICECandidateInit
mu sync.Mutex mu sync.Mutex
closed bool
pushed bool pushed bool
replace string replace string
tracks []*rtpUpTrack tracks []*rtpUpTrack
...@@ -500,6 +502,11 @@ func (up *rtpUpConnection) User() (string, string) { ...@@ -500,6 +502,11 @@ func (up *rtpUpConnection) User() (string, string) {
func (up *rtpUpConnection) AddLocal(local conn.Down) error { func (up *rtpUpConnection) AddLocal(local conn.Down) error {
up.mu.Lock() up.mu.Lock()
defer up.mu.Unlock() defer up.mu.Unlock()
// the connection may have been closed in the meantime, in which
// case we'd never get rid of the down connection
if up.closed {
return os.ErrClosed
}
for _, t := range up.local { for _, t := range up.local {
if t == local { if t == local {
return nil return nil
......
...@@ -231,6 +231,10 @@ func delUpConn(c *webClient, id string, userId string, push bool) error { ...@@ -231,6 +231,10 @@ func delUpConn(c *webClient, id string, userId string, push bool) error {
g := c.group g := c.group
c.mu.Unlock() c.mu.Unlock()
conn.mu.Lock()
conn.closed = true
conn.mu.Unlock()
conn.pc.Close() conn.pc.Close()
if push && g != nil { if push && g != nil {
...@@ -616,7 +620,10 @@ func gotAnswer(c *webClient, id string, sdp string) error { ...@@ -616,7 +620,10 @@ func gotAnswer(c *webClient, id string, sdp string) error {
add := func() { add := func() {
down.pc.OnConnectionStateChange(nil) down.pc.OnConnectionStateChange(nil)
for _, t := range down.tracks { for _, t := range down.tracks {
t.remote.AddLocal(t) err := t.remote.AddLocal(t)
if err != nil && err != os.ErrClosed {
log.Printf("Add track: %v", err)
}
} }
} }
down.pc.OnConnectionStateChange(func(state webrtc.PeerConnectionState) { down.pc.OnConnectionStateChange(func(state webrtc.PeerConnectionState) {
...@@ -981,6 +988,9 @@ func handleAction(c *webClient, a interface{}) error { ...@@ -981,6 +988,9 @@ func handleAction(c *webClient, a interface{}) error {
down, _, err := addDownConn(c, a.conn) down, _, err := addDownConn(c, a.conn)
if err != nil { if err != nil {
if err == os.ErrClosed {
return nil
}
return err return err
} }
done, err := replaceTracks(down, tracks, a.conn) done, err := replaceTracks(down, tracks, a.conn)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment