Skip to main content
An ICE Agent is the core component that manages the ICE protocol execution, including candidate gathering, connectivity checks, and connection maintenance.

What is an ICE Agent?

The Agent type (defined in agent.go:40) orchestrates the entire ICE process:

Creating an Agent

Using Config (Deprecated)

The AgentConfig approach is deprecated. Use NewAgentWithOptions() for new code.

Agent Lifecycle

The ICE agent progresses through several phases during its lifetime:

1. Creation and Initialization

2. Credential Exchange

3. Candidate Gathering

The gathering state transitions from GatheringStateNewGatheringStateGatheringGatheringStateComplete.

4. Connectivity Establishment

5. Connection Usage

6. Cleanup

Connection States

The agent’s connection state (defined in ice.go:10-34) tracks the ICE negotiation progress:

State Transitions

State changes are triggered by:
  • New → Checking: When Dial() or Accept() is called
  • Checking → Connected: When a candidate pair succeeds
  • Connected → Disconnected: After disconnectedTimeout without traffic
  • Disconnected → Failed: After failedTimeout from disconnected state
  • Connected → Connected: Can switch selected pairs during renomination
  • Any → Closed: When Close() is called
Implementation in agent.go:731-747:

Controlling vs Controlled Roles

ICE agents take on one of two roles during connection establishment:

Controlling Agent

  • Initiates nomination of candidate pairs
  • Sends binding requests with USE-CANDIDATE attribute
  • Typically the peer that initiated the session (caller)
  • Set by calling Dial()

Controlled Agent

  • Responds to nomination from controlling agent
  • Accepts nominated pairs
  • Typically the peer that received the session (callee)
  • Set by calling Accept()

Role Conflicts

If both agents claim the same role, ICE resolves the conflict using the tie-breaker value (randomly generated 64-bit number). The agent with the higher tie-breaker value keeps its role; the other switches. Implementation in agent.go:1452-1481:

Agent Configuration Options

Pion ICE provides extensive configuration through options:

Network Configuration

Candidate Configuration

Timeout Configuration

Configured in agent_config.go:16-59:
Disconnected Timeout (default 5s):
  • How long without traffic before transitioning to ConnectionStateDisconnected
  • Set to 0 to never go to disconnected
Failed Timeout (default 25s):
  • How long in disconnected state before transitioning to ConnectionStateFailed
  • Set to 0 to never go to failed
Keepalive Interval (default 2s):
  • How often to send STUN binding requests to maintain the connection
  • Set to 0 to disable keepalives (not recommended)
Check Interval (default 200ms):
  • How often to perform connectivity checks while in checking state

Advanced Configuration

Restarting an Agent

You can restart an agent to perform ICE restart (generates new credentials):
From agent.go:1694-1754, restarting:
  • Cancels ongoing gathering
  • Clears all candidates
  • Resets checklist and selected pair
  • Generates new credentials if not provided
  • Returns to ConnectionStateChecking (if not new)

Event Handlers

OnCandidate

OnConnectionStateChange

OnSelectedCandidatePairChange

Best Practices

Always set event handlers before calling GatherCandidates() to ensure you don’t miss any candidates.
Use GracefulClose() instead of Close() when shutting down to ensure all goroutines complete cleanly.
ICE Lite is suitable when:
  • Your application runs on a server with a public IP address
  • You want to reduce server complexity
  • The remote peer will be a full ICE agent
  • You don’t need relay candidates
Lite agents only gather host candidates and don’t perform active connectivity checks.