Skip to main content
ICE connectivity is the process of establishing and maintaining a peer-to-peer connection by testing candidate pairs and selecting the optimal path.

Connection Establishment

The connection establishment process follows these steps:

1. Exchange Credentials

Credentials consist of:
  • ufrag (username fragment): At least 24 bits of randomness
  • pwd (password): At least 128 bits of randomness
These are used for STUN message authentication.

2. Exchange Candidates

3. Start Connectivity Checks

From agent.go:625-652, starting checks:

Connectivity Checks

The Check Process

Connectivity checks test whether candidate pairs can successfully communicate.
Connectivity checks use STUN Binding Requests and Responses to verify that a path works and measure round-trip time.

Check Flow

Implementation

From agent.go:654-729, the connectivity check loop:

Candidate Pair States

From candidatepair_state.go:9-26: Transitions:

Ping Candidates

From agent.go:772-794, pinging all pairs in checklist:

Selecting the Best Pair

From agent.go:843-858, finding the highest priority succeeded pair:

Connection State Transitions

From ice.go:10-34, the connection states:

State Diagram

Checking → Connected

Transition occurs when a candidate pair succeeds:

Connected → Disconnected

From agent.go:882-922, validation checks:
Example timeline:
  • t=0s: Connected
  • t=5s: No traffic received → Disconnected (if disconnectedTimeout=5s)
  • t=30s: Still no traffic → Failed (if failedTimeout=25s)
Set disconnectedTimeout to 0 to skip the disconnected state and go directly to failed.

Gathering States

From ice.go:58-72:

Gathering Flow

From gather.go:79-113:

Keep-alive Mechanism

Once connected, the agent must maintain the connection through keepalives.

Purpose of Keep-alive

  1. Maintain NAT bindings: NATs have timeouts (typically 30-300 seconds)
  2. Detect disconnections: Verify the path is still working
  3. Consent freshness: RFC 7675 requires ongoing consent

Implementation

From agent.go:924-938:
Pion ICE uses STUN Binding Requests for keepalives (not Binding Indications) to support consent freshness requirements from RFC 7675.

Keepalive Timing

Recommendations:
  • Minimum: 15 seconds (to avoid excessive traffic)
  • Default: 2 seconds (works well for most scenarios)
  • Maximum: 15-20 seconds (risk NAT timeout)

Handling Disconnections

Detecting Disconnection

Disconnection is detected when no traffic is received:

Recovery Strategies

1. Wait for Recovery

The agent continues sending keepalives during disconnection:

2. ICE Restart

Perform a full ICE restart with new credentials:

3. Renomination (Advanced)

Switch to a different candidate pair without restarting:

Connection Failures

Failure Scenarios

  1. All candidate pairs fail
    • No working path between peers
    • Might need relay candidates
  2. Timeout in checking state
    • Exceeded disconnectedTimeout + failedTimeout while checking
    • From agent.go:670-680
  3. Prolonged disconnection
    • Connected then lost connection for disconnectedTimeout + failedTimeout

Handling Failure

Monitoring Connection Health

Using Callbacks

Checking Selected Pair

Pair Statistics

From candidatepair.go:131-336, available metrics:

Best Practices

Configure timeouts based on your use case:
  • Real-time gaming: Short timeouts (3s disconnected, 10s failed)
  • Video conferencing: Medium timeouts (5s disconnected, 25s failed)
  • File transfer: Long timeouts (30s disconnected, 60s failed)
Always handle state changes in your application. Don’t assume the connection will stay in the connected state.
Common issues and solutions:
  1. Stuck in checking state
    • Check if remote candidates were added
    • Verify credentials match
    • Ensure STUN/TURN servers are reachable
    • Check firewall rules
  2. Connected then immediate disconnect
    • Verify keepalive is enabled
    • Check if NAT timeout is very short
    • Ensure application sends data
  3. Only works with relay
    • Symmetric NAT on both sides
    • Firewall blocking UDP
    • Check if srflx candidates are gathered
  4. Frequent disconnections
    • Network instability
    • NAT rebinding
    • Enable continual gathering
    • Consider increasing timeouts
Mobile networks present unique challenges:
Handle network type changes: