skip to content

In ICE (RFC 8445), what are host, server-reflexive, peer-reflexive and relayed candidates, and how do connectivity checks choose the pair that is used?

level: middleimportance: should knowfreq 29%

answer

  1. four places an address can come from
  2. one type appears only during checks
  3. priority favours direct over relayed
  4. a STUN request on every pair
  5. one agent nominates

basics

~20 s

Host candidates are local addresses, server-reflexive ones are NAT mappings learned from STUN, relayed ones are TURN addresses, and peer-reflexive ones appear during checks. Agents test candidate pairs with STUN requests by priority; the controlling agent nominates one.

solid answer

~50 s

An ICE agent (RFC 8445) gathers **host** candidates from its own interfaces, **server-reflexive** candidates from STUN Binding responses, and **relayed** candidates from a TURN allocation. **Peer-reflexive** candidates are never gathered: they appear when a connectivity check reveals a mapping the agent had not seen, typically a NAT that allocated a new port toward this peer. Each candidate gets a priority, `2^24 x type preference + 2^8 x local preference + (256 - component ID)`, with recommended type preferences of 126 for host, 110 for peer-reflexive, 100 for server-reflexive and 0 for relayed. The agents pair their candidates, sort the pairs into a checklist and send a STUN Binding request on each one, paced (Ta, 50 ms by default); a request and response in both directions makes a pair valid. The **controlling** agent then nominates one valid pair per component, and that pair carries the data.

go deeper

for a junior

Learn the four candidate types and where each comes from: your interface, a STUN server, a TURN server, or a connectivity check.

for a middle

Explain the priority formula and the recommended type preferences, how pairs are formed and checked with STUN requests, and how a peer-reflexive candidate appears mid-check.

for a senior

Diagnose a session that always lands on the relay: check which candidates were gathered, whether checks reached the peer, and whether the NATs allocate new ports per destination.

for a principal

Decide how candidate gathering and check timing trade connection speed against relay cost and battery or bandwidth use across the device mix your product serves.

## The four candidate types A **candidate** is a transport address (IP address plus port) at which an ICE agent might receive data. RFC 8445 names four kinds: | Type | Where it comes from | Recommended type preference | |---|---|---| | **Host** | an address bound to the agent's own interface | 126 | | **Peer-reflexive** | learned *during* connectivity checks, from a mapped address no other candidate matches | 110 | | **Server-reflexive** | the mapped address in a STUN Binding response from a STUN server | 100 | | **Relayed** | the relayed transport address of an allocation on a TURN server | 0 | Host, server-reflexive and relayed candidates are **gathered** before checks start. A peer-reflexive candidate cannot be gathered: it exists because a check from this agent to the peer went through a NAT mapping that differs from every candidate the agent already had. Before exchanging lists, an agent removes **redundant** candidates, those with the same transport address and the same base as a higher-priority one; a server-reflexive candidate equal to a host candidate, which is what an agent with no NAT sees, is the usual case. ## Priority: direct paths first Each candidate's priority is: ``` priority = 2^24 x (type preference) + 2^8 x (local preference) + (256 - component ID) ``` - **Type preference** (0 to 126) must be the same for every candidate of a type and different between types, and peer-reflexive must rank above server-reflexive. - **Local preference** (0 to 65535) orders several candidates of the same type, for example two interfaces or IPv6 against IPv4. - **Component ID** (1 to 256) separates the components of one data stream, such as two related flows that each need a path. A relayed candidate at type preference 0 is, as RFC 8445 puts it, used only as a last resort. Pairs combine both sides' priorities, so the checklist tries the most direct pairings first. ## Connectivity checks 1. Each agent pairs its local candidates with the remote candidates of the same component and address family. 2. The pairs are sorted by pair priority and pruned into a **checklist**. 3. The agent sends a STUN Binding request on the next pair at a pacing interval **Ta**, 50 ms by default. Checks go from and to the exact addresses and ports the data will use, which is why the data path and the checks share one port and are told apart by content. 4. When the peer receives a check, it answers and schedules a **triggered check** back on the same pair, which speeds things up. 5. A pair whose checks succeed in both directions becomes **valid**. 6. If a Binding response reports a mapped address the agent does not know, that address becomes a new **peer-reflexive** candidate, and the pair it forms is checked like any other. Because every pair is tried, ICE finds a working path if one exists; ordering only makes it find the best one sooner. ## Nomination and conclusion One agent is **controlling**, the other **controlled**. When at least one valid pair exists for a component, the controlling agent picks one and sends a check on it carrying the `USE-CANDIDATE` attribute; once that succeeds, the pair is **nominated** and becomes the selected pair. RFC 8445 keeps only this procedure, which RFC 5245 called *regular nomination*, and deprecates RFC 5245's *aggressive nomination*. After selection, each agent sends a **keepalive** on the selected pair if nothing has been sent on it for **Tr** seconds; RFC 8445 recommends 15 seconds and forbids less. ICE uses STUN Binding indications for this, so no response traffic is added. ## Why peer-reflexive outranks server-reflexive It is tempting to say a peer-reflexive address is preferred because it is the mapping the NAT really made toward this peer. That is true, but RFC 8445's own stated reason is **security**: an attacker can more easily get an agent to use a false server-reflexive candidate than a false peer-reflexive one, so preferring peer-reflexive candidates blunts attacks on address gathering. ## Points that are easy to get wrong - **Peer-reflexive candidates are not gathered from a server.** They come only out of checks. - **The STUN server takes no part in the checks.** Agents check each other directly. - **The candidate exchange itself is not ICE's wire protocol.** ICE says what must be carried; the application's signalling carries it. - **A lite implementation** (ICE-lite, for an endpoint that is always on a public address) gathers only host candidates and does not generate checks; it answers the full agent's checks.

  • Why does ICE keep checking pairs after the first one succeeds instead of using it immediately?
    The first pair to succeed is not necessarily the best: a relayed pair may complete before a direct one simply because of timing. Under RFC 8445 the controlling agent lets checks continue until at least one valid pair exists for each component, then chooses when to nominate based on local policy, and it can wait for a higher-priority pair. Aggressive nomination, which nominated on every check, is deprecated.
  • Why does ICE send keepalives on a selected pair that is already carrying data?
    Data alone cannot be relied on to keep NAT mappings open: a stream can fall silent for long periods. RFC 8445 requires a keepalive on each pair used for data if nothing has been sent for Tr seconds, 15 seconds recommended and never less, using STUN Binding indications so the keepalive adds no response traffic.

saying these in an interview costs you the question

  • Peer-reflexive candidates are learned from a STUN server before the checks start.
  • The STUN server runs the connectivity checks between the two peers.
  • ICE uses the first candidate pair whose check succeeds, whatever its type.
  • Relayed candidates get the highest priority because they almost always work.
  • Either agent may nominate a pair as soon as its own check succeeds.