JavaScript Session Establishment Protocol (JSEP)
obsoletes
- rfc-8829 — JavaScript Session Establishment Protocol (JSEP)
Extracted elements (27)
JSEP decouples the ICE state machine from the signaling state machine because only the implementation has the necessary knowledge of candidates and transport information. This allows JSEP to accommodate both traditional self-contained SDP offers (SIP) and Trickle ICE (RFC 8838), enabling faster ICE and DTLS startup.
JSEP provides createOffer/createAnswer rather than a getCapabilities API because the latter would require every application (or a mandatory library) to generate correct session descriptions from raw capabilities. This would make even simple examples complex and force library adoption.
SDP syntax is used for session descriptions because it is widely accepted and frequently updated with new features. It is encapsulated in a SessionDescription object so that a future JSON format could be adopted without changing the API; most applications can treat SessionDescriptions as opaque blobs.
The 'max-bundle' policy from RFC 8829 was deprecated and replaced by the identically defined 'must-bundle' because some implementations had applied an earlier pre-standard definition (not marking 'm=' sections as bundle-only), causing unexpected breakage for applications relying on that behavior.
JSEP implementations must accept offers bearing legacy profile strings (RTP/AVP, RTP/AVPF, RTP/SAVP, RTP/SAVPF, and the TCP/DTLS and UDP/TLS SAVP/SAVPF variants) because some endpoints generate non-standard strings while still intending DTLS-SRTP. Generated answers must exactly match the offered profile.
The 'canTrickleIceCandidates' property returns null (SDP not yet received), true, or false. An application that compares against 'true' will attempt half-trickle on initial offers and full trickle on subsequent interactions with a Trickle ICE-compatible agent.
When communicating with a non-JSEP endpoint that does not understand 'a=imageattr', any signaled video size limits may be exceeded. The JSEP implementation MUST handle this gracefully, e.g., by discarding the oversized video.
All session descriptions handled by JSEP implementations, both local and remote, MUST indicate support for ICE (RFC 8445). Implementations MUST properly handle remote endpoints using ICE-lite and MUST properly handle remote endpoints using the older RFC 5245 version of ICE.
DTLS (RFC 6347 or RFC 9147) or DTLS-SRTP (RFC 5763) MUST be used as appropriate for the media type per RFC 8827. The SDP security descriptions mechanism for SRTP keying (RFC 4568) MUST NOT be used.
During ICE candidate policy enforcement, the JSEP implementation MUST NOT expose disallowed candidates to the application, use them for connectivity checks, or indirectly expose them via raddr/rport attributes of other candidates. The implementation MUST allow the policy to be changed mid-session.
Implementations MUST be able to accept remote descriptions that do not have the 'ice2' attribute, supporting smooth transition from RFC 5245 to RFC 8445 ICE.
JSEP implementations MUST support the 'UDP/TLS/RTP/SAVPF' and 'TCP/DTLS/RTP/SAVPF' profiles for media 'm=' sections and MUST indicate one of these profiles in each media 'm=' line they produce in an offer. The profile in any generated answer MUST exactly match the profile in the offer.
Session descriptions generated by createOffer and createAnswer MUST be immediately usable by setLocalDescription. For subsequent offers, each existing stream's SDP MUST follow the updated-offer generation process; each new stream MUST follow the initial-offer generation process.
The default BUNDLE policy MUST be 'balanced' as the best trade-off between performance and compatibility. The default RTP/RTCP multiplexing policy MUST be 'require'; implementations MAY reject attempts to set it to 'negotiate'.
The default ICE candidate policy MUST be 'all'. The default ICE candidate pool size MUST be zero (pre-gathering only occurs on application request). The bundle and RTCP-multiplexing policies MUST NOT be changed after construction of the PeerConnection.
The PeerConnection MUST be able to simultaneously support both the current and pending local descriptions (e.g., codecs in either description) from the time it enters 'have-local-offer' until a final answer or rollback is received.
When an 'a=imageattr recv' attribute is present in the remote description, the RtpSender MUST follow the specified video-size rules for each encoding. If none of the supplied imageattr attributes can be processed successfully, the encoding MUST NOT be transmitted and an error SHOULD be raised.
The 'relay' ICE candidate policy allows applications to prevent user location leakage by exposing only relay candidates to the remote peer, obfuscating location to a metro or global level depending on relay server deployment. Applications may switch from 'relay' to 'all' mid-session after the user accepts a call by triggering an ICE restart.
An IceCandidate object uses SDP 'candidate-attribute' syntax (without the 'a=' prefix) for the candidate field, plus fields for ufrag (identifying the gathering phase), an 'm=' section index, and a MID. If the MID field is present it MUST be used for identification; otherwise the 'm=' section index is used.
An RtpTransceiver controls the RTP media associated with one 'm=' section and contains one RtpSender and one RtpReceiver. It is associated with an 'm=' section when its mid property is non-null; once a session description is applied, each 'm=' section is associated with exactly one RtpTransceiver.
ICE candidate policy controls which candidates are gathered and used. The 'all' policy permits all implementation-allowed candidates; the 'relay' policy filters out non-relay candidates to reduce location leakage. The policy can be changed mid-session by triggering an ICE restart.
JSEP defines three BUNDLE policies: 'balanced' (one transport per media type, marking subsequent same-type sections bundle-only), 'max-compat' (separate transport per 'm=' section), and 'must-bundle' (single transport, all but first marked bundle-only). The 'max-bundle' policy from RFC 8829 is deprecated.
JSEP supports simulcast using RFC 8853 (a=simulcast) and RFC 8851 (a=rid). When multiple encodings are configured on an RtpSender, the 'm=' section includes an 'a=simulcast' attribute with a 'send' description listing each desired encoding and an 'a=rid' attribute per encoding to disambiguate streams.
SessionDescriptionType values are 'offer', 'pranswer', 'answer', and 'rollback'. A 'pranswer' MUST NOT result in freeing allocated resources; an 'answer' completes the exchange and SHOULD release unused resources. A 'rollback' has empty contents and transitions the state machine back to stable.
The ICE candidate pool allows the application to pre-gather candidates for a specified number of ICE components before setLocalDescription is called. The pool is only used for the first offer/answer exchange and is emptied thereafter; pre-gathering consumes STUN/TURN server resources for potentially long periods.
JSEP mandates DTLS-SRTP for all media (RFC 8827) and prohibits the SDP security descriptions keying mechanism (RFC 4568). TLS fingerprints used in DTLS are declarative and non-negotiable; lack of an 'a=fingerprint' attribute leads to negotiation failure.
JSEP defines a five-state offer/answer machine: stable, have-local-offer, have-remote-offer, have-local-pranswer, and have-remote-pranswer. Transitions are triggered by setLocalDescription and setRemoteDescription with offer, pranswer, answer, or rollback types. A rollback returns the machine to the previous stable state.