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 (
"io"
"log"
"math/bits"
"os"
"sync"
"sync/atomic"
"time"
......@@ -461,6 +462,7 @@ type rtpUpConnection struct {
iceCandidates []*webrtc.ICECandidateInit
mu sync.Mutex
closed bool
pushed bool
replace string
tracks []*rtpUpTrack
......@@ -500,6 +502,11 @@ func (up *rtpUpConnection) User() (string, string) {
func (up *rtpUpConnection) AddLocal(local conn.Down) error {
up.mu.Lock()
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 {
if t == local {
return nil
......
......@@ -231,6 +231,10 @@ func delUpConn(c *webClient, id string, userId string, push bool) error {
g := c.group
c.mu.Unlock()
conn.mu.Lock()
conn.closed = true
conn.mu.Unlock()
conn.pc.Close()
if push && g != nil {
......@@ -616,7 +620,10 @@ func gotAnswer(c *webClient, id string, sdp string) error {
add := func() {
down.pc.OnConnectionStateChange(nil)
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) {
......@@ -981,6 +988,9 @@ func handleAction(c *webClient, a interface{}) error {
down, _, err := addDownConn(c, a.conn)
if err != nil {
if err == os.ErrClosed {
return nil
}
return err
}
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