Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
marc-evans opened this issue Jun 28, 2023 · 0 comments
Labels
bug Something isn't working difficulty:easy

Comments

@marc-evans
Copy link

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.

@Sean-Der Sean-Der added bug Something isn't working difficulty:easy labels Apr 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working difficulty:easy
Projects
None yet
Development

No branches or pull requests

2 participants