Fix for proxy deadlock bug

This is a fix for the proxy-go deadlock bug (ticket #25688). The
assumption that OnIceComplete is always followed by a successful
connection where OnDataChannel has been called turns out not to occur in
practice. OnICEComplete looks like it is being deprecated in other
libraries anyway, so it's safer to just remove it.
This commit is contained in:
Cecylia Bocovich 2019-03-30 12:19:29 -04:00
parent 88f282c733
commit c28c8ca489

View file

@ -259,8 +259,6 @@ func datachannelHandler(conn *webRTCConn, remoteAddr net.Addr) {
// Installs an OnDataChannel callback that creates a webRTCConn and passes it to // Installs an OnDataChannel callback that creates a webRTCConn and passes it to
// datachannelHandler. // datachannelHandler.
func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config *webrtc.Configuration) (*webrtc.PeerConnection, error) { func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config *webrtc.Configuration) (*webrtc.PeerConnection, error) {
errChan := make(chan error)
answerChan := make(chan struct{})
pc, err := webrtc.NewPeerConnection(config) pc, err := webrtc.NewPeerConnection(config)
if err != nil { if err != nil {
@ -269,9 +267,6 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config *webrtc.
pc.OnNegotiationNeeded = func() { pc.OnNegotiationNeeded = func() {
panic("OnNegotiationNeeded") panic("OnNegotiationNeeded")
} }
pc.OnIceComplete = func() {
answerChan <- struct{}{}
}
pc.OnDataChannel = func(dc *webrtc.DataChannel) { pc.OnDataChannel = func(dc *webrtc.DataChannel) {
log.Println("OnDataChannel") log.Println("OnDataChannel")
@ -310,30 +305,25 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config *webrtc.
} }
log.Println("sdp offer successfully received.") log.Println("sdp offer successfully received.")
go func() { log.Println("Generating answer...")
log.Println("Generating answer...") answer, err := pc.CreateAnswer()
answer, err := pc.CreateAnswer() // blocking // blocks on ICE gathering. we need to add a timeout if needed
if err != nil { // not putting this in a separate go routine, because we need
errChan <- err // SetLocalDescription(answer) to be called before sendAnswer
return if err != nil {
} pc.Destroy()
err = pc.SetLocalDescription(answer) return nil, err
if err != nil { }
errChan <- err
return if answer == nil {
} pc.Destroy()
}() return nil, fmt.Errorf("Failed gathering ICE candidates.")
}
// Wait until answer is ready.
select { err = pc.SetLocalDescription(answer)
case err = <-errChan: if err != nil {
pc.Destroy() pc.Destroy()
return nil, err return nil, err
case _, ok := <-answerChan:
if !ok {
pc.Destroy()
return nil, fmt.Errorf("Failed gathering ICE candidates.")
}
} }
return pc, nil return pc, nil
} }