Skip to main content
ICE candidate gathering is the process of discovering and collecting local network addresses that can be used for peer-to-peer communication. This guide covers how gathering works, the different gathering modes, and how to handle candidates.

Starting Candidate Gathering

To begin gathering candidates, call GatherCandidates() after creating an agent:
You must set the OnCandidate handler before calling GatherCandidates(), otherwise the agent will return ErrNoOnCandidateHandler.

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:
  1. Enumerating network interfaces
  2. Filtering based on interface and IP filters
  3. Binding UDP/TCP sockets to local ports
  4. Creating candidate objects with priority calculations

Server Reflexive Gathering

Server reflexive candidates are discovered by:
  1. Binding local UDP sockets
  2. Sending STUN binding requests to configured STUN servers
  3. Receiving XOR-MAPPED-ADDRESS responses
  4. Creating srflx candidates with the public address

Relay Candidate Gathering

Relay candidates are obtained by:
  1. Connecting to TURN servers via UDP, TCP, TLS, or DTLS
  2. Performing TURN allocation
  3. Receiving relayed transport address
  4. Creating relay candidates

Gathering States

The gathering process transitions through three states:
  1. New - Initial state before gathering starts
  2. Gathering - Actively gathering candidates
  3. 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:
The 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 peer
  • MulticastDNSModeQueryAndGather - Gather and resolve mDNS candidates
When using MulticastDNSModeQueryAndGather, host candidates will advertise .local hostnames instead of IP addresses, hiding location-tracking information.

Handling Candidates

The OnCandidate handler is called for each discovered candidate:

Location Tracking Prevention

ICE automatically filters certain candidates to prevent location tracking:
Link-local IPv6 addresses are filtered when gathering candidates that use privacy mechanisms.

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 OnCandidate handler is set before GatherCandidates()
  • 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