Starting Candidate Gathering
To begin gathering candidates, callGatherCandidates() after creating an agent:
Candidate Types
The ICE agent can gather three types of candidates:1
Host Candidates
Local network addresses discovered from your network interfaces. These are gathered by enumerating network interfaces and binding to local ports.
2
Server Reflexive Candidates
Public addresses discovered by sending STUN binding requests to STUN servers. The server returns your public IP and port as seen from the internet.
3
Relay Candidates
Relayed addresses obtained from TURN servers. All traffic flows through the TURN server, ensuring connectivity even through restrictive NATs.
Gathering Process
The gathering process runs concurrently for all candidate types:Host Candidate Gathering
Host candidates are gathered by:- Enumerating network interfaces
- Filtering based on interface and IP filters
- Binding UDP/TCP sockets to local ports
- Creating candidate objects with priority calculations
Server Reflexive Gathering
Server reflexive candidates are discovered by:- Binding local UDP sockets
- Sending STUN binding requests to configured STUN servers
- Receiving XOR-MAPPED-ADDRESS responses
- Creating srflx candidates with the public address
Relay Candidate Gathering
Relay candidates are obtained by:- Connecting to TURN servers via UDP, TCP, TLS, or DTLS
- Performing TURN allocation
- Receiving relayed transport address
- Creating relay candidates
Gathering States
The gathering process transitions through three states:- New - Initial state before gathering starts
- Gathering - Actively gathering candidates
- Complete - All gathering finished (in GatherOnce mode)
Continual vs Single Gathering
Pion ICE supports two gathering policies:GatherOnce (Default)
Gathering completes after the initial collection:OnCandidate handler receives a nil candidate when gathering completes.
GatherContinually
Continuously monitors network interfaces and gathers new candidates as they appear:Continual gathering is useful for mobile applications where network interfaces change frequently (switching between WiFi and cellular).
Network Monitoring
With continual gathering, the agent periodically checks for network changes:mDNS Candidates
For local network privacy, ICE can use mDNS hostnames instead of IP addresses:Multicast DNS Modes
MulticastDNSModeDisabled- No mDNS support (default)MulticastDNSModeQueryOnly- Resolve mDNS candidates from remote peerMulticastDNSModeQueryAndGather- Gather and resolve mDNS candidates
When using
MulticastDNSModeQueryAndGather, host candidates will advertise .local hostnames instead of IP addresses, hiding location-tracking information.Handling Candidates
TheOnCandidate handler is called for each discovered candidate:
Location Tracking Prevention
ICE automatically filters certain candidates to prevent location tracking:Example: Continual Gathering
Here’s a complete example demonstrating continual gathering:Troubleshooting
No Candidates Gathered
- Verify network types are enabled:
WithNetworkTypes() - Check interface filters aren’t too restrictive
- Enable debug logging to see why interfaces are skipped
STUN/TURN Failures
- Verify server URLs are correct
- Check firewall allows UDP/TCP to STUN/TURN ports
- Increase STUN gather timeout:
WithSTUNGatherTimeout(10 * time.Second) - Check TURN credentials are valid
Gathering Never Completes
- Ensure
OnCandidatehandler is set beforeGatherCandidates() - Check for network connectivity issues
- Review logs for errors during gathering
Next Steps
Connectivity Checks
Learn how ICE performs connectivity checks between candidates
NAT Traversal
Configure address rewriting for NAT traversal
Multiplexing
Share UDP/TCP ports across multiple ICE sessions
Examples
See gathering examples in action