1. Introduction
The
RtcTransport
API
is
a
low-level
API
used
for
sending
and
receiving
datagrams
over
a
secure
peer-to-peer
transport.
The transport is consent-based, meaning that the connection must be accepted by the remote peer before any application data can be sent.
It provides application-level packet scheduling, giving applications full control over packet pacing and bandwidth estimation. Additionally, transport feedback is sent back to the sender and fed into a circuit-breaker, which protects the network by disallowing packets to be sent if abusive behavior is detected.
The API has been designed in a modular fashion to allow wire formats, transport establishment mechanics, and feedback formats to evolve over time.
2. Conformance
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in [RFC2119] and [RFC8174] when, and only when, they appear in all capitals, as shown here.
This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.
Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)
Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [WEBIDL] , as this specification uses that specification and terminology.
3. Concepts
- Circuit Breaker
-
A mechanism used to protect the network by detecting and stoping abusive behavior.
- Network Route
-
A specific route between a local and a remote peer.
- Transport Format
-
A combination of a wire format and a Transport Header .
- Transport Header
-
A transport level header included in packets that carries feedback information from the remote peer, used in conjuction with the Circuit Breaker to detect and prevent abusive network behavior.
- Writable
-
A Network Route is considered writable when it has been verified that the remote peer can successfully receive packets over that specific Network Route .
4.
The
RtcTransport
Interface
[Exposed =(Window ,Worker )]interface {RtcTransport constructor (RtcTransportConfig );config undefined setFormat (RtcTransportFormat );format undefined sendPackets (sequence <RtcPacketToSend >,packets RtcNetworkRoute );networkRoute undefined setRemoteFingerprints (sequence <ArrayBuffer >);fingerprint Promise <boolean >establishEncryption (RtcNetworkRoute );networkRoute sequence <RtcPacketSentInfo >getPacketSentInfo ();();sequence <RtcPacketReceived >getReceivedPacket ();static readonly attribute FrozenArray <RtcTransportFormat >supportedFormats ;readonly attribute RtcNetworkRouteController networkRouteController ;attribute EventHandler ontransportstatus ;attribute EventHandler onpendingpacketssentinfo ;attribute EventHandler onpendingpacketsreceived ;attribute EventHandler onerror ;attribute EventHandler onfeedbacksent ; };
4.1. Internal slots
An
RtcTransport
object
has
the
following
internal
slots.
| Internal Slot | Description ( non-normative ) |
|---|---|
[[Format]]
|
The
configured
RtcTransportFormat
.
|
[[RouteController]]
|
The
route
controller.
Instantiated
according
to
the
provided
transportControllerType
.
|
[[PendingSendPackets]]
| A queue for packets that are scheduled to be sent. |
[[PendingSentInfo]]
| A queue for information about sent packets. |
[[PendingReceivedPackets]]
| A queue for received packets. |
[[EncryptionContext]]
| The established encryption context. |
[[RemoteFingerprints]]
| A list of fingerprints of the remote peer’s certificates. |
[[LastScheduledPacketInfo]]
| The ID and send time of the last successfully scheduled packet. |
4.2. Constructor
-
constructor(config) -
When the
RtcTransport()constructor is invoked, the user agent MUST run the following steps:-
Let transport be a new
RtcTransportobject. -
Set transport ’s
[[Format]]internal slot toundefined. -
Set transport ’s
[[PendingSendPackets]]internal slot to a new empty queue . -
Set transport ’s
[[PendingSentInfo]]internal slot to a new empty queue . -
Set transport ’s
[[PendingReceivedPackets]]internal slot to a new empty queue . -
Set transport ’s
[[EncryptionContext]]internal slot toundefined. -
Set transport ’s
[[RemoteFingerprints]]internal slot toundefined. -
Set transport ’s
[[LastScheduledPacketInfo]]internal slot toundefined. -
If config ’s
transportControllerTypemember is"automaticIceController", set transport ’s[[RouteController]]internal slot to a newRtcAutomaticIceControllerobject. -
If config ’s
transportControllerTypemember is"manualIceController", set transport ’s[[RouteController]]internal slot to a newRtcManualIceControllerobject. -
Return transport .
-
4.3. Methods
-
setFormat(format) -
When the
setFormat(format)method is invoked, the user agent MUST run the following steps:-
Let transport be the
RtcTransportobject on which the method was invoked. -
If transport ’s
[[Format]]internal slot is notundefined, throw anInvalidStateError. -
If format is the
RtcTransportFormatvalue"ICE-DTLS/V0"and transport ’s[[RouteController]]internal slot is neither anRtcAutomaticIceControllernor anRtcManualIceControllerobject, throw aNotSupportedError.In this version of the specification, the only supported
RtcTransportFormatis"ICE-DTLS/V0", which is compatible with all available route controllers (RtcAutomaticIceControllerandRtcManualIceController). -
Set transport ’s
[[Format]]internal slot to format .
-
-
sendPackets(packets, networkRoute) -
When the
sendPackets(packets, networkRoute)method is invoked, the user agent MUST run the following steps:-
Let transport be the
RtcTransportobject on which the method was invoked. -
Let controller be transport ’s
[[RouteController]]internal slot. -
If networkRoute ’s
[[AssociatedController]]internal slot is not controller , throw anInvalidAccessError. -
If transport ’s
[[EncryptionContext]]internal slot isundefined, throw anInvalidStateError. -
If networkRoute is not Writable , throw an exception.
-
If packets is empty , return.
-
Let lastInfo be transport ’s
[[LastScheduledPacketInfo]]internal slot. -
For each packet in packets :
-
If packet is the first item in packets :
-
If lastInfo is not
undefined:-
If packet ’s
idis less than or equal to lastInfo ’s ID, throw aRangeError. -
If packet ’s
sendTimeis less than lastInfo ’s send time, throw aRangeError.
-
-
-
Otherwise:
-
Let previousPacket be the item in packets immediately preceding packet .
-
If packet ’s
idis less than or equal to previousPacket ’sid, throw aRangeError. -
If packet ’s
sendTimeis less than previousPacket ’ssendTime, throw aRangeError.
-
-
Let now be the current high resolution time.
-
If packet ’s
sendTimeis greater than now + 100ms, throw aRangeError.
-
-
Enqueue all items in packets into transport ’s
[[PendingSendPackets]]queue. -
Let lastPacket be the last item in packets .
-
Set transport ’s
[[LastScheduledPacketInfo]]to a new record containing lastPacket ’sidas ID and lastPacket ’ssendTimeas send time.
-
What type of exceptions should be thrown when the various checks fail?
What should the acceptable range for the send time be? What if the send time is in the past?
Decide
what
to
do
if
the
networkRoute
becomes
non-writable
before
packets
were
scheduled
for
sending.
Describe how sendPackets interacts with the circuit breaker.
There should be some text describing how sending is done and what the expected behavior should be.
-
setRemoteFingerprints(fingerprint) -
When the
setRemoteFingerprints(fingerprint)method is invoked, the user agent MUST run the following steps:-
Let transport be the
RtcTransportobject on which the method was invoked. -
If transport ’s
[[RemoteFingerprints]]internal slot is notundefined, throw anInvalidStateError. -
Set transport ’s
[[RemoteFingerprints]]internal slot to fingerprint .
-
Should there be any validation of the fingerprints? Is there a particular standard we expect them to adhere to?
-
establishEncryption(networkRoute) -
When the
establishEncryption(networkRoute)method is invoked, the user agent MUST run the following steps:-
Let transport be the
RtcTransportobject on which the method was invoked. -
Let p be a new promise .
-
Let controller be transport ’s
[[RouteController]]internal slot. -
If networkRoute ’s
[[AssociatedController]]internal slot is not controller , reject p with anInvalidAccessErrorand return p . -
If transport ’s
[[EncryptionContext]]internal slot is notundefined, resolve p withtrueand return p . -
If transport ’s
[[RemoteFingerprints]]internal slot isundefined, reject p with anInvalidStateErrorand return p . -
If networkRoute is not writable , resolve p with
falseand return p . -
Run the following steps in parallel :
-
Start or continue the encryption establishment process over networkRoute to establish a secure transport connection.
-
As part of the encryption establishment process, the user agent MUST verify that the certificate presented by the remote peer matches one of the fingerprints stored in transport ’s
[[RemoteFingerprints]]internal slot. If the verification fails, the encryption establishment process fails.The specific encryption mechanism depends on the configured
RtcTransportFormat. For example, for theRtcTransportFormatvalue"ICE-DTLS/V0", this corresponds to performing a DTLS handshake and verifying the remote certificate against the fingerprints. -
If the encryption establishment process completes successfully:
-
Set transport ’s
[[EncryptionContext]]internal slot to the established encryption context. -
Resolve p with
true.
-
-
If the encryption establishment process fails or times out:
-
Resolve p with
false.
-
-
-
Return p .
-
-
getPacketSentInfo() -
When the
getPacketSentInfo()method is invoked, the user agent MUST run the following steps:-
Let transport be the
RtcTransportobject on which the method was invoked. -
Let result be a new empty list .
-
While transport ’s
[[PendingSentInfo]]queue is not empty :-
Append the result of dequeueing from transport ’s
[[PendingSentInfo]]queue to result .
-
-
Return result .
-
-
getReceivedPacket() -
When the
getReceivedPacket()method is invoked, the user agent MUST run the following steps:-
Let transport be the
RtcTransportobject on which the method was invoked. -
Let result be a new empty list .
-
While transport ’s
[[PendingReceivedPackets]]queue is not empty :-
Append the result of dequeueing from transport ’s
[[PendingReceivedPackets]]queue to result .
-
-
Return result .
-
4.4. Attributes
-
supportedFormats, of type FrozenArray< RtcTransportFormat >, readonly -
Returns a list of supported
RtcTransportFormats. -
networkRouteController, of type RtcNetworkRouteController , readonly -
Returns the controller associated with this transport.
-
ontransportstatus, of type EventHandler -
Fired when the circuit-breaker disables or re-enables the transport.
-
onpendingpacketssentinfo, of type EventHandler -
Fired when there is new packet sent info to retrieve.
-
onpendingpacketsreceived, of type EventHandler -
Fired when there are new received packets to retrieve.
-
onerror, of type EventHandler -
Fired on buffer overflows (sent info, feedback, or receive buffers).
-
onfeedbacksent, of type EventHandler -
Fired when the transport automatically generates and sends protocol-level feedback.
5. ICE Controllers
5.1. RtcManualIceController
[Exposed =(Window ,Worker )]interface {RtcManualIceController undefined gatherHostCandidates ();Promise <undefined >gatherSrflxCandidates (IceServerInit );iceServer Promise <boolean >refreshSrflxCandidate (LocalIceCandidate );localCandidate Promise <undefined >gatherRelayCandidates (IceServerInit ,server unsigned long );requestedLifetimeInSeconds Promise <unsigned long >refreshRelayCandidate (LocalIceCandidate ,relayCandidate unsigned long );requestedLifetimeInSeconds IceCandidatePair createCandidatePair (LocalIceCandidate ,local RemoteIceCandidateInit );remote Promise <IceProbeResult >probeCandidatePair (IceCandidatePair );candidatePair attribute EventHandler oncandidategathered ;attribute EventHandler oncandidateremoved ;attribute EventHandler onmaxpayloadsizeupdate ;attribute EventHandler onerror ; };
5.1.1. Internal slots
An
RtcManualIceController
object
has
the
following
internal
slots.
| Internal Slot | Description ( non-normative ) |
|---|---|
[[HostCandidateGatheringStarted]]
| A boolean indicating whether host candidate gathering has been started. |
[[IceUfrag]]
| A randomly assigned username fragment for local ICE authentication. |
[[IcePassword]]
| A randomly assigned password for local ICE authentication. |
[[LocalCandidatesToProcess]]
|
A
queue
of
LocalIceCandidate
objects
gathered
by
this
controller
that
are
scheduled
to
be
processed.
|
5.1.2. Instantiation
When
a
new
RtcManualIceController
object
is
created,
the
user
agent
MUST
run
the
following
steps:
-
Let controller be a new
RtcManualIceControllerobject. -
Set controller ’s
[[HostCandidateGatheringStarted]]internal slot tofalse. -
Set controller ’s
[[IceUfrag]]internal slot to a newly generated random username fragment. -
Set controller ’s
[[IcePassword]]internal slot to a newly generated random password. -
Set controller ’s
[[LocalCandidatesToProcess]]internal slot to a new empty queue . -
Return controller .
5.1.3. Methods
-
gatherHostCandidates() -
When the
gatherHostCandidates()method is invoked, the user agent MUST run the following steps:-
Let controller be the
RtcManualIceControllerobject on which the method was invoked. -
If controller ’s
[[HostCandidateGatheringStarted]]internal slot istrue, return. -
Set controller ’s
[[HostCandidateGatheringStarted]]internal slot totrue. -
Gather host candidates in parallel for controller .
-
-
gatherSrflxCandidates(iceServer) -
When the
gatherSrflxCandidates(iceServer)method is invoked, the user agent MUST run the following steps:-
Let controller be the
RtcManualIceControllerobject on which the method was invoked. -
Validate the IceServer iceServer with expected scheme
"stun". -
Let p be a new promise .
-
Run the following steps in parallel :
-
Let completedCount be 0.
-
Let availableInterfaces be the system’s available network interfaces.
-
If availableInterfaces is empty , Queue a task to resolve p with
undefined. -
Let numInterfaces be the size of availableInterfaces .
-
For each interface in availableInterfaces :
-
Run the following steps in parallel:
-
Send a STUN Binding request to the STUN server defined by iceServer , utilizing a local port allocated for host candidates on interface .
-
Wait for a successful STUN Binding response, for the request to time out after 30 seconds, or for interface to become unavailable.
-
If a successful STUN Binding response is received:
-
Let reflectedAddress and reflectedPort be the mapped IP address and port discovered in the STUN response.
-
Let candidate be a new
LocalIceCandidateobject. -
Initialize a local candidate candidate for controller on interface , with type
"srflx", address reflectedAddress , port reflectedPort , and source server iceServer . -
Enqueue candidate into controller ’s
[[LocalCandidatesToProcess]]queue.
-
-
Set completedCount to completedCount + 1.
-
If completedCount is equal to numInterfaces :
-
Queue a task to resolve p with
undefined.
-
-
-
-
-
Return p .
-
-
refreshSrflxCandidate(localCandidate) -
When the
refreshSrflxCandidate(localCandidate)method is invoked, the user agent MUST run the following steps:-
Let controller be the
RtcManualIceControllerobject on which the method was invoked. -
If localCandidate ’s
[[AssociatedController]]internal slot is not controller , throw anInvalidAccessError. -
If localCandidate ’s
typeattribute is not theIceCandidateTypevalue"srflx", throw aTypeError. -
Let server be localCandidate ’s
[[SourceServer]]internal slot. -
Let interface be localCandidate ’s
[[NetworkInterface]]internal slot. -
Let p be a new promise .
-
Run the following steps in parallel :
-
If interface is unavailable, Queue a task to resolve p with
falseand return. -
Send a STUN Binding request to the STUN server defined by server , utilizing the local port allocated for localCandidate on interface .
-
Wait for a successful STUN Binding response, for the request to time out after 30 seconds, or for interface to become unavailable.
-
If a successful STUN Binding response is received:
-
Queue a task to resolve p with
true.
-
-
Otherwise:
-
Queue a task to resolve p with
false.
-
-
-
Return p .
-
-
gatherRelayCandidates(server, requestedLifetimeInSeconds) -
When the
gatherRelayCandidates(server, requestedLifetimeInSeconds)method is invoked, the user agent MUST run the following steps:-
Let controller be the
RtcManualIceControllerobject on which the method was invoked. -
Validate the IceServer server with expected scheme
"turn". -
Let p be a new promise .
-
Run the following steps in parallel :
-
Let completedCount be 0.
-
Let availableInterfaces be the system’s available network interfaces.
-
If availableInterfaces is empty , Queue a task to resolve p with
undefined. -
Let numInterfaces be the size of availableInterfaces .
-
For each interface in availableInterfaces :
-
Run the following steps in parallel:
-
Send a TURN Allocate request to the TURN server defined by server , utilizing a local port allocated for host candidates on interface . The Allocate request MUST include a
LIFETIMEattribute containing requestedLifetimeInSeconds , and utilize the authentication credentials defined by server . -
Wait for a successful TURN Allocate response, for the allocation to fail, for the request to time out after 30 seconds, or for interface to become unavailable.
-
If a successful TURN Allocate response is received:
-
Let relayedAddress and relayedPort be the relayed IP address and port discovered in the
XOR-RELAYED-ADDRESSattribute of the Allocate response. -
Let grantedLifetime be the lifetime (in seconds) returned in the
LIFETIMEattribute of the Allocate response. -
Let candidate be a new
LocalIceCandidateobject. -
Initialize a local candidate candidate for controller on interface , with type
"relay", address relayedAddress , port relayedPort , source server server , and relay allocation lifetime grantedLifetime . -
Enqueue candidate into controller ’s
[[LocalCandidatesToProcess]]queue.
-
-
Set completedCount to completedCount + 1.
-
If completedCount is equal to numInterfaces :
-
Queue a task to resolve p with
undefined.
-
-
-
-
-
Return p .
-
-
refreshRelayCandidate(relayCandidate, requestedLifetimeInSeconds) -
When the
refreshRelayCandidate(relayCandidate, requestedLifetimeInSeconds)method is invoked, the user agent MUST run the following steps:-
Let controller be the
RtcManualIceControllerobject on which the method was invoked. -
If relayCandidate ’s
[[AssociatedController]]internal slot is not controller , throw anInvalidAccessError. -
If relayCandidate ’s
typeattribute is not theIceCandidateTypevalue"relay", throw aTypeError. -
Let server be relayCandidate ’s
[[SourceServer]]internal slot. -
Let interface be relayCandidate ’s
[[NetworkInterface]]internal slot. -
Let p be a new promise .
-
If interface is unavailable, resolve p with
0and return p . -
Run the following steps in parallel :
-
Send a TURN Refresh request to the TURN server defined by server , utilizing the local port allocated for relayCandidate on interface . The Refresh request MUST include a
LIFETIMEattribute containing requestedLifetimeInSeconds , and utilize the authentication credentials defined by server . -
Wait for a successful TURN Refresh response, for the request to fail, for the request to time out after 30 seconds, or for interface to become unavailable.
-
If a successful TURN Refresh response is received:
-
Let grantedLifetime be the lifetime (in seconds) returned in the
LIFETIMEattribute of the Refresh response. -
Set relayCandidate ’s
[[RelayAllocationLifetime]]internal slot to grantedLifetime . -
Queue a task to resolve p with grantedLifetime .
-
-
Otherwise:
-
Queue a task to resolve p with
0.
-
-
-
Return p .
-
-
createCandidatePair(local, remote) -
When the
createCandidatePair(local, remote)method is invoked, the user agent MUST run the following steps:-
Let controller be the
RtcManualIceControllerobject on which the method was invoked. -
If local ’s
[[AssociatedController]]internal slot is not controller , throw anInvalidAccessError. -
Validate the remote candidate remote .
-
Let pair be a new
IceCandidatePairobject. -
Set pair ’s
[[LocalCandidate]]internal slot to local . -
Set pair ’s
[[RemoteCandidate]]internal slot to remote . -
Set pair ’s
[[AssociatedController]]internal slot to controller . -
Return pair .
-
-
probeCandidatePair(candidatePair) -
When the
probeCandidatePair(candidatePair)method is invoked, the user agent MUST run the following steps:-
Let controller be the
RtcManualIceControllerobject on which the method was invoked. -
If candidatePair ’s
[[AssociatedController]]internal slot is not controller , throw anInvalidAccessError. -
Let local be candidatePair ’s
localCandidateattribute. -
Let remote be candidatePair ’s
remoteCandidateattribute. -
Let interface be local ’s
[[NetworkInterface]]internal slot. -
Let p be a new promise .
-
Run the following steps in parallel :
-
If interface is unavailable, run the following steps:
-
Let result be a new
IceProbeResultdictionary, initialized as follows:-
successset tofalse.
-
-
Queue a task to resolve p with result and return.
-
-
Send a STUN Binding request (probe) to the remote destination defined by remote ’s IP address and port, utilizing the local port allocated for local on interface . The probe request MUST utilize standard ICE connectivity check attributes authenticated using the remote candidate’s password fragment.
-
Let sendTime be the high-resolution timestamp when the STUN Binding request was sent.
-
Wait for a successful STUN Binding response, for the request to fail, or for the request to time out after 30 seconds, or for interface to become unavailable.
-
If interface is unavailable, run the following steps:
-
Let result be a new
IceProbeResultdictionary, initialized as follows:-
successset tofalse.
-
-
Queue a task to resolve p with result and return.
-
-
If a successful STUN Binding response is received:
-
Let receiveTime be the high-resolution timestamp when the Binding response was received on the local socket.
-
Let rtt be the measured duration in milliseconds: receiveTime - sendTime .
-
Let result be a new
IceProbeResultdictionary, initialized as follows: -
Queue a task to resolve p with result .
-
-
Otherwise:
-
Let result be a new
IceProbeResultdictionary, initialized as follows:-
successset tofalse.
-
-
Queue a task to resolve p with result .
-
-
-
Return p .
-
5.1.4. Attributes
-
oncandidategathered, of type EventHandler -
Fired when a local candidate has been found.
-
oncandidateremoved, of type EventHandler -
Fired when a local candidate has been removed.
-
onmaxpayloadsizeupdate, of type EventHandler -
Fired when the max payload size of some IceCandidatePair is updated.
-
onerror, of type EventHandler -
Fired on candidate gathering errors.
5.1.5. Local Candidate Processing
When
the
[[LocalCandidatesToProcess]]
queue
of
an
RtcManualIceController
controller
is
updated:
-
While controller ’s
[[LocalCandidatesToProcess]]queue is not empty :-
Let candidate be the result of dequeueing from controller ’s
[[LocalCandidatesToProcess]]queue. -
Let source be
undefined. -
Let lifetime be
null. -
If candidate ’s
typeattribute is theIceCandidateTypevalue"srflx":-
Set source to candidate ’s
[[SourceServer]]internal slot.
-
-
If candidate ’s
typeattribute is theIceCandidateTypevalue"relay":-
Set source to candidate ’s
[[SourceServer]]internal slot. -
Set lifetime to candidate ’s
[[RelayAllocationLifetime]]internal slot.
-
-
If candidate ’s
typeattribute is theIceCandidateTypevalue"host":-
Set source to
"host".
-
-
Dispatch a gathered candidate event at controller with candidate , source source , and allocation lifetime lifetime .
-
The network cost per network type needs to be defined.
What policies should be considered in relation to candidate discovery?
What are reasonable timeout limits? Implementation defined?
Do we need to specify in more detail what it means for an interface to be unavailable?
5.2. RtcAutomaticIceController
[Exposed =(Window ,Worker )]interface {RtcAutomaticIceController undefined setIceServers (sequence <IceServer >);servers undefined setRemoteCandidates (sequence <RemoteIceCandidate >);remoteCandidates attribute EventHandler oncandidategathered ;attribute EventHandler oncandidateremoved ;attribute EventHandler onmaxpayloadsizeupdate ;attribute EventHandler oncandidatepairupdated ;attribute EventHandler onerror ; };
5.2.1. Internal slots
An
RtcAutomaticIceController
object
has
the
following
internal
slots.
| Internal Slot | Description ( non-normative ) |
|---|---|
[[IceServers]]
|
A
list
of
IceServer
dictionaries
configured
for
this
controller.
|
[[IceUfrag]]
| A username fragment used for remote authentication. |
[[IcePassword]]
| A password used for remote authentication. |
[[RemoteCandidates]]
|
A
list
of
RemoteIceCandidate
dictionaries
representing
remote
candidates
added
to
the
controller.
|
[[LocalCandidates]]
|
A
list
of
LocalIceCandidate
objects
representing
local
candidates
active
for
pair
forming.
|
[[LocalCandidatesToProcess]]
|
A
queue
of
LocalIceCandidate
objects
gathered
by
this
controller
that
are
scheduled
to
be
processed.
|
5.2.2. Instantiation
When
a
new
RtcAutomaticIceController
object
is
created,
the
user
agent
MUST
run
the
following
steps:
-
Let controller be a new
RtcAutomaticIceControllerobject. -
Set controller ’s
[[IceServers]]internal slot to a new empty list . -
Set controller ’s
[[RemoteCandidates]]internal slot to a new empty list . -
Set controller ’s
[[LocalCandidates]]internal slot to a new empty list . -
Set controller ’s
[[LocalCandidatesToProcess]]internal slot to a new empty queue . -
Set controller ’s
[[IceUfrag]]internal slot to a newly generated random username fragment. -
Set controller ’s
[[IcePassword]]internal slot to a newly generated random password. -
Start the candidate gathering process for controller .
-
Return controller .
5.2.3. Methods
-
setIceServers(servers) -
When the
setIceServers(servers)method is invoked, the user agent MUST run the following steps:-
Let controller be the
RtcAutomaticIceControllerobject on which the method was invoked. -
For each server in servers :
-
Validate the IceServer server .
-
-
Set controller ’s
[[IceServers]]internal slot to servers .
-
-
setRemoteCandidates(remoteCandidates) -
When the
setRemoteCandidates(remoteCandidates)method is invoked, the user agent MUST run the following steps:-
Let controller be the
RtcAutomaticIceControllerobject on which the method was invoked. -
For each candidate in remoteCandidates :
-
Validate the remote candidate candidate .
-
-
Set controller ’s
[[RemoteCandidates]]internal slot to remoteCandidates .
-
5.2.4. Attributes
-
oncandidategathered, of type EventHandler -
Fired when a local candidate has been found.
-
oncandidateremoved, of type EventHandler -
Fired when a local candidate has been removed.
-
onmaxpayloadsizeupdate, of type EventHandler -
Fired when the max payload size is updated.
-
oncandidatepairupdated, of type EventHandler -
Fired whenever a new IceCandidatePair has been selected.
-
onerror, of type EventHandler -
Fired on candidate gathering errors.
5.2.5. Candidate Gathering
To start the candidate gathering process for a controller controller , the user agent MUST run the following steps in parallel:
-
Gather host candidates for controller .
-
Continuously monitor network interfaces.
-
When a network interface becomes available, for each server in controller ’s
[[IceServers]]internal slot:-
Gather reflexive and relay candidates for controller using server over the network interface.
-
-
When controller ’s
[[IceServers]]internal slot is updated:-
Let newServers be the list of
IceServers in the new value of[[IceServers]]that were not present in its previous value. -
For each server in newServers :
-
Run the following steps in parallel over each available network interface:
-
Gather reflexive and relay candidates for controller using server over the network interface.
-
-
-
5.2.6. Gather Reflexive and Relay Candidates
To
gather
reflexive
and
relay
candidates
for
a
controller
controller
using
an
IceServer
server
over
a
network
interface
interface
,
the
user
agent
MUST
run
the
following
steps:
-
Let url be the result of parsing server ’s
urlattribute as a URL. -
If url ’s scheme is
"stun"or"stuns":-
Perform STUN candidate gathering utilizing server on interface .
-
If a STUN Binding response is successfully received:
-
Let reflectedAddress and reflectedPort be the mapped IP address and port discovered in the STUN response.
-
Let candidate be a new
LocalIceCandidateobject. -
Initialize a local candidate candidate for controller on interface , with type
"srflx", address reflectedAddress , port reflectedPort , and source server server . -
Enqueue candidate into controller ’s
[[LocalCandidatesToProcess]]queue.
-
-
-
If url ’s scheme is
"turn"or"turns":-
Perform TURN candidate allocation utilizing server on interface .
-
If a TURN Allocate response is successfully received:
-
Let relayedAddress and relayedPort be the relayed IP address and port discovered in the
XOR-RELAYED-ADDRESSattribute of the Allocate response. -
Let grantedLifetime be the lifetime (in seconds) returned in the
LIFETIMEattribute of the Allocate response. -
Let candidate be a new
LocalIceCandidateobject. -
Initialize a local candidate candidate for controller on interface , with type
"relay", address relayedAddress , port relayedPort , source server server , and relay allocation lifetime grantedLifetime . -
Enqueue candidate into controller ’s
[[LocalCandidatesToProcess]]queue.
-
-
Does STUN/TURN gathering need to be specified in more detail? Is there some other doc we can point to?
5.2.7. Local Candidate Processing
When
the
[[LocalCandidatesToProcess]]
queue
of
an
RtcAutomaticIceController
controller
is
updated:
-
While controller ’s
[[LocalCandidatesToProcess]]queue is not empty :-
Let localCandidate be the result of dequeueing from controller ’s
[[LocalCandidatesToProcess]]queue. -
Let source be
undefined. -
Let lifetime be
null. -
If localCandidate ’s
typeattribute is theIceCandidateTypevalue"srflx":-
Set source to localCandidate ’s
[[SourceServer]]internal slot.
-
-
If localCandidate ’s
typeattribute is theIceCandidateTypevalue"relay":-
Set source to localCandidate ’s
[[SourceServer]]internal slot. -
Set lifetime to localCandidate ’s
[[RelayAllocationLifetime]]internal slot.
-
-
If localCandidate ’s
typeattribute is theIceCandidateTypevalue"host":-
Set source to
"host".
-
-
Append localCandidate to controller ’s
[[LocalCandidates]]internal slot. -
Dispatch a gathered candidate event at controller with localCandidate , source source , and allocation lifetime lifetime .
-
5.2.8. Candidate Pair Forming
An
RtcAutomaticIceController
controller
continuously
monitors
and
reacts
to
updates
in
its
local
candidates
and
remote
candidates
to
form
and
evaluate
candidate
pairs:
-
When controller ’s
[[LocalCandidates]]internal slot is updated (e.g., when a new local candidate localCandidate is appended):-
For each remoteCandidate in controller ’s
[[RemoteCandidates]]internal slot:-
Evaluate whether trying to form a candidate pair with localCandidate and remoteCandidate is worth it or not (e.g., based on candidate types, network type, and routing policies).
-
If so:
-
Let pair be an
IceCandidatePaircreated by setting its[[LocalCandidate]]slot to localCandidate ,[[RemoteCandidate]]slot to remoteCandidate , and[[AssociatedController]]slot to controller . -
Perform an ICE connectivity check (ping) on pair by sending an authenticated STUN Binding request using the remote candidate’s credentials.
-
-
-
-
When controller ’s
[[RemoteCandidates]]internal slot is updated:-
Let newCandidates be the list of
RemoteIceCandidates in the new value of[[RemoteCandidates]]that were not present in its previous value. -
For each remoteCandidate in newCandidates :
-
For each localCandidate in controller ’s
[[LocalCandidates]]internal slot:-
Evaluate whether trying to form a candidate pair with localCandidate and remoteCandidate is worth it or not (e.g., based on candidate types, network type, and routing policies).
-
If so:
-
Let pair be an
IceCandidatePaircreated by setting its[[LocalCandidate]]slot to localCandidate ,[[RemoteCandidate]]slot to remoteCandidate , and[[AssociatedController]]slot to controller . -
Perform an ICE connectivity check (ping) on pair by sending an authenticated STUN Binding request using the remote candidate’s credentials.
-
-
-
-
-
Continuously perform ICE connectivity checks by forming candidate pairs with the remote candidates in controller ’s
[[RemoteCandidates]]internal slot and the local candidates in controller ’s[[LocalCandidates]]internal slot, in order to select and maintain network routes.
5.3. Procedures
5.3.1. Validate IceServer
To validate the IceServer server with an optional DOMString expectedScheme :
-
Let url be the result of parsing server ’s
urlattribute as a URL. -
If url is failure, throw a
TypeError. -
Let scheme be url ’s scheme.
-
If expectedScheme is provided:
-
Otherwise, if scheme is neither
"stun","stuns","turn", nor"turns", throw aTypeError. -
If scheme is
"turn"or"turns":-
If server ’s
usernamemember is not present, or if server ’scredentialsmember is not present, throw aTypeError.
-
5.3.2. Validate Remote Candidate
To validate the remote candidate candidate :
-
If candidate ’s
ufragmember is the empty string, throw aTypeError. -
If candidate ’s
pwdmember is the empty string, throw aTypeError. -
If candidate ’s
addressmember is the empty string, throw aTypeError. -
If candidate ’s
portmember is equal to 0, throw aTypeError. -
If candidate ’s
typemember is not a validIceCandidateTypevalue, throw aTypeError.
5.3.3. Initialize a Local Candidate
To initialize a local candidate candidate for a controller controller on a network interface interface , with a type type , address address , port port , optional source server server , and optional relay allocation lifetime lifetime , the user agent MUST run the following steps:
-
Set candidate ’s
addressattribute to address . -
Set candidate ’s
portattribute to port . -
Set candidate ’s
typeattribute to type . -
Set candidate ’s
ufragattribute to controller ’s[[IceUfrag]]internal slot. -
Set candidate ’s
pwdattribute to controller ’s[[IcePassword]]internal slot. -
Set candidate ’s
networkCostattribute to a value representing the network cost of interface . -
Set candidate ’s
[[NetworkInterface]]internal slot to interface . -
If server is provided, set candidate ’s
[[SourceServer]]internal slot to server . -
If lifetime is provided, set candidate ’s
[[RelayAllocationLifetime]]internal slot to lifetime . -
Set candidate ’s
[[AssociatedController]]internal slot to controller .
5.3.4. Gather Host Candidates
To
gather
host
candidates
for
an
RtcNetworkRouteController
controller
,
the
user
agent
MUST
run
the
following
steps
in
parallel:
-
Continuously monitor network interfaces.
-
When a network interface is available:
-
Let candidate be a new
LocalIceCandidateobject. -
Let port be a port allocated for host candidates on the network interface.
-
Initialize a local candidate candidate for controller on the network interface, with type
"host", address as the IP address of the network interface, and port port . -
Enqueue candidate into controller ’s
[[LocalCandidatesToProcess]]queue.
-
5.3.5. Dispatch a Gathered Candidate Event
To dispatch a gathered candidate event at a controller controller with a candidate candidate , a source source , and an optional allocation lifetime lifetime , the user agent MUST run the following steps:
-
Let event be a new
IceCandidateGatheredEventobject, initialized as follows:-
typeset to"candidategathered". -
bubblesset tofalse. -
cancelableset tofalse. -
candidateset to candidate . -
sourceset to source . -
networkCostset to candidate ’snetworkCostattribute. -
allocationLifetimeset to lifetime if provided, andnullotherwise.
-
-
Queue a task to dispatch event at controller .
6. Helper Types
6.1. RtcTransportConfig
dictionary {RtcTransportConfig required DOMString name ;required RtcNetworkRouteControllerType transportControllerType ;required sequence <RTCCertificate >certificates ; };
-
name, of type DOMString -
A name useful for debugging/devtools.
-
transportControllerType, of type RtcNetworkRouteControllerType -
Determines the ICE controller type.
-
certificates, of type sequence< RTCCertificate > -
The certificates to use for DTLS.
6.2. RtcPacketToSend
dictionary {RtcPacketToSend long long id ;ArrayBuffer data ;DOMHighResTimeStamp sendTime ; };
-
id, of type long long -
Monotonically increasing packet ID.
-
data, of type ArrayBuffer -
The byte buffer to be sent.
-
sendTime, of type DOMHighResTimeStamp -
The timestamp describing when the packet should be put on the wire.
6.3. RtcPacketSentInfo
dictionary {RtcPacketSentInfo long long id ;long long packetSizeBytes ;DOMHighResTimeStamp sendTime ; };
-
id, of type long long -
The ID of the packet.
-
packetSizeBytes, of type long long -
The size of the packet in bytes.
-
sendTime, of type DOMHighResTimeStamp -
The actual timestamp that the packet was put on the wire.
6.4. RtcEcnMarking
enum {RtcEcnMarking "classic" ,"l4s" ,"experienced-congestion" };
"classic"The ECN field is
10, indicating the ECT(0) codepoint used by classic ECN senders."l4s"The ECN field is
01, indicating the ECT(1) codepoint used by L4S-aware senders."experienced-congestion"The ECN field is
11, indicating that the packet experienced congestion.
6.5. RtcPacketReceived
[Exposed =(Window ,Worker )]interface {RtcPacketReceived readonly attribute ArrayBuffer data ;readonly attribute DOMHighResTimeStamp receiveTime ;readonly attribute RtcEcnMarking ?ecnMarking ;readonly attribute RtcNetworkRoute networkRoute ; };
-
data, of type ArrayBuffer , readonly -
The byte buffer received.
-
receiveTime, of type DOMHighResTimeStamp , readonly -
The timestamp of packet receipt.
-
ecnMarking, of type RtcEcnMarking , readonly, nullable The Explicit Congestion Notification (ECN) field of the IP packet as received from the network, or
nullif the ECN field is00, indicating a Not-ECN-Capable Transport packet.This is receive-only metadata. It is not part of
data, and copying that data into anRtcPacketToSenddoes not cause the received ECN marking to be applied to the packet sent bysendPackets().-
networkRoute, of type RtcNetworkRoute , readonly -
The route the packet arrived on.
6.5.
6.6.
IceServer
dictionary {IceServerInit required DOMString url ;DOMString username ;DOMString credentials ; };
-
url, of type DOMString -
The URL of the ICE server.
-
username, of type DOMString -
The username used for credential verification.
-
credentials, of type DOMString -
The credentials for authentication.
[Exposed =(Window ,Worker )]interface {IceServer readonly attribute DOMString url ;readonly attribute DOMString username ;readonly attribute DOMString credentials ; };
-
url, of type DOMString , readonly -
The URL of the ICE server.
-
username, of type DOMString , readonly -
The username used for credential verification.
-
credentials, of type DOMString , readonly -
The credentials for authentication.
6.6.
6.7.
IceCandidateType
enum {IceCandidateType "host" ,"srflx" ,"prflx" ,"relay" };
-
"host" -
Host candidate.
-
"srflx" -
Server reflexive candidate.
-
"prflx" -
Peer reflexive candidate.
-
"relay" -
Relay candidate.
6.7.
6.8.
LocalIceCandidate
[Exposed =(Window ,Worker )]interface {LocalIceCandidate readonly attribute DOMString ufrag ;readonly attribute DOMString pwd ;readonly attribute DOMString address ;readonly attribute unsigned short port ;readonly attribute IceCandidateType type ;readonly attribute unsigned short networkCost ; };
6.7.1.
6.8.1.
Internal
slots
A
LocalIceCandidate
object
has
the
following
internal
slots.
| Internal Slot | Description ( non-normative ) |
|---|---|
[[SourceServer]]
|
The
IceServer
dictionary
used
to
discover
this
candidate,
if
it
is
a
server
reflexive
candidate,
and
undefined
otherwise.
|
[[NetworkInterface]]
| The dynamic system network interface this candidate is bound to. |
[[RelayAllocationLifetime]]
|
An
unsigned
long
representing
the
TURN
allocation
lifetime
in
seconds
if
this
is
a
relay
candidate,
and
undefined
otherwise.
|
[[AssociatedController]]
|
The
ICE
controller
instance
(either
RtcManualIceController
or
RtcAutomaticIceController
)
that
created
this
candidate.
|
6.7.2.
6.8.2.
Instantiation
When
a
new
LocalIceCandidate
object
is
created,
the
user
agent
MUST
run
the
following
steps:
-
Let candidate be a new
LocalIceCandidateobject. -
Set candidate ’s
[[SourceServer]]internal slot toundefined. -
Set candidate ’s
[[NetworkInterface]]internal slot toundefined. -
Set candidate ’s
[[RelayAllocationLifetime]]internal slot toundefined. -
Set candidate ’s
[[AssociatedController]]internal slot toundefined. -
Return candidate .
-
ufrag, of type DOMString , readonly -
ICE user fragment.
-
pwd, of type DOMString , readonly -
ICE password.
-
address, of type DOMString , readonly -
IP Address of the candidate.
-
port, of type unsigned short , readonly -
Port of the candidate.
-
type, of type IceCandidateType , readonly -
The candidate type.
-
networkCost, of type unsigned short , readonly -
The costs associated with network route utilization.
6.8.
6.9.
RemoteIceCandidate
[Exposed =(Window ,Worker )]interface {RemoteIceCandidate readonly attribute DOMString ufrag ;readonly attribute DOMString pwd ;readonly attribute DOMString address ;readonly attribute unsigned short port ;readonly attribute IceCandidateType type ;readonly attribute unsigned short networkCost ; };
-
ufrag, of type DOMString , readonly -
Remote ICE user fragment.
-
pwd, of type DOMString , readonly -
Remote ICE password.
-
address, of type DOMString , readonly -
Remote IP Address of the candidate.
-
port, of type unsigned short , readonly -
Remote Port of the candidate.
-
type, of type IceCandidateType , readonly -
The remote candidate type.
-
networkCost, of type unsigned short , readonly -
The remote costs associated with network route utilization.
[Exposed =(Window ,Worker )]dictionary {RemoteIceCandidateInit required DOMString ufrag ;required DOMString pwd ;required DOMString address ;required unsigned short port ;required IceCandidateType type ;unsigned short networkCost ; };
-
ufrag, of type DOMString -
Remote ICE user fragment.
-
pwd, of type DOMString -
Remote ICE password.
-
address, of type DOMString -
Remote IP Address of the candidate.
-
port, of type unsigned short -
Remote Port of the candidate.
-
type, of type IceCandidateType -
The remote candidate type.
-
networkCost, of type unsigned short -
The remote costs associated with network route utilization.
6.9.
6.10.
IceCandidatePair
[Exposed =(Window ,Worker )]interface {IceCandidatePair readonly attribute LocalIceCandidate localCandidate ;readonly attribute RemoteIceCandidate remoteCandidate ; };
6.9.1.
6.10.1.
Internal
slots
An
IceCandidatePair
object
has
the
following
internal
slots.
| Internal Slot | Description ( non-normative ) |
|---|---|
[[LocalCandidate]]
| The local candidate associated with this pair. |
[[RemoteCandidate]]
| The remote candidate associated with this pair. |
[[AssociatedController]]
|
The
ICE
controller
instance
(either
RtcManualIceController
or
RtcAutomaticIceController
)
that
created
this
pair.
|
6.9.2.
6.10.2.
Instantiation
When
a
new
IceCandidatePair
object
is
created,
the
user
agent
MUST
run
the
following
steps:
-
Let pair be a new
IceCandidatePairobject. -
Set pair ’s
[[LocalCandidate]]internal slot toundefined. -
Set pair ’s
[[RemoteCandidate]]internal slot toundefined. -
Set pair ’s
[[AssociatedController]]internal slot toundefined. -
Return pair .
6.9.3.
6.10.3.
Attributes
-
localCandidate, of type LocalIceCandidate , readonly -
Returns the value of this
IceCandidatePair’s[[LocalCandidate]]internal slot. -
remoteCandidate, of type RemoteIceCandidate , readonly -
Returns the value of this
IceCandidatePair’s[[RemoteCandidate]]internal slot.
6.10.
6.11.
IceCandidateGatheredEvent
[Exposed =(Window ,Worker )]interface :IceCandidateGatheredEvent Event {readonly attribute (DOMString or IceServer or RemoteIceCandidate )source ;readonly attribute LocalIceCandidate candidate ;readonly attribute unsigned long networkCost ;readonly attribute unsigned long ?allocationLifetime ; };
-
source, of type(DOMString or IceServer or RemoteIceCandidate), readonly -
Gathering source descriptor.
-
candidate, of type LocalIceCandidate , readonly -
The gathered candidate.
-
networkCost, of type unsigned long , readonly -
Costs of the network utilized.
-
allocationLifetime, of type unsigned long , readonly, nullable -
Lifetime of allocation granted by allocation servers.
6.11.
6.12.
IceProbeResult
dictionary {IceProbeResult required boolean success ;DOMHighResTimeStamp rtt ; };
-
success, of type boolean -
A boolean indicating whether the route probe check succeeded (received a STUN response).
-
rtt, of type DOMHighResTimeStamp -
Round-trip time discovered by the probe in milliseconds. Only present if
successistrue.
6.12.
6.13.
Type
Definitions
and
Rest
Enums
typedef (RtcManualIceController or RtcAutomaticIceController );RtcNetworkRouteController typedef IceCandidatePair ;RtcNetworkRoute enum {RtcTransportFormat "ICE-DTLS/V0" };enum {RtcNetworkRouteControllerType "automaticIceController" ,"manualIceController" };
- RtcNetworkRouteController
-
Union type describing the underlying ICE route controller.
- RtcNetworkRoute
-
Underlying network route identifier.
-
"ICE-DTLS/V0" -
Wire format utilizing ICE for connection establishment and DTLS as a wire format with Transport Header iteration version 0.
-
"automaticIceController" -
Automatically managed ICE candidates route controller.
-
"manualIceController" -
Manually managed ICE candidates route controller.
7. Security and Privacy Considerations
7.1. Network Route Exposure
Exposing local IP addresses (including private ones) via ICE candidates poses a severe privacy risk. Mitigations should include permission prompts or limiting access to mDNS addresses unless permissions are explicitly granted by the user.7.2. Circuit Breaker
The
ontransportstatus
event
signals
that
a
circuit-breaker
mechanism
is
present.
Implementations
MUST
shut
down
the
transport
if
they
detect
excessive
congestion
or
abusive
behavior
to
protect
the
integrity
of
network
paths.
7.3. Encryption
The transport MUST be encrypted. Chosen formats like
"ICE-DTLS/V0"
mandate
explicit
full-time
encryption
in
flight.
The
specification
requires
full
secure
transport.
7.4. Buffer Overflows
The
onerror
event
mitigates
buffer
overflows
across
implementation
tiers.
Limits
must
be
defined
to
guarantee
bounds
on
memory
allocations,
preventing
standard
memory-exhaustion
vectors.