Skip to content

Commit

Permalink
Cancel previous gathering routine on restart
Browse files Browse the repository at this point in the history
Updated ICE agent restart method to cancel the
current gathering and then restart the candidate
gathering process.
  • Loading branch information
wawesomeNOGUI authored and stv0g committed Nov 12, 2022
1 parent 7f2d498 commit 9ab8f71
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 12 deletions.
9 changes: 5 additions & 4 deletions agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -1196,8 +1196,10 @@ func (a *Agent) SetRemoteCredentials(remoteUfrag, remotePwd string) error {
// Restart restarts the ICE Agent with the provided ufrag/pwd
// If no ufrag/pwd is provided the Agent will generate one itself
//
// Restart must only be called when GatheringState is GatheringStateComplete
// a user must then call GatherCandidates explicitly to start generating new ones
// If there is a gatherer routine currently running, Restart will
// cancel it.
// After a Restart, the user must then call GatherCandidates explicitly
// to start generating new ones.
func (a *Agent) Restart(ufrag, pwd string) error {
if ufrag == "" {
var err error
Expand All @@ -1224,8 +1226,7 @@ func (a *Agent) Restart(ufrag, pwd string) error {
var err error
if runErr := a.run(a.context(), func(ctx context.Context, agent *Agent) {
if agent.gatheringState == GatheringStateGathering {
err = ErrRestartWhenGathering
return
agent.gatherCandidateCancel()
}

// Clear all agent needed to take back to fresh state
Expand Down
21 changes: 16 additions & 5 deletions agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1375,13 +1375,24 @@ func TestAgentRestart(t *testing.T) {
oneSecond := time.Second

t.Run("Restart During Gather", func(t *testing.T) {
agent, err := NewAgent(&AgentConfig{})
assert.NoError(t, err)
connA, connB := pipe(&AgentConfig{
DisconnectedTimeout: &oneSecond,
FailedTimeout: &oneSecond,
})

ctx, cancel := context.WithCancel(context.Background())
assert.NoError(t, connB.agent.OnConnectionStateChange(func(c ConnectionState) {
if c == ConnectionStateFailed || c == ConnectionStateDisconnected {
cancel()
}
}))

agent.gatheringState = GatheringStateGathering
connA.agent.gatheringState = GatheringStateGathering
assert.NoError(t, connA.agent.Restart("", ""))

assert.Equal(t, ErrRestartWhenGathering, agent.Restart("", ""))
assert.NoError(t, agent.Close())
<-ctx.Done()
assert.NoError(t, connA.agent.Close())
assert.NoError(t, connB.agent.Close())
})

t.Run("Restart When Closed", func(t *testing.T) {
Expand Down
3 changes: 0 additions & 3 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,6 @@ var (
// ErrInvalidMulticastDNSHostName indicates an invalid MulticastDNSHostName
ErrInvalidMulticastDNSHostName = errors.New("invalid mDNS HostName, must end with .local and can only contain a single '.'")

// ErrRestartWhenGathering indicates Restart was called when Agent is in GatheringStateGathering
ErrRestartWhenGathering = errors.New("ICE Agent can not be restarted when gathering")

// ErrRunCanceled indicates a run operation was canceled by its individual done
ErrRunCanceled = errors.New("run was canceled by done")

Expand Down

0 comments on commit 9ab8f71

Please sign in to comment.