From c62fd28aa856386e986727651a6d0210e17c4d5a Mon Sep 17 00:00:00 2001 From: Raja Subramanian Date: Sat, 2 Sep 2023 22:59:39 +0530 Subject: [PATCH] Clear selected pair on ICE failed (#612) When ICE times out and fails, all candidates are deleted. That means all the candidates are closed and their underlying conns are clsoed. But, the selected pair could still be valid. On a subsequenct `Write`, ICE transport conn will get the selected pair and write to the pair. As the pair is still valid, write will flow through to the local candidate `writeTo`. But, as all candidates and their underlying conns are closed, `Write` will return a `io.ErrClosedPipe` error. There are cases where it is not ignored and causes a broken pipe after an ICERestart. When the `Write` error propagates back to sctp/association, the writeLoop is exited. So, sending data channel traffic after a successful ICERestart still fails as the SCTP association errored out and write loop exited. I have copied the changes that are done when ICERestart happens to when ICE state is set to failed (except for gathering state and resetting ufrag/pwd). In my testing, it is working well, i. e. can continue data channel after ICE Restart whereas previously it was failing every time. But, I am not sure of all the implications of this change. Update authors Update AUTHORS.txt --- AUTHORS.txt | 1 + agent.go | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index 7c5adc7f..56269cc7 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -15,6 +15,7 @@ Artur Shellunts Assad Obaid Atsushi Watanabe backkem +boks1971 buptczq cgojin Chao Yuan diff --git a/agent.go b/agent.go index 3f06857a..426df0b4 100644 --- a/agent.go +++ b/agent.go @@ -494,6 +494,10 @@ func (a *Agent) updateConnectionState(newState ConnectionState) { if a.connectionState != newState { // Connection has gone to failed, release all gathered candidates if newState == ConnectionStateFailed { + a.removeUfragFromMux() + a.checklist = make([]*CandidatePair, 0) + a.pendingBindingRequests = make([]bindingRequest, 0) + a.setSelectedPair(nil) a.deleteAllCandidates() }