What is ICE?
ICE is a technique used to find the best way to connect two peers in WebRTC and other real-time communication systems. The protocol works by gathering potential connection paths (candidates) from both peers, testing them, and selecting the optimal path for media transmission.ICE solves the complex problem of NAT traversal by systematically testing multiple connection paths between peers to find one that works.
Why ICE is Needed
Modern networks present several challenges for direct peer-to-peer connections:- NAT devices hide internal IP addresses and translate ports
- Firewalls block unsolicited inbound connections
- Multiple network interfaces (WiFi, Ethernet, VPN) create routing complexity
- Enterprise networks may restrict certain protocols or ports
RFC 5245 Compliance
Pion ICE implements the Interactive Connectivity Establishment protocol as defined in RFC 5245. The implementation provides:- Full ICE agent functionality
- Support for both controlling and controlled roles
- Candidate gathering and prioritization
- Connectivity checks with STUN binding requests
- Nomination and pair selection
Key ICE Concepts
Candidates
Candidates represent potential connection endpoints. ICE defines four types:Host
Direct IP addresses from local network interfaces
Server Reflexive
Public IP addresses discovered via STUN servers
Peer Reflexive
Addresses learned during connectivity checks
Relay
Addresses allocated on TURN relay servers
Connectivity Checks
Connectivity checks test whether candidate pairs can successfully exchange data:- The ICE agent forms candidate pairs from local and remote candidates
- Pairs are prioritized based on candidate types and preferences
- STUN binding requests are sent to test each pair
- Successful responses validate the connection path
- The best working pair is selected for media transmission
Nomination
Nomination is the process of selecting a candidate pair for use:- Controlling agent: Initiates nomination by sending binding requests with USE-CANDIDATE flag
- Controlled agent: Responds to nomination requests
- Once nominated and acknowledged, the pair becomes the selected pair
How Pion ICE Implements the Protocol
Agent Architecture
Pion ICE centers around theAgent type defined in agent.go:40:
- Local and remote candidate lists
- Candidate pair checklist for connectivity testing
- Connection state machine
- Gathering state machine
- Role (controlling vs controlled)
State Machines
Pion ICE implements two parallel state machines:Connection State
Defined inice.go:10-34:
ConnectionStateNew- Initial state, gathering addressesConnectionStateChecking- Performing connectivity checksConnectionStateConnected- Successfully connected with a working pairConnectionStateCompleted- All checks finishedConnectionStateFailed- Unable to establish connectionConnectionStateDisconnected- Previously connected, now having issuesConnectionStateClosed- Agent has been closed
Gathering State
Defined inice.go:58-72:
GatheringStateNew- Gathering not yet startedGatheringStateGathering- Actively gathering candidatesGatheringStateComplete- All candidates gathered
Candidate Gathering Process
The gathering process implemented ingather.go:50-113:
- Initiate gathering with
GatherCandidates() - Collect host candidates from local network interfaces
- Discover server reflexive candidates using STUN servers
- Allocate relay candidates from TURN servers
- Emit candidates through the candidate callback handler
- Complete gathering when all sources exhausted
Connectivity Check Implementation
Connectivity checks are handled inagent.go:654-729:
- Forms candidate pairs from local and remote candidates
- Prioritizes pairs based on candidate preferences
- Sends binding requests to test connectivity
- Tracks responses and round-trip times
- Updates pair state based on results
Priority Calculation
Candidate priorities follow RFC 5245 recommendations (defined incandidatetype.go:44-57):
- Host: 126 (highest priority for direct connections)
- Peer Reflexive: 110
- Server Reflexive: 100
- Relay: 0 (lowest priority, used as fallback)
candidatepair.go:92-129:
Usage Example
Best Practices
Performance considerations:
- Use
WithMaxBindingRequests()to limit retry attempts - Configure appropriate timeout values for your network conditions
- Consider using lite mode for servers with public IP addresses
When to use ICE Lite mode
When to use ICE Lite mode
ICE Lite is appropriate for servers with publicly accessible IP addresses. Lite agents only provide host candidates and don’t perform connectivity checks, making them simpler but less flexible. Use lite mode when:
- Your server has a public IP address
- You want to reduce complexity on the server side
- Clients will be full ICE agents
Related Topics
- Agents - Learn about ICE agent lifecycle and configuration
- Candidates - Detailed information on candidate types
- Connectivity - Connection establishment and maintenance