Skip to content

Blocked goro if peer connection is closed before ICE candidate gathering completes when using non-trickling ICE #2507

Open
@marc-evans

Description

Your environment.

  • Version: v3.2.8
  • Browser: N/A
  • Other Information - stacktraces, related issues, suggestions how to fix, links for us to have context

What did you do?

We have client that is unable to use trickling ICE, so we use the gathering promise approach to wait until local candidates have been collected before sending the SDP answer:

// Create channel that is blocked until ICE Gathering is complete
	gatherComplete := webrtc.GatheringCompletePromise(peerConnection)

	answer, err := peerConnection.CreateAnswer(nil)
	if err != nil {
		panic(err)
	} else if err = peerConnection.SetLocalDescription(answer); err != nil {
		panic(err)
	}

	// Block until ICE Gathering is complete, disabling trickle ICE
	// we do this because we only can exchange one signaling message
	// in a production application you should exchange ICE Candidates via OnICECandidate
	<-gatherComplete

We have noticed an occasional networking issue that cause ICE candidate gathering to stall, which after a timeout causes the peer connection to time out. This then closes the ICE agent whilst, due to longer TCP timeouts, the ICE gathering continues. Eventually, the ICE gathering concludes but the GatheringStateComplete status is never set:

ice WARNING: 2023/06/28 10:30:28 Failed to set gatheringState to GatheringStateComplete: the agent is closed

This results in the gatherComplete channel never receiving the 'done' signal, which blocks the goro it is running in indefinitely.

This behaviour can be reproduced using the ice-tcp example with the following diff:

@@ -71,0 +74 @@ func doSignaling(w http.ResponseWriter, r *http.Request) {
+       peerConnection.Close()
        <-gatherComplete

What did you expect?

The promise resolves successfully on the peer connection / ICE agent being closed.

What happened?

The peer connection is closed, which closes the ICE agent, but then setting GatheringStateComplete fails due to the ICE agent being closed. This results in the gathering promise never resolving, which blocks the goro it's running in indefinitely.

Whilst the WebRTC spec may be moving towards trickling ICE as standard, clients are still allowed to be non-trickling and some examples in this repo utilise the gathering promise, so this seems like a pertinent bug to flag.

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions