Check out our Amazon Connect solution! Learn More

The Evolution of the WebRTC ICE API

By callstats on June 22, 2018

Real-time communication requires a reliable NAT traversal mechanism, as the involved endpoints are likely to be behind NATs or firewalls. Thus, the WebRTC Standard makes ICE usage mandatory for all WebRTC endpoints (RFC5245). In our previous blog posts, we covered WebRTC v1.0’s ICE gathering states and ICE connection states.

The WebRTC Working Group (WG) met this week to discuss the evolution of the WebRTC v1.0 spec based on emerging use cases (AR, VR, IoT, etc) and developer feedback on the current API. We will cover the discussions in forthcoming blog posts. Since we have covered ICE in detail before (e.g., ICE data tables, detections, our REST API series ) and NAT-related issues seem to be at the forefront of each new delpoyment, we look to discuss the evolution of WebRTC ICE API first.

At the meeting, the main line of discussion within the WG was how to evolve the WebRTC API over the next few years and overcome the issues that we have encountered with the current API. Peter Thatcher from Google described possible options for the API based on the level of control. As always, the API is simple when we have less control and more complex when we have more control.

Another big reason for evolving the WebRTC ICE API is to be able to add more or new UDP transports, such as, QUIC (A UDP-Based Multiplexed and Secure Transport). QUIC’s reliable (ordered or unordered) transport can already be a big benefit for live streaming and decentralized content distribution. In the future when unreliable-mode of QUIC becomes available, it could also enable sending media over QUIC, which would empower new features like multipath for media reliability and resilience.


The PeerConnection API of v1.0 gives a stable communication of streaming media and data between endpoints. It provides some control over ICE with RTCIceTransport API through the Session Description Protocol (SDP). The current API allows you to gather, exchange and sort the candidates, and start checks. For example, setLD on the Answering side starts the ICE checks and setRD on the Offering side starts the corresponding checks. The major issue with this is the reliance on the SDP Offer/Answer semantics.

WebRTC-ICE More Control

In order to remove dependency on the SDP, RTCIceTransport needs to be decoupled from the PeerConnection. This lets it be controlled directly, so it can be wired up to any other object like the RTCSctpTransport, RTCDtlsTransport, or possibly a RTCQuicTransport, which is currently documented in WebRTC-ICE. As such, it is compatible with WebRTC 1.0 IceTransport and gives direct control with no SDP. By giving more control of ICE to the web application, the typical use cases are:

  1. Control over which local candidates are gathered (wifi, cell, cable, etc.).
  2. Control over the lifetime of the local candidate (retaining it, closing it).
  3. Easier way of controlling the order of candidates.
  4. Control over the frequency of checks for the candidate pairs.
  5. Control over reselection, renomination, and debugging of candidate and/or candidate pairs.


Some of the above use cases can be achieved by imbuing the RTCIceCandidate object from ORTC, which allows for parallel forking and has additional objects such as an IceGatherer. Since ORTC was designed to allow the WebRTC 1.0 API to be written as a shim on top of the ORTC API, it already allows backwards compatibility and feedback from the existing customer base of ORTC. ORTC is popularly used for gaming consoles.


Why not go one step further from the features in ORTC and enable all the above listed use cases? Apart from ICE renomination and ICE freezing, everything else is already possible via ICE-bis. The overarching concept is known as as Flexible ICE, or FlexICE for short. FlexICE should provide more control that will enable more complex use cases. Some of these are listed below:

  • RTCIceGatherOptions.networkInterfaceIds to control network usage, for example filter WiFi and Mobile candidates. And the corresponding IceLocalCandidate.networkInterfaceType and networkInterfaceId to allow these candidate pairs to be listed.
  • IceTransport.gather() and removeLocalCandidate() to add/remove local candidates
  • IceCandidatePair.setCheckPriority() to control check order
  • and nominate() to select and nominate a candidate pair
  • IceCandidatePair.setMinCheckInterval(), setFrozen(), setReceiveTimeout() to control check activity/frequency
  • IceCandidatePair.onchecksent, oncheckresponsereceived, onreceivetimeout to know when things stop working and control what “disconnected” means.
  • IceTransport.retainLocalCandidate() to not free a particular local candidate. Similarly, IceTransport.retainCandidatePair() to not free a particular candidate pair.
  • IceTransport.removeCandidatePair() to remove a particular candidate pair

FlexICE is the most likely option to be pursued as WebRTC moves forward. To this end, we may discuss some of the proposals made in FlexICE at a later date.

Interested in learning more about the future of real-time communication and its new, intriguing uses? Check out our white paper on innovative uses of real-time video and audio communication.

Notes: Parts of the Diagram were taken from Image Credit: Peter Thatcher, Google (WebRTC NV Interim, 20 June 2018)

Tags: WebRTC, ICE