Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal
obsoletes
- rfc-5245 — Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal for Offer/Answer Protocols
updated by
- rfc-8863 — Interactive Connectivity Establishment Patiently Awaiting Connectivity (ICE PAC)
Extracted elements (31)
Peer-reflexive candidates receive higher type preference than server-reflexive candidates because they are learned directly from the peer endpoint, always represent a path the peer can actually reach, and may reflect a more accurate NAT binding than a server-reflexive candidate discovered through a distant STUN server.
STUN transactions are paced via timer Ta rather than sent as fast as possible to avoid overloading NAT binding tables, STUN/TURN servers, and the network path. The recommended Ta formula (default ~50 ms) is based on the number of active data streams and an assumed bandwidth target for signaling traffic.
The STUN username in connectivity checks is formed by concatenating both agents' username fragments to prevent cross-session replay attacks and to allow the receiving agent to unambiguously look up the correct password. A globally unique username per session is required because STUN short-term credentials do not include a session identifier.
ICE mismatch occurs when middleboxes such as ALGs alter signaling (e.g., rewrite IP addresses in SDP), breaking candidate exchange. Each ICE usage specification must define whether the protocol is vulnerable to ICE mismatch, how to detect it, and what actions to take.
Each candidate MUST have a unique priority that MUST be a positive integer between 1 and (2^31 - 1). The type preference for peer-reflexive candidates MUST be higher than that of server-reflexive candidates.
Host candidates MUST NOT include loopback, deprecated IPv4-compatible IPv6, or IPv6 site-local unicast addresses. When privacy-protecting IPv6 addresses are gathered, corresponding tracking-enabling addresses on the same interface and prefix MUST NOT be gathered.
IPv6 link-local addresses MUST NOT be paired with non-link-local addresses when forming candidate pairs, to avoid creating pairs that are highly unlikely to succeed.
Server-reflexive and relayed candidates MUST be kept alive until ICE processing completes. For server-reflexive candidates learned via Binding requests, bindings MUST be refreshed by additional Binding requests; relayed candidates are refreshed using the TURN Refresh transaction.
The PRIORITY attribute MUST be included in every Binding request used for a connectivity check. Its value MUST be computed using the Section 5.1.2 formula for the local candidate but substituting the type preference of peer-reflexive candidates.
The username fragment and password used for connectivity-check authentication MUST be unguessable: at least 128 bits of random number generator output for the password and at least 24 bits for the username fragment.
To bound amplification attacks, an ICE agent MUST limit the total number of candidate pairs across all checklists. The default limit is 100 but MUST be configurable. Excess lower-priority pairs are discarded, distributed evenly across checklists.
Host candidates directly expose an endpoint's IP addresses to the peer and any passive observers, revealing location information. Agents may suppress tracking-enabling IPv6 addresses when privacy-preserving addresses are available on the same interface and prefix to limit location exposure.
A foundation is an arbitrary string assigned to each candidate that is identical for two candidates sharing the same type, base IP address, transport protocol, and STUN/TURN server IP address. Foundations group related candidates for the freezing algorithm that controls initial check ordering.
Candidate information that MUST be exchanged includes: candidate address, transport, foundation, component ID, 32-bit priority, type, and related address/port. Session-level information includes whether the agent is lite or full, a username fragment and password, and connectivity-check pacing value.
Candidate pair priority is computed as: pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0), where G is the controlling agent's candidate priority and D is the controlled agent's. Checklists are sorted in decreasing order of pair priority.
Candidate priority is computed as: priority = (2^24)*(type preference) + (2^8)*(local preference) + (2^0)*(256 - component ID). Recommended type preferences are 126 for host, 110 for peer-reflexive, 100 for server-reflexive, and 0 for relayed candidates.
ICE agents take one of two roles: controlling (nominates the final candidate pair) or controlled (waits for nomination). When both agents are full, the initiating agent is controlling; when one is lite, the full agent is controlling; when both are lite, the initiator is controlling.
ICE defines four candidate types: host (from local interfaces), server-reflexive (NAT binding learned via STUN/TURN), peer-reflexive (NAT binding discovered during connectivity checks), and relayed (address allocated on a TURN server). Each candidate has a transport address, type, base, priority, foundation, and component ID.
ICE extends STUN with four attributes used exclusively in connectivity checks: PRIORITY (32-bit unsigned integer), USE-CANDIDATE (empty value; nominates a pair), ICE-CONTROLLED (64-bit tie-breaker for the controlled agent), and ICE-CONTROLLING (64-bit tie-breaker for the controlling agent).
Initial candidate pair states are set by placing all pairs in Frozen, then for each foundation, unfreezing exactly one pair — the first pair (lowest component ID, then highest priority) in the first checklist of the checklist set that has that foundation.
Lite implementations use only host candidates, do not run state machines, and do not generate connectivity checks; they only respond to incoming checks. Lite is intended for hosts permanently on the public Internet with stable public IP addresses.
Nomination is performed by the controlling agent sending a STUN Binding request with the USE-CANDIDATE attribute on a valid pair. Once both agents complete successful transactions for the nominated pair, the nominated flag is set and those pairs become the selected pairs for the data stream.
Triggered checks are connectivity checks enqueued when an agent receives an incoming Binding request from its peer. They are placed in a per-checklist FIFO triggered-check queue and take priority over ordinary scheduled checks, accelerating pair validation.
IANA has created the ICE Options registry with Expert Review policy. The string 'ice2' is registered to indicate support for RFC 8445 (as opposed to RFC 5245), allowing peers to detect which ICE version is in use.
IANA has registered error response code 487 (Role Conflict) in the STUN Error Codes registry, used when an agent detects that both agents have taken the same role (both controlling or both controlled).
IANA has registered four STUN attributes for ICE connectivity checks in the STUN Attributes registry: PRIORITY (0x0024), USE-CANDIDATE (0x0025), ICE-CONTROLLED (0x8029), and ICE-CONTROLLING (0x802A).
A STUN amplification attack occurs when an attacker provides many candidate addresses, causing an agent to send a large volume of STUN checks toward a victim. The mandatory 100-pair (configurable) limit on total candidate pairs in the checklist set directly bounds the worst-case amplification factor.
An attacker can spoof STUN Binding requests to induce an agent to perform triggered checks toward a victim (off-path amplification), or to falsely declare a candidate pair valid. The STUN short-term credential mechanism keyed to the per-session username fragment and password provides integrity and authenticity protection for all connectivity checks.
Each candidate pair has one of five states: Frozen (initial; cannot be checked yet), Waiting (unfrozen; ready to check), In-Progress (check sent; awaiting response), Succeeded (check succeeded), or Failed (check failed or timed out). Transitions: Frozen→Waiting (unfreeze), Waiting→In-Progress (perform), In-Progress→Succeeded or Failed.
Each checklist has a state: Running (initial), Completed (nominated pair exists for each component), or Failed (no valid pair for some component and all pairs are in Failed/Succeeded). Overall ICE state is Completed if all checklists are Completed, Failed if all are Failed, Running otherwise.
PRIORITY is a 32-bit unsigned integer STUN attribute (type 0x0024). ICE-CONTROLLED (0x8029) and ICE-CONTROLLING (0x802A) each carry a 64-bit unsigned integer tie-breaker value. USE-CANDIDATE (0x0025) has an empty value field (length 0).