RFC 8864
Negotiation Data Channels Using the Session Description Protocol (SDP)
RFC 8864: Negotiation Data Channels Using SDP π¦
okay bestie, this one is RFC 8864, titled Negotiation Data Channels Using the Session Description Protocol (SDP) β¨. It's a Standards Track document from the IETF, which means it's an actual Internet standard and not just a suggestion. It was published in January 2021 and has ISSN 2070-1721. The authors are K. Drage, M. Makaraju, R. Ejzak, J. Marcon (listed as Unaffiliated), and R. Even, who is the editor (Ed.). The title block doesn't list any RFCs that it obsoletes or updates, so this one is standing on its own π .
Abstract β¨
okay so, data channel setup can happen in two ways: in-band with DCEP (Data Channel Establishment Protocol), or out-of-band with some non-DCEP protocol π«Ά. This document explains how the SDP offer/answer exchange can be used to do that out-of-band non-DCEP negotiation for setting up a data channel. it's giving "pick your own vibe" energy π
Status of This Memo
this part is the official paperwork π. The document is an Internet Standards Track document and a product of the IETF. It represents the consensus of the IETF community, got public review, and was approved by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check Section 2 of RFC 7841. For the current status, any errata, and how to give feedback, go to https://www.rfc-editor.org/info/rfc8864 π.
Copyright Notice
Copyright (c) 2021 IETF Trust and the persons identified as the document authors. All rights reserved π. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, which are at https://trustee.ietf.org/license-info and were in effect on the publication date. Please actually read these, because they describe your rights and restrictions. Code components pulled out of this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as the Simplified BSD License describes.
Table of Contents π
1. Introduction
2. Conventions
3. Terminology
4. Applicability Statement
5. SDP Data Channel Attributes
5.1. SDP DCMAP Attribute
5.1.1. DCMAP Attribute Syntax
5.1.2. 'dcmap-stream-id' Parameter
5.1.3. 'label' Parameter
5.1.4. 'subprotocol' Parameter
5.1.5. 'max-retr' Parameter
5.1.6. 'max-time' Parameter
5.1.7. 'ordered' Parameter
5.1.8. 'priority' Parameter
5.1.9. DCMAP Multiplexing Category
5.2. SDP DCSA Attribute
5.2.1. DCSA Attribute Syntax
5.2.2. DCSA Multiplexing Category
6. SDP Offer/Answer Procedures
6.1. Managing Stream Identifiers
6.2. Negotiating Data Channel Parameters
6.3. Generating the Initial Offer for a Data Channel
6.4. Generating the SDP Answer
6.5. Offerer Processing of the SDP Answer
6.6. Modifying the Session
6.6.1. Closing a Data Channel
6.7. Various SDP Offer/Answer Considerations
7. Examples
8. Security Considerations
9. IANA Considerations
9.1. Subprotocol Identifiers
9.2. New SDP Attributes
9.2.1. dcmap
9.2.2. dcsa
9.3. Registering Attributes for Use with Data Channels
10. References
10.1. Normative References
10.2. Informative References
Appendix A. Generic Data Channel Negotiation Aspects when Not
Using DCEP
A.1. Stream Identifier Numbering
A.2. Generic Data Channel Negotiation Not Using DCEP
A.2.1. Overview
A.2.2. Opening a Data Channel
A.2.3. Closing a Data Channel
Acknowledgements
Contributors
Authors' Addresses
1. Introduction πΈ
okay so, a bidirectional data channel that runs on top of SCTP (the Stream Control Transmission Protocol) is covered in [RFC8831], and that's what lets applications use data channels π. The in-band DCEP is described in [RFC8832], but honestly other in-band or out-of-band protocols can also set up data channels π. Every data channel is a pair of SCTP streams that share the same SCTP Stream Identifier.
Apps create data channels in one of two ways: (1) the WebRTC API (Application Programming Interface) [WebRtcAPI], or (2) other protocols, like Controlling Multiple Streams for Telepresence (CLUE) [RFC8850] π§. The protocol gets signaled with the data channel 'subprotocol' parameter, which is kinda like a WebSocket subprotocol from [RFC6455] π₯. The main thing is that besides the "subprotocol" value that gets sent to the peer, the two endpoint applications can agree on how to start up a given subprotocol on a data channel. They can also agree on whether it gets signaled in-band with DCEP, out-of-band with a non-DCEP protocol, or both π.
This document defines the SDP (Session Description Protocol) offer/answer procedures from [RFC3264] π
. These procedures make out-of-band negotiation possible for setting up data channels that carry well-defined subprotocols. They're based on the general SDP offer/answer rules for SCTP-based media transport in [RFC8841], for the SDP m= line proto values UDP/DTLS/SCTP and TCP/DTLS/SCTP β¨.
This document uses MSRP (the Message Session Relay Protocol) [RFC4975] and BFCP (the Binary Floor Control Protocol) [RFC8855] in a few examples π¦. It does NOT give a complete spec for negotiating a data channel that carries MSRP, though. Each subprotocol's own procedures would need to be written up somewhere else. For MSRP, that's [RFC8873]. The MSRP examples are only there to show how the general procedures might apply to one specific subprotocol π.
2. Conventions π
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174], but only when they show up in all capitals, exactly like that π. Anywhere else, they're just regular words, no special powers π.
3. Terminology π
okay, here are the terms this document uses, and I'm obsessed with how precise they are π€.
Data channel: A WebRTC data channel, as specified in [RFC8831].
Data channel stack: An entity that runs the data channel protocol when an application asks it to. It keeps track of states, plus sending and receiving data. If the application is a browser-based JavaScript app, the stack lives in the browser. If it's a native app, the stack lives in the app and you reach it through some kind of API or APIs π.
Data channel properties: Fixed properties given to a data channel when it gets created. Some of them decide how the data channel stack sends data on that channel, like the stream identifier, reliability, and order of delivery β¨.
Data channel subprotocol: The application protocol carried over one data channel. Subprotocol messages get sent as data channel payload over an established data channel. An SDP offer/answer exchange, as specified in this document, can negotiate setting up data channels, their properties, the subprotocols attached to them, and the subprotocol properties π. When that happens, the data channel subprotocols can be identified by the values of the 'subprotocol' parameters of the SDP a=dcmap: attribute, described in Section 5.1.4. Inside this document, "data channel subprotocol" usually gets shortened to just "subprotocol" π«Ά.
DCEP: Data Channel Establishment Protocol, as defined in [RFC8832] π οΈ.
In-band: Transmission through the peer-to-peer SCTP association π.
Out-of-band: Transmission through the application signaling path π‘.
Peer: From the point of view of one agent in a session, its peer is the other agent. So from the SDP offerer's point of view, the peer is the SDP answerer. And from the SDP answerer's point of view, the peer is the SDP offerer π―.
SCTP Stream Sequence Number (SSN): The SCTP Stream Sequence Number, as specified in [RFC4960] π§Ύ.
Stream identifier: The identifier of the outbound and inbound SCTP streams that make up a data channel π.
4. Applicability Statement π¦
This mechanism only applies to SDP [RFC8866] when it's used together with the SDP offer/answer mechanism [RFC3264]. Declarative usage of SDP is out of scope for this document, so it's undefined here π ββοΈ.
5. SDP Data Channel Attributes π
This section defines two new SDP media-level attributes. You can use them with the SDP Offer/Answer mechanism to negotiate data-channel-specific and subprotocol-specific parameters, and you don't need DCEP [RFC8832] for that π. The first attribute (Section 5.1) negotiates channel-specific parameters. The second attribute (Section 5.2) negotiates subprotocol-specific parameters β¨.
Note: Appendix A explains how data channels work in general. It also sums up some key things to think about when negotiating data channels without DCEP, so go peek if that's you π.
5.1. SDP DCMAP Attribute πΊοΈ
This section defines a new media-level attribute, a=dcmap:, which sets the data channel parameters for each data channel being negotiated π§.
This attribute is used to create bidirectional SCTP data channels that all have the same set of attributes. The data channel properties (reliable, partially reliable, ordered, or unordered) need to suit the subprotocol's transport requirements, so pick wisely, bestie π .
to be continued... part 2 is where the DCMAP syntax and its parameters show up, and it gets SO good π¦π
5.1.1. DCMAP Attribute Syntax π
Okay bestie, so a=dcmap: is a media-level attribute, and its definition and ABNF syntax come from [RFC5234] (yes, the ABNF one π
). Here's the whole attribute at a glance:
+=================================+
| "a=dcmap:" Attribute |
+===================+=============+
| Name | dcmap |
+-------------------+-------------+
| Value | dcmap-value |
+-------------------+-------------+
| Usage Level | media |
+-------------------+-------------+
| Charset Dependent | No |
+-------------------+-------------+
Table 1: "a=dcmap:" Attribute
Definition
Now the formal syntax, which is giving precise and kind of iconic π₯:
dcmap-value = dcmap-stream-id
[ SP dcmap-opt *(";" dcmap-opt) ]
dcmap-opt = ordering-opt / subprotocol-opt / label-opt
/ maxretr-opt / maxtime-opt / priority-opt
; maxretr-opt and maxtime-opt are
; mutually exclusive
dcmap-stream-id = 1*5DIGIT
ordering-opt = "ordered=" ordering-value
ordering-value = "true" / "false"
subprotocol-opt = "subprotocol=" quoted-string
label-opt = "label=" quoted-string
maxretr-opt = "max-retr=" maxretr-value
maxretr-value = "0" / integer
; number of retransmissions,
; less than 2^32,
; derived from 'Reliability Parameter' [RFC8832]
maxtime-opt = "max-time=" maxtime-value
maxtime-value = "0" / integer
; milliseconds,
; less than 2^32,
; derived from 'Reliability Parameter' [RFC8832]
priority-opt = "priority=" priority-value
priority-value = "0" / integer
; unsigned integer value indicating the priority of
; the data channel,
; less than 2^16,
; derived from 'Priority' [RFC8832]
quoted-string = DQUOTE *(quoted-char / escaped-char) DQUOTE
quoted-char = SP / quoted-visible
quoted-visible = %x21 / %x23-24 / %x26-7E ; VCHAR without " or %
escaped-char = "%" HEXDIG HEXDIG
DQUOTE = <from RFC 5234>
integer = <from RFC 8866>
And some examples to vibe check π§:
a=dcmap:0
a=dcmap:1 subprotocol="bfcp";max-time=60000;priority=512
a=dcmap:2 subprotocol="msrp";ordered=true;label="msrp"
a=dcmap:3 label="Label 1";ordered=false;max-retr=5;priority=128
a=dcmap:4 label="foo%09bar";ordered=true;max-time=15000
Note: The last example (a=dcmap:4) has alabelvalue with one nonprintableescaped-charin it, which is the tab character (%09). Slay the detail π
Okay, real talk on the rules: on a single a=dcmap: line, only one max-retr parameter or one max-time parameter can show up, not both. They MUST NOT be present together π«
5.1.2. 'dcmap-stream-id' Parameter π¦
So dcmap-stream-id is the SCTP stream identifier inside the SCTP association that gets used to form the data channel. It's basically the channel's address in the SCTP association π
5.1.3. 'label' Parameter π·οΈ
The label parameter is the name of the channel. In the context of the WebRTC API [WebRtcAPI], it's what lets you tell one RTCDataChannel object apart from another RTCDataChannel object. It maps to the 'Label' parameter defined in [RFC8832]. label is optional, and if it's not there, its value defaults to the empty string π
When it's time to talk to the WebRTC API, the label parameter should:
- Serialize the WebRTC label as a UTF-8 string [RFC3629].
- Treat the UTF-8 serialization as a series of bytes.
- For each byte in the serialization,
- If the byte can be expressed as a 'quoted-char', do so.
- Otherwise, express the byte as an 'escaped-char'.
Note: The empty string can also be used on purpose as alabelvalue, solabel=""means the same thing as not including thelabelparameter at all. [RFC8832] lets the DATA_CHANNEL_OPEN message's 'Label' value be an empty string, so it's all valid π
5.1.4. 'subprotocol' Parameter π§
The subprotocol parameter says which protocol the client expects to exchange over the channel. It maps to the 'Protocol' parameter defined in [RFC8832]. Section 9.1 explains how values for new subprotocol parameters get registered. subprotocol is optional, and if it's missing, its value defaults to an empty string β¨
Note: The empty string can also be used on purpose as asubprotocolvalue, sosubprotocol=""means the same thing as not including thesubprotocolparameter at all. [RFC8832] lets the DATA_CHANNEL_OPEN message's 'Protocol' value be an empty string.
5.1.5. 'max-retr' Parameter π
This parameter tells you the data channel is partially reliable π«Ά The max-retr parameter is the maximum number of times a user message gets retransmitted. It's optional. If max-retr and max-time are both absent, reliable transmission happens as specified in [RFC4960]. This parameter maps to the 'Number of RTX' parameter defined in [RFC8832].
5.1.6. 'max-time' Parameter β³
Also partially reliable, bestie π¦ A user message stops being transmitted or retransmitted once its lifetime runs out. The lifetime is given in milliseconds in the max-time parameter, and it starts counting when the user message is handed to the protocol stack. max-time is optional. If max-retr and max-time are both absent, reliable transmission happens as specified in [RFC4960]. This parameter maps to the 'Lifetime in ms' parameter defined in [RFC8832].
5.1.7. 'ordered' Parameter π¬
When ordered has the value "true", the receiver passes DATA chunks in the data channel up to the upper layer while keeping their order π§ ordered is optional and has two values: "true" for ordered delivery and "false" for unordered delivery. The default is "true". Any other value gets ignored, and then "ordered=true" is assumed. If the parameter isn't there at all, "ordered=true" is also assumed. This parameter maps to the ordered or unordered data channel types defined in [RFC8832].
5.1.8. 'priority' Parameter π
The priority parameter shows the data channel's priority compared to other data channels, which might also exist over the same SCTP association. It maps to the 'Priority' parameter defined in [RFC8832]. priority is optional. If it's not there, "priority=256" is assumed π
5.1.9. DCMAP Multiplexing Category π
The multiplexing category [RFC8859] of the a=dcmap: attribute is SPECIAL, which is a whole vibe π
Using multiple SCTP associations on top of a single DTLS association is outside the scope of [RFC8841]. Because of that, no a=dcmap: multiplexing rules are specified for the UDP/DTLS/SCTP and TCP/DTLS/SCTP proto values. If future extensions of [RFC8841] define how to negotiate multiplexing of multiple SCTP associations on top of a single DTLS association, or how to add multiple SCTP associations to one BUNDLE group, then multiplexing rules for the a=dcmap: attribute need to be defined as well. For instance, that could happen in an extension of this specification π
5.2. SDP DCSA Attribute π§ββοΈ
In the SDP media description, each data channel declaration MAY also be followed by other SDP attributes. These apply to the matching data channel and its subprotocol. Each one is represented by a new a=dcsa: attribute line that references another SDP attribute defined for use with this data channel's subprotocol. Instructions for registering attributes for use with a data channel are in Section 9.3 β¨
Any SDP attribute that's related to the subprotocol and would normally be used to negotiate it through the SDP offer/answer mechanism gets replaced with an attribute of the form a=dcsa:stream-id original-attribute. Here dcsa stands for "data channel subprotocol attribute", stream-id is the SCTP stream identifier assigned to this subprotocol instance, and original-attribute holds the contents of the subprotocol-related attribute being included.
The same syntax applies to any other SDP attribute needed to negotiate this instance of the subprotocol π«§
The detailed offer/answer procedures for the dcsa attribute depend on the associated subprotocol. If no offer/answer procedures exist for the subprotocol when it's used outside of the dcsa attribute, nothing needs to be specified for use with dcsa. The IANA (Internet Assigned Numbers Authority) registration procedures for the "WebSocket Subprotocol Name Registry" (Section 9.1) don't strictly require a specification of the offer/answer procedures for the subprotocol when it's used with dcsa. If the subprotocol has defined offer/answer procedures when used outside of dcsa, such a specification is encouraged to keep things interoperable π€ If the subprotocol has defined offer/answer procedures outside of dcsa but there's no specification for them when used with dcsa, implementations SHOULD assume the default values for all otherwise-negotiable and applicable subprotocol parameters π
5.2.1. DCSA Attribute Syntax β¨
okay so this is where the a=dcsa: attribute gets its grammar π it's a media-level attribute, and the ABNF is defined using [RFC5234] π
Here's the whole vibe in one table, bestie π¦
+================================+
| "a=dcsa:" Attribute |
+===================+============+
| Name | dcsa |
+-------------------+------------+
| Value | dcsa-value |
+-------------------+------------+
| Usage Level | media |
+-------------------+------------+
| Charset Dependent | No |
+-------------------+------------+
Table 2: "a=dcsa:" Attribute
Definition
The formal syntax is literally just this πΈ
dcsa-value = stream-id SP attribute
stream-id = 1*5DIGIT
attribute = <from RFC 8866>
and here's an example that makes it click π
a=dcmap:2 subprotocol="msrp";ordered=true;label="msrp"
a=dcsa:2 accept-types:text/plain
So the [RFC8866] reference just tells you where the attribute definition lives, it doesn't limit support for attributes defined in other documents that follow this format π§ BUT not every SDP attribute is suitable to go inside a dcsa π The IANA SDP parameters registry has the lists of session-level and media-level (or media-level-only) attributes, so check there π
In the example, the original a=accept-types:text/plain becomes a=dcsa:2 accept-types:text/plain, which says this instance of the MSRP subprotocol, carried over the SCTP association on the data channel with stream id 2, accepts plaintext files π
Here's the big difference from the a=dcmap: parameters: these ones are subject to offer/answer negotiation, following the procedures in the subprotocol-specific documents π₯
It's assumed that subprotocol-related media-level attributes are generally independent of the subprotocol's transport protocol π«Ά So those transport-independent attributes get used exactly the same way as in the original subprotocol spec, even when the subprotocol runs over a data channel and the attribute is wrapped in a dcsa π
There may be cases where the usage does depend on the transport protocol π In that case, the data-channel usage is expected to be described for the data channel transport. A data-channel-specific usage is expected to be specified in the same document that registers the subprotocol's identifier for data channel usage, as described in Section 9.1 β¨
5.2.2. DCSA Multiplexing Category β
The multiplexing category of the a=dcsa: attribute is SPECIAL π¦
Since using multiple SCTP associations on top of a single DTLS association is outside the scope of [RFC8841], there are no a=dcsa: multiplexing rules for the UDP/DTLS/SCTP and TCP/DTLS/SCTP proto values π If future extensions of [RFC8841] define how to negotiate multiplexing of multiple SCTP associations on one DTLS association, or how to add multiple SCTP associations to one BUNDLE group, then multiplexing rules for a=dcsa: will need to be defined too, for instance in an extension of this specification π
6. SDP Offer/Answer Procedures π
okay this section is where the actual negotiation choreography happens π
A single media description can describe multiple data channels (each one gets its own SDP dcmap attribute), and they can be created, modified, and closed across different offer/answer exchanges π¦ The procedures here apply to one given data channel at a time πΈ
The generic offer/answer procedures for negotiating the SCTP association are defined in [RFC8841], and this section only covers the data-channel-specific bits π§
"Initial offer" refers to the offer where a data channel gets opened. It can be either the initial offer or a subsequent offer of the associated SDP session π
The detailed offer/answer procedures for the dcsa attribute depend on the associated subprotocol, so see Section 5.2 π«Ά
6.1. Managing Stream Identifiers π₯
To avoid SCTP stream identifier collisions, in alignment with [RFC8832], the endpoint acting as a DTLS client (for the SCTP association used to realize data channels) MUST use even identifier values, and the endpoint acting as a DTLS server MUST use odd identifier values π
SCTP stream identifiers tied to data channels negotiated using DCEP MUST NOT be included in SDP offers and answers π
6.2. Negotiating Data Channel Parameters π
The data channel types defined in [RFC8832] map to the dcmap SDP attribute parameters like this, where ordered=true is the default and can be left out π
DATA_CHANNEL_RELIABLE
ordered=true
DATA_CHANNEL_RELIABLE_UNORDERED
ordered=false
DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT
ordered=true;max-retr=<number of retransmissions>
DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT_UNORDERED
ordered=false;max-retr=<number of retransmissions>
DATA_CHANNEL_PARTIAL_RELIABLE_TIMED
ordered=true;max-time=<lifetime in milliseconds>
DATA_CHANNEL_PARTIAL_RELIABLE_TIMED_UNORDERED
ordered=false;max-time=<lifetime in milliseconds>
By definition, max-retr and max-time are mutually exclusive, so both MUST NOT be present in the a=dcmap: attribute line π
ββοΈ If an SDP offer contains both, the receiver MUST reject that offer. If an SDP answer contains both, the offerer MUST treat the associated offer/answer as failed π
6.3. Generating the Initial Offer for a Data Channel π
When an offerer sends an initial offer to negotiate an SCTP stream for a data channel, the offerer:
- SHALL include an SDP
dcmapattribute (Sections 5.1 and 6.2) associated with the data channel in them=section representing the SCTP association used to realize the data channel, and - MAY include one or more SDP
dcsaattributes (Section 5.2) associated with the data channel. The value of the 'stream-id' part of each attribute SHALL match the 'dcmap-stream-id' value of thedcmapattribute π§
6.4. Generating the SDP Answer π¦
When an answerer gets an offer with an m= section for an SCTP association, and the offer describes an SCTP stream for a data channel, and the answerer accepts that data channel, it:
- SHALL include an SDP
dcmapattribute (Sections 5.1 and 6.2) associated with the data channel in them=section representing the SCTP association used to realize the data channel. The values of the 'dcmap-stream-id', 'max-retr', and 'max-time' in thedcmapattribute SHALL be identical to the values used for the data channel in the offer, and - MAY include one or more SDP
dcsaattributes (Section 5.2) associated with the data channel π
6.5. Offerer Processing of the SDP Answer π
An offerer receiving an SDP answer does the following:
- It SHALL close any created data channels, as described in Section 6.6.1, for which the expected
a=dcmap:attributes are not present in the SDP answer. If the SDP answer has noa=dcmap:attributes, then either the peer doesn't support them or it rejected all the data channels. Either way, the offerer closes all the data channels offered by SDP that were open at the time of the offer π The DTLS association and SCTP association will still be set up. At this point, the offerer MAY use DCEP negotiation [RFC8832] to open data channels πΈ
Each agent application MUST wait to send data until it has confirmation that the data channel at the peer is instantiated. For WebRTC, that's when both data channel stacks have channel parameters instantiated, and it happens like this:
- At both peers, when a data channel is created without a previously established SCTP association, as soon as the SCTP association is successfully established π₯
- At the agent receiving an SDP offer for which there is an established SCTP association, as soon as it creates the negotiated data channel based on the information in the SDP offer π«Ά
- At the agent sending an SDP offer to create a new data channel for which there is an established SCTP association, when it receives the SDP answer confirming acceptance of the data channel, or when it starts receiving data on the data channel from the peer, whichever comes first π
6.6. Modifying the Session π
When an offerer sends a subsequent offer that includes information for a previously negotiated data channel, unless the offerer intends to close that data channel (Section 6.6.1), the offerer SHALL include the previously negotiated SDP attributes and attribute values associated with the data channel. The answerer MAY reject the offer. How rejection works depends on the higher-layer protocol. The offer/answer exchange is atomic: if the answer is rejected, the session reverts to the state it was in before the offer [RFC3264] π§
6.6.1. Closing a Data Channel π
To close a data channel, the endpoint that wants to close it SHALL send an SCTP SSN Reset message [RFC6525], following the procedure in Section 6.7 of [RFC8831]. On top of that, if the closed data channel was negotiated using the offer/answer mechanism (Section 6.3), the endpoint that closed it SHALL send a subsequent offer that does one of the following:
- Removes the SDP
dcmapattribute and SDPdcsaattributes associated with the closed data channel. Once the endpoint gets a successful answer, the SCTP stream identifier value can later be used for a new data channel (negotiated using either SCTP or the offer/answer mechanism), or - After a reset has been performed, reuses the SCTP stream used for the closed data channel for a new data channel, following the procedure in Section 6.3. The offerer SHALL use a different SDP
dcmapattribute value for the data channel using the same SCTP stream π
6.7. Various SDP Offer/Answer Considerations π
If an SDP offer or answer has no a=dcmap: attributes but does have a=dcsa: attributes, that's an error case π In this case, the receiver of such an offer or answer MUST discard the a=dcsa: attributes.
If an SDP offer or answer has an a=dcsa: attribute whose subprotocol attribute is unknown, the receiver of that offer or answer SHOULD ignore this entire a=dcsa: attribute line π¦
If an SDP offer or answer has an a=dcsa: attribute whose subprotocol attribute is known, but whose subprotocol attribute semantic isn't known for the data channel transport case, the receiver of that offer or answer SHOULD ignore this entire a=dcsa: attribute line πΈ
7. Examples π
Okay bestie, Figure 1 is the one where the SDP answerer says "nope" to the data channel with stream id 0. Maybe it's a deliberate no, or maybe it just doesn't understand the a=dcmap: attribute π. Either way the offerer closes that channel. The SCTP association still gets set up over DTLS β¨, and after that the offerer or the answerer can use DCEP negotiation to open channels π¦.
m=application 10001 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP6 2001:db8::3
a=max-message-size:100000
a=sctp-port:5000
a=setup:actpass
a=fingerprint:SHA-1 \
4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB
a=tls-id:abc3de65cddef001be82
a=dcmap:0 subprotocol="bfcp";label="bfcp"
m=application 10002 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP6 2001:db8::1
a=max-message-size:100000
a=sctp-port:5002
a=setup:passive
a=fingerprint:SHA-1 \
5B:AD:67:B1:3E:82:AC:3B:90:02:B1:DF:12:5D:CA:6B:3F:E5:54:FA
a=tls-id:dcb3ae65cddef0532d42
Figure 1: Example 1
Figure 2 is the one with a little drama π . The offer has data channels for both BFCP and MSRP. The answer says no to BFCP and yes to MSRP. So the offerer closes the BFCP channel, and once the SCTP association is up, both sides can start using the MSRP channel π. Stream id 0 is now free for future DCEP or SDP offer/answer negotiation.
m=application 10001 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 192.0.2.1
a=max-message-size:100000
a=sctp-port:5000
a=setup:actpass
a=fingerprint:SHA-1 \
4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB
a=tls-id:abc3de65cddef001be82
a=dcmap:0 subprotocol="bfcp";label="bfcp"
a=dcmap:2 subprotocol="msrp";label="msrp"
a=dcsa:2 accept-types:message/cpim text/plain
a=dcsa:2 path:msrp://alice.example.com:10001/2s93i93idj;dc
m=application 10002 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 192.0.2.2
a=max-message-size:100000
a=sctp-port:5002
a=setup:passive
a=fingerprint:SHA-1 \
5B:AD:67:B1:3E:82:AC:3B:90:02:B1:DF:12:5D:CA:6B:3F:E5:54:FA
a=tls-id:dcb3ae65cddef0532d42
a=dcmap:2 subprotocol="msrp";label="msrp"
a=dcsa:2 accept-types:message/cpim text/plain
a=dcsa:2 path:msrp://bob.example.com:10002/si438dsaodes;dc
Figure 2: Example 2
Figure 3 picks up right where Figure 2 left off β¨. The offerer drops the MSRP channel with stream id 2 and opens a brand new MSRP channel with stream id 4 π§. The answerer accepts the whole offer, so the offerer closes the old MSRP channel, and both sides can start using the new one. Iconic glow-up π.
m=application 10001 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 192.0.2.1
a=max-message-size:100000
a=sctp-port:5000
a=setup:actpass
a=fingerprint:SHA-1 \
4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB
a=tls-id:abc3de65cddef001be82
a=dcmap:4 subprotocol="msrp";label="msrp"
a=dcsa:4 accept-types:message/cpim text/plain
a=dcsa:4 path:msrp://alice.example.com:10001/2s93i93idj;dc
m=application 10002 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 192.0.2.2
a=max-message-size:100000
a=sctp-port:5002
a=setup:passive
a=fingerprint:SHA-1 \
5B:AD:67:B1:3E:82:AC:3B:90:02:B1:DF:12:5D:CA:6B:3F:E5:54:FA
a=tls-id:dcb3ae65cddef0532d42
a=dcmap:4 subprotocol="msrp";label="msrp"
a=dcsa:4 accept-types:message/cpim text/plain
a=dcsa:4 path:msrp://bob.example.com:10002/si438dsaodes;dc
Figure 3: Example 3
8. Security Considerations π
Let's get serious for a sec π«Ά. This document specifies new SDP attributes that are used to negotiate data channel parameters.
These parameters get negotiated as part of opening an SCTP channel over DTLS, as specified in [RFC8841]. Every subprotocol might come with its own security considerations, and those need to be written up as part of that subprotocol's definition. Other than that, this document doesn't add any security considerations on top of the ones in [RFC8841] π.
Error cases are a big deal π. Unknown parameter values, or breaking the odd/even rule in Section 6.1, MUST be handled by closing the corresponding data channel. No exceptions, bestie.
9. IANA Considerations π
9.1. Subprotocol Identifiers
New subprotocol identifiers get registered in the existing IANA "WebSocket Subprotocol Name Registry" table π.
A line of text has been added under the title of that table, and it says:
"This table also includes subprotocol identifiers specified for usage within a WebRTC data channel."
This document (RFC 8864) has also been added to the "Reference" list for the registry.
This document doesn't assign any new values to that table, so nothing new is being added there π.
A subprotocol can be defined for data channel transport and for WebSocket transport at the same time. When that happens, the "Subprotocol Definition" and "Reference" cells in that subprotocol's row of the IANA "WebSocket Subprotocol Name Registry" table should contain two entries. One entry in each of those cells should point to the WebSocket-related subprotocol specification, and the other entry should point to the data-channel-related one β¨.
9.2. New SDP Attributes
9.2.1. dcmap
This document defines a brand new SDP media-level attribute, a=dcmap:, and here's how it's registered π¦:
+==================================================================+
| "a=dcmap:" |
+=====================+============================================+
| Contact name | IESG |
+---------------------+--------------------------------------------+
| Contact email | iesg@ietf.org |
+---------------------+--------------------------------------------+
| Attribute name | dcmap |
+---------------------+--------------------------------------------+
| Attribute syntax | As per Section 5.1.1 |
+---------------------+--------------------------------------------+
| Attribute semantics | As per Section 5.1.1 |
+---------------------+--------------------------------------------+
| Usage level | media |
+---------------------+--------------------------------------------+
| Charset dependent | No |
+---------------------+--------------------------------------------+
| Purpose | To define data-channel-specific parameters |
+---------------------+--------------------------------------------+
| Appropriate values | As per Section 5.1.1 |
+---------------------+--------------------------------------------+
| O/A procedures | SDP offer/answer procedures as per |
| | Section 6 |
+---------------------+--------------------------------------------+
| Mux category | SPECIAL. See Section 5.1.9 |
+---------------------+--------------------------------------------+
| Reference | RFC 8864 |
+---------------------+--------------------------------------------+
Table 3: New "a=dcmap:" Attribute
9.2.2. dcsa
This document also defines a new SDP media-level attribute, a=dcsa: π. Check out the registration details:
+=============================================================+
| "a=dcsa:" |
+=====================+=======================================+
| Contact name | IESG |
+---------------------+---------------------------------------+
| Contact email | iesg@ietf.org |
+---------------------+---------------------------------------+
| Attribute name | dcsa |
+---------------------+---------------------------------------+
| Attribute syntax | As per Section 5.2.1 |
+---------------------+---------------------------------------+
| Attribute semantics | As per Section 5.2.1 |
+---------------------+---------------------------------------+
| Usage level | media |
+---------------------+---------------------------------------+
| Charset dependent | No |
+---------------------+---------------------------------------+
| Purpose | To define attributes that are |
| | specific to data channel subprotocols |
+---------------------+---------------------------------------+
| Appropriate values | As per Section 5.2.1 |
+---------------------+---------------------------------------+
| O/A procedures | SDP offer/answer procedures as per |
| | Section 6 |
+---------------------+---------------------------------------+
| Mux category | SPECIAL. See Section 5.2.2 |
+---------------------+---------------------------------------+
| Reference | RFC 8864 |
+---------------------+---------------------------------------+
Table 4: New "a=dcsa:" Attribute
9.3. Registering Attributes for Use with Data Channels
When a subprotocol gets defined for use over data channels with the SDP offer/answer mechanism, any SDP attributes that can be negotiated using a=dcsa: MUST be added to the IANA "attribute-name registry (formerly "att-field")", as specified in [RFC8866], Section 8.2.4 π
. This document also sets up new Usage Levels of the form "dcsa (foo)", where foo stands in for the subprotocol name. Documents that specify negotiation of particular subprotocols should register these Usage Levels.
IANA has updated the "attribute-name (formerly "att-field")" registry so that it points to this document πΈ.
10. References π
The reference entries weren't included in the text I was given, so I can't rewrite them without guessing. Please send that part and I'll slay it in full β¨.
10.1. Normative References π
These are the must-reads to actually understand this spec, bestie π«Ά
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>. - [RFC3264] Rosenberg, J. and H. Schulzrinne, "An Offer/Answer Model with Session Description Protocol (SDP)", RFC 3264, DOI 10.17487/RFC3264, June 2002,
<https://www.rfc-editor.org/info/rfc3264>. - [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003,
<https://www.rfc-editor.org/info/rfc3629>. - [RFC4960] Stewart, R., Ed., "Stream Control Transmission Protocol", RFC 4960, DOI 10.17487/RFC4960, September 2007,
<https://www.rfc-editor.org/info/rfc4960>. - [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008,
<https://www.rfc-editor.org/info/rfc5234>. - [RFC6525] Stewart, R., Tuexen, M., and P. Lei, "Stream Control Transmission Protocol (SCTP) Stream Reconfiguration", RFC 6525, DOI 10.17487/RFC6525, February 2012,
<https://www.rfc-editor.org/info/rfc6525>. - [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017,
<https://www.rfc-editor.org/info/rfc8174>. - [RFC8831] Jesup, R., Loreto, S., and M. TΓΌxen, "WebRTC Data Channels", RFC 8831, DOI 10.17487/RFC8831, January 2021,
<https://www.rfc-editor.org/info/rfc8831>. - [RFC8832] Jesup, R., Loreto, S., and M. TΓΌxen, "WebRTC Data Channel Establishment Protocol", RFC 8832, DOI 10.17487/RFC8832, January 2021,
<https://www.rfc-editor.org/info/rfc8832>. - [RFC8841] Holmberg, C., Shpount, R., Loreto, S., and G. Camarillo, "Session Description Protocol (SDP) Offer/Answer Procedures for Stream Control Transmission Protocol (SCTP) over Datagram Transport Layer Security (DTLS) Transport", RFC 8841, DOI 10.17487/RFC8841, January 2021,
<https://www.rfc-editor.org/info/rfc8841>. - [RFC8859] Nandakumar, S., "A Framework for Session Description Protocol (SDP) Attributes When Multiplexing", RFC 8859, DOI 10.17487/RFC8859, January 2021,
<https://www.rfc-editor.org/info/rfc8859>. - [RFC8866] Begen, A., Kyzivat, P., Perkins, C., and M. Handley, "SDP: Session Description Protocol", RFC 8866, DOI 10.17487/RFC8866, January 2021,
<https://www.rfc-editor.org/info/rfc8866>.
10.2. Informative References π¦
These ones are good background reading, but they're not required to implement this spec π
- [RFC4975] Campbell, B., Ed., Mahy, R., Ed., and C. Jennings, Ed., "The Message Session Relay Protocol (MSRP)", RFC 4975, DOI 10.17487/RFC4975, September 2007,
<https://www.rfc-editor.org/info/rfc4975>. - [RFC6455] Fette, I. and A. Melnikov, "The WebSocket Protocol", RFC 6455, DOI 10.17487/RFC6455, December 2011,
<https://www.rfc-editor.org/info/rfc6455>. - [RFC8850] Holmberg, C., "Controlling Multiple Streams for Telepresence (CLUE) Protocol Data Channel", RFC 8850, DOI 10.17487/RFC8850, January 2021,
<https://www.rfc-editor.org/info/rfc8850>. - [RFC8855] Camarillo, G., Drage, K., Kristensen, T., Ott, J., and C. Eckel, "The Binary Floor Control Protocol (BFCP)", RFC 8855, DOI 10.17487/RFC8855, January 2021,
<https://www.rfc-editor.org/info/rfc8855>. - [RFC8873] Recio, JM., Ed. and C. Holmberg, "Message Session Relay Protocol (MSRP) over Data Channels", RFC 8873, DOI 10.17487/RFC8873, January 2021,
<https://www.rfc-editor.org/info/rfc8873>. - [T38] International Telecommunication Union, "Procedures for real-time Group 3 facsimile communication over IP networks", ITU-T Recommendation T.38, November 2015,
<https://www.itu.int/rec/T-REC-T.38-201511-I/en>. - [WebRtcAPI] Jennings, C., BostrΓΆm, H., and J-I. Bruaroey, "WebRTC 1.0: Real-time Communication Between Browsers", W3C Proposed Recommendation,
<https://www.w3.org/TR/webrtc/>.
Appendix A. Generic Data Channel Negotiation Aspects when Not Using DCEP β¨
Okay so this appendix is basically a recap of how data channels work in general, plus the key stuff you should think about when you negotiate them out-of-band and skip DCEP π
A WebRTC app makes a data channel by handing over a bunch of setup params: subprotocol, label, max number of retransmissions, max retransmission time, order of delivery, and priority π The app also gets to pick whether it wants to use negotiation via DCEP [RFC8832] or negotiate data channels through the SDP offer/answer protocol.
Either way, the SDP offer the app generates follows [RFC8841]. Quick version: it has one "m=" line for the SCTP association that the data channels will run on top of πΈ
m=application 54111 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 192.0.2.1
a=max-message-size:100000
a=sctp-port:5000
a=tls-id:abc3de65cddef001be82
a=setup:actpass
a=fingerprint:SHA-1 \
4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB
Note: A WebRTC application will only use the "m=" line format "webrtc-datachannel" and will not use other formats in the "m=" line for other protocols such as T.38 [T38]. [RFC8841] supports only one SCTP association to be established on top of a DTLS association.
Note: The above SDP media description does not contain any channel-specific information.
A.1. Stream Identifier Numbering π’
No matter what kind of negotiation is happening, the app creating a data channel can either (1) pass the stream identifier into the data channel stack so it gets assigned, or (2) let the data channel stack pick one of the unused ones π
Also, to avoid glare situations [RFC3264], each endpoint can own its own exclusive set of stream identifiers. If it does that, an endpoint can only create a data channel with a stream identifier it owns π
Which endpoint owns which set is decided by convention or some other means.
Note: For data channels negotiated with DCEP, one endpoint owns by convention the even stream identifiers, whereas the other owns the odd stream identifiers, as defined in [RFC8832].
Note: For data channels negotiated via a protocol other than DCEP, no convention is defined by default.
A.2. Generic Data Channel Negotiation Not Using DCEP π«§
A.2.1. Overview
Honestly, DCEP negotiation only covers the transport parameters of a data channel. It doesn't cover subprotocol-specific parameters at all π Non-DCEP negotiation can be defined to handle more than that, like parameters specific to the subprotocol running on a particular data channel.
The procedures below are shared by every non-DCEP method, whether it's in-band (done with proprietary means over a data channel that's already open) or out-of-band (using the SDP offer/answer mechanism or some other protocol tied to the signaling channel) π¦
A.2.2. Opening a Data Channel
For non-DCEP negotiation, the endpoint application gets to fully control the stream identifier assignments. Those assignments still have to coexist with the ones the data channel stack controls for DCEP-negotiated channels (if there are any). It's the application's job to make sure stream identifiers are assigned consistently β¨
When the app asks for a new data channel through non-DCEP negotiation, the data channel stack creates it locally without sending any DATA_CHANNEL_OPEN messages in-band. Now, even if ICE (Interactive Connectivity Establishment), DTLS, and SCTP are all already done, the application can't send data on this channel until negotiation with the peer finishes π The peer has to know about the channel and accept it first. Once the peer accepts the data channel offer, it can start sending data right away. That means the offerer might receive subprotocol messages before negotiation is complete, so the app should be ready to handle them π
If the peer rejects the data channel part of the offer, it doesn't have to do anything, because the data channel was never created through the stack. The offerer, on the other hand, needs to close the data channel it opened, by calling the relevant data channel stack API procedures π₯
Also worth knowing: a data channel stack implementation might not give you any APIs to create and close data channels. Instead, the channels can just get used on the fly, by communicating through non-DCEP means or even through some local configuration or assumptions on both peers π§
Then the application negotiates the data channel properties and subprotocol properties with the peer's application, using a mechanism that isn't DCEP π
The peer then symmetrically creates a data channel with these negotiated properties. This is the only way the peer's data channel stack knows which properties to apply when it transmits data on that channel. The data channel stack must allow data channel creation with any nonconflicting stream identifier, so both peers can create the data channel with the same stream identifier π
A.2.3. Closing a Data Channel
When the app asks to close a data channel that was negotiated without DCEP, the data channel stack always does an SCTP SSN Reset for that channel π
Depending on the non-DCEP negotiation method and the subprotocol tied to the data channel, closing the channel might also be signaled to the peer through SDP offer/answer negotiation π
Acknowledgements π«Ά
The authors want to give a shoutout to Salvatore Loreto, Gonzalo Camarillo, Peter Dunkley, and Gavin Llewellyn for the ideas they borrowed from their draft documents π They also want to thank Flemming Andreasen, Christian Groves, Gunnar HellstrΓΆm, Paul Kyzivat, Jonathan Lennox, Uwe Rauschenbach, and Roman Shpount for their invaluable comments πΈ
Special thanks to Christer Holmberg for helping finish the document and cleaning up Section 6! πβ¨
Contributors π
Juergen Stoetzer-Bradler made significant contributions to this document and should be considered a coauthor π¦
Authors' Addresses π·
Keith Drage Unaffiliated Email: drageke@ntlworld.com
Maridi R. Makaraju (Raju) Unaffiliated Email: mmraju@gmail.com
Richard Ejzak Unaffiliated Email: richard.ejzak@gmail.com
Jerome Marcon Unaffiliated Email: jeromee.marcon@free.fr
Roni Even (editor) Email: ron.even.tlv@gmail.com
π¦ where this page comes from
- ietf: rfc8864 2021-01
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms