RFC 8839
Session Description Protocol (SDP) Offer/Answer Procedures for Interactive Connectivity Establishment (ICE)
RFC 8839: SDP Offer/Answer Procedures for ICE ๐
Okay bestie, let's talk about this one ๐ It's the Internet Engineering Task Force (IETF) doc that explains how Interactive Connectivity Establishment (ICE) gets handled inside Session Description Protocol (SDP) offer/answer ๐ธ Think of it as the rulebook for how two devices swap their connection options so they can finally talk to each other, no drama โจ
Here's the title block tea โ:
- Number and title: RFC 8839, "Session Description Protocol (SDP) Offer/Answer Procedures for Interactive Connectivity Establishment (ICE)" ๐ฆ
- Authors: M. Petit-Huguenin (Impedance Mismatch), S. Nandakumar (Cisco Systems), C. Holmberg (Ericsson), A. Kerรคnen (Ericsson), and R. Shpount (TurboBridge) ๐
- Category: Standards Track, so this is the real deal, not a suggestion ๐
- Date: January 2021 ๐
- Obsoletes: RFC 5245 and RFC 6336, so they're officially retired ๐
- Updates: nothing listed here, but the Introduction explains what's changed from RFC 5245 ๐ง
The Abstract is the elevator pitch: this doc describes SDP offer/answer procedures for carrying out ICE between the agents ๐
Status of This Memo
This is an Internet Standards Track document ๐ It's a product of the IETF and it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). For more on Internet Standards, check Section 2 of RFC 7841 ๐ซถ Info about this doc's status, any errata, and how to send feedback lives at https://www.rfc-editor.org/info/rfc8839 โจ
Copyright Notice
Copyright (c) 2021 IETF Trust and the persons identified as the document authors. All rights reserved ๐
This doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as in effect on the publication date. Read those carefully, bestie, because they spell out your rights and restrictions ๐ Code Components pulled from this doc must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and come without warranty as described in that license ๐
This doc may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The people controlling copyright in some of that material may not have granted the IETF Trust permission to allow modifications outside the IETF Standards Process. Without an adequate license from them, this doc may not be modified outside the IETF Standards Process, and derivative works may not be created outside it, except to format it for publication as an RFC or to translate it into languages other than English ๐
Table of Contents
1. Introduction
2. Conventions
3. Terminology
4. SDP Offer/Answer Procedures
4.1. Introduction
4.2. Generic Procedures
4.2.1. Encoding
4.2.2. RTP/RTCP Considerations
4.2.3. Determining Role
4.2.4. STUN Considerations
4.2.5. Verifying ICE Support Procedures
4.2.6. SDP Example
4.3. Initial Offer/Answer Exchange
4.3.1. Sending the Initial Offer
4.3.2. Sending the Initial Answer
4.3.3. Receiving the Initial Answer
4.3.4. Concluding ICE
4.4. Subsequent Offer/Answer Exchanges
4.4.1. Sending Subsequent Offer
4.4.2. Sending Subsequent Answer
4.4.3. Receiving Answer for a Subsequent Offer
5. Grammar
5.1. "candidate" Attribute
5.2. "remote-candidates" Attribute
5.3. "ice-lite" and "ice-mismatch" Attributes
5.4. "ice-ufrag" and "ice-pwd" Attributes
5.5. "ice-pacing" Attribute
5.6. "ice-options" Attribute
6. Keepalives
7. SIP Considerations
7.1. Latency Guidelines
7.1.1. Offer in INVITE
7.1.2. Offer in Response
7.2. SIP Option Tags and Media Feature Tags
7.3. Interactions with Forking
7.4. Interactions with Preconditions
7.5. Interactions with Third Party Call Control
8. Interactions with Application Layer Gateways and SIP
9. Security Considerations
9.1. IP Address Privacy
9.2. Attacks on the Offer/Answer Exchanges
9.3. The Voice Hammer Attack
10. IANA Considerations
10.1. SDP Attributes
10.1.1. "candidate" Attribute
10.1.2. "remote-candidates" Attribute
10.1.3. "ice-lite" Attribute
10.1.4. "ice-mismatch" Attribute
10.1.5. "ice-pwd" Attribute
10.1.6. "ice-ufrag" Attribute
10.1.7. "ice-options" Attribute
10.1.8. "ice-pacing" Attribute
10.2. Interactive Connectivity Establishment (ICE) Options
Registry
10.3. Candidate Attribute Extension Subregistry Establishment
11. Changes from RFC 5245
12. References
12.1. Normative References
12.2. Informative References
Appendix A. Examples
Appendix B. The "remote-candidates" Attribute
Appendix C. Why Is the Conflict Resolution Mechanism Needed?
Appendix D. Why Send an Updated Offer?
Acknowledgements
Contributors
Authors' Addresses
1. Introduction ๐ธ
1.1. Overview
Okay so this doc explains how ICE gets used with SDP offer/answer, which is defined in [RFC3264] ๐ The general ICE spec, [RFC8445], covers the procedures that every ICE usage shares, and this doc adds the extra details you need for SDP offer/answer ๐ซถ
This doc obsoletes RFCs 5245 and 6336 ๐
NOTE: Back in the day, both the common ICE stuff and the SDP offer/answer specifics lived in [RFC5245]. Then [RFC8445] obsoleted [RFC5245], and the SDP offer/answer details were pulled out of it. Section 11 covers what's changed in the SDP offer/answer details this doc specifies ๐ง
2. Conventions โจ
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this doc are to be read as described in BCP 14 [RFC2119] [RFC8174], but only when they show up in ALL CAPS like this ๐
3. Terminology ๐ฆ
You should already know the terms defined in [RFC3264] and [RFC8445], plus these:
Default Destination/Candidate: The default destination for a component of a data stream is the transport address an agent that isn't ICE aware would use ๐ง A default candidate for a component is one whose transport address matches that default destination. For the RTP component, the default connection address is in the "c=" line of the SDP, and the port and transport protocol are in the "m=" line. For the RTP Control Protocol (RTCP) component, the address and port are indicated with the "rtcp" attribute defined in [RFC3605] if it's present. Otherwise, the RTCP component address is the same as the RTP component's address, and its port is one greater than the RTP component's port ๐
4. SDP Offer/Answer Procedures ๐
4.1. Introduction ๐
[RFC8445] defines ICE candidate exchange as the process where ICE agents (initiator and responder) swap the candidate info they need for ICE processing at the agents ๐ For this spec, the candidate exchange process matches the Offer/Answer protocol in [RFC3264], and the terms "offerer" and "answerer" line up with the initiator and responder roles from [RFC8445] ๐ซถ
Once the initiating agent has gathered, pruned, and prioritized its set of candidates [RFC8445], the candidate exchange with the peer agent kicks off โจ
4.2. Generic Procedures ๐
4.2.1. Encoding ๐
Section 5 has the detailed rules for building the various SDP attributes this spec defines ๐ฆ
4.2.1.1. Data Streams ๐ธ
Each data stream [RFC8445] is represented by an SDP media description ("m=" section) ๐
4.2.1.2. Candidates ๐ซถ
Inside an "m=" section, each candidate (including the default candidate) for the data stream is represented by an SDP "candidate" attribute โจ
Before nomination, the "c=" line for an "m=" section holds the connection address of the default candidate, and the "m=" line holds the port and transport protocol of that default candidate ๐ง
After nomination, the "c=" line for a given "m=" section holds the connection address of the nominated candidate (the local candidate of the nominated candidate pair), and the "m=" line holds the port and transport protocol that match the nominated candidate for that "m=" section ๐
4.2.1.3. Username and Password ๐ฅ
The ICE username is represented by an SDP "ice-ufrag" attribute, and the ICE password is represented by an SDP "ice-pwd" attribute ๐
4.2.1.4. Lite Implementations ๐
An ICE-lite implementation [RFC8445] MUST include an SDP "ice-lite" attribute. A full implementation MUST NOT include that attribute ๐
4.2.1.5. ICE Extensions ๐
An agent uses the SDP "ice-options" attribute to say it supports ICE extensions ๐
An agent compliant with this spec MUST include an SDP "ice-options" attribute with an "ice2" attribute value [RFC8445] ๐ซถ If an agent gets an SDP offer or answer that indicates ICE support but doesn't have an SDP "ice-options" attribute with an "ice2" value, the agent can assume the peer is compliant with [RFC5245] ๐
4.2.1.6. Inactive and Disabled Data Streams ๐ฆ
If an "m=" section is marked as inactive [RFC4566], or has a bandwidth value of zero [RFC4566], the agent MUST still include ICE-related SDP attributes ๐ธ
If the port value for an "m=" section is set to zero (implying a disabled stream) as defined in Section 8.2 of [RFC3264], the agent SHOULD NOT include ICE-related SDP "candidate" attributes in that "m=" section, unless an SDP extension says otherwise and is used ๐ง
4.2.2. RTP/RTCP Considerations ๐
If an agent uses both RTP and RTCP, and separate ports are used for RTP and RTCP, the agent MUST include SDP "candidate" attributes for both the RTP and RTCP components ๐
The agent includes an SDP "rtcp" attribute following the procedures in [RFC3605]. So when the RTCP port is one higher than the RTP port, and the RTCP component address is the same as the RTP component's address, the SDP "rtcp" attribute might get left out ๐ซถ
NOTE: [RFC5245] required that an agent always include the SDP "rtcp" attribute, even when the RTCP port was one higher than the RTP port. This spec lines up the "rtcp" attribute procedures with [RFC3605] โจ
If the agent doesn't use RTCP, it signals that by including "RS:0" and "RR:0" SDP attributes as described in [RFC3556] ๐
4.2.3. Determining Role ๐
The offerer acts as the initiating agent, and the answerer acts as the responding agent ๐ The ICE roles (controlling and controlled) get figured out using the procedures in [RFC8445] ๐ฆ
4.2.4. STUN Considerations ๐ธ
Once an agent has given its local candidates to its peer in an SDP offer or answer, the agent MUST be ready to receive STUN (Session Traversal Utilities for NAT, [RFC5389]) connectivity check Binding requests on those candidates ๐ฅ
Part 1 of 8 is done, bestie! ๐ More parts are coming, so stay tuned ๐ซถ
4.2.5. Verifying ICE Support Procedures โจ
Okay so first things first ๐
an ICE agent tells the other side it's ICE-pilled by including at least the SDP ice-pwd and ice-ufrag attributes in an offer or answer. And if you're compliant with this spec, you MUST also include an SDP ice-options attribute with an ice2 attribute value. No skipping!! ๐ซถ
The agents will go ahead with the ICE procedures in [RFC8445] and this spec if, for each data stream in the SDP it received, the default destination for each component of that data stream shows up in a candidate attribute. For example, with RTP, the connection address, port, and transport protocol from the c= and m= lines (respectively) show up in a candidate attribute, and the value in the rtcp attribute shows up in a candidate attribute too. It's giving consistency ๐
This spec doesn't give any guidance on what an agent should do when that condition isn't met, with a few exceptions:
- The presence of certain Application Layer Gateways might modify the transport address information, as described in Section 8. The behavior of the responding agent in that situation is implementation dependent. Informally, the responding agent might treat the mismatched transport address information as a plausible new candidate learned from the peer and keep its ICE processing going with that transport address included. Alternatively, the responding agent MAY include an
ice-mismatchattribute in its answer for those data streams. If an agent chooses to include anice-mismatchattribute in its answer for a data stream, then it MUST also omitcandidateattributes, MUST terminate the usage of ICE procedures, and [RFC3264] procedures MUST be used instead for that data stream. ๐ฆ - The transport address from the peer for the default destination is set to IPv4/IPv6 address values
0.0.0.0/::and port value of9. This MUST NOT be considered an ICE failure by the peer agent, and the ICE processing MUST continue as usual. ๐ not a failure, bestie, it's just vibes - In some cases, the controlling/initiator agent may receive an SDP answer that omits
candidateattributes for the data stream and instead includes a media-levelice-mismatchattribute. This tells the offerer that the answerer supports ICE, but that ICE processing wasn't used for this data stream. In this case, ICE processing MUST be terminated for this data stream, and [RFC3264] procedures MUST be followed instead. ๐ธ - The transport address from the peer for the default destination is an FQDN. Regardless of the procedures used to resolve the FQDN or the resolution result, this MUST NOT be considered an ICE failure by the peer agent, and the ICE processing MUST continue as usual. ๐ง
4.2.6. SDP Example ๐
Here's an example SDP message that includes ICE attributes (lines folded for readability):
v=0
o=jdoe 2890844526 2890842807 IN IP4 203.0.113.141
s=
c=IN IP4 192.0.2.3
t=0 0
a=ice-options:ice2
a=ice-pacing:50
a=ice-pwd:asd88fgpdd777uzjYhagZg
a=ice-ufrag:8hhY
m=audio 45664 RTP/AVP 0
b=RS:0
b=RR:0
a=rtpmap:0 PCMU/8000
a=candidate:1 1 UDP 2130706431 203.0.113.141 8998 typ host
a=candidate:2 1 UDP 1694498815 192.0.2.3 45664 typ srflx raddr
203.0.113.141 rport 8998
4.3. Initial Offer/Answer Exchange ๐
4.3.1. Sending the Initial Offer ๐
When an offerer generates the initial offer, in each m= section it MUST include SDP candidate attributes for each available candidate associated with that m= section. On top of that, the offerer MUST include an SDP ice-ufrag attribute, an SDP ice-pwd attribute, and an SDP ice-options attribute with an ice2 attribute value in the offer. If the offerer is a full ICE implementation, it SHOULD include an ice-pacing attribute in the offer (if it's not included, the default value applies). A lite ICE implementation MUST NOT include the ice-pacing attribute in the offer, because it won't perform connectivity checks. ๐
It's valid for an offer m= line to include no SDP candidate attributes and have the default destination set to the IP address values 0.0.0.0/:: and the port value to 9. This implies that the offering agent is only going to use peer-reflexive candidates, or that it will provide additional candidates in subsequent signaling messages. โจ
Note: Within the scope of this document, "initial offer" refers to the first SDP offer that is sent in order to negotiate usage of ICE. It might, or might not, be the initial SDP offer of the SDP session.
Note: The procedures in this document only consider m= sections associated with data streams where ICE is used.
4.3.2. Sending the Initial Answer ๐
When an answerer receives an initial offer indicating that the offerer supports ICE, and the answerer accepts both the offer and the usage of ICE, the answerer MUST include in each m= section within the answer the SDP candidate attributes for each available candidate associated with that m= section. The answerer MUST also include an SDP ice-ufrag attribute, an SDP ice-pwd attribute, and an SDP ice-options attribute with an ice2 attribute value in the answer. If the answerer is a full ICE implementation, it SHOULD include an ice-pacing attribute in the answer (if it's not included, the default value applies). A lite ICE implementation MUST NOT include the ice-pacing attribute in the answer, because it won't perform connectivity checks. ๐ซถ
In each m= line, the answerer MUST use the same transport protocol that was used in the offer m= line. If none of the candidates in the m= line in the answer uses the same transport protocol indicated in the offer m= line, then, to avoid ICE mismatch, the default destination MUST be set to IP address values 0.0.0.0/:: and port value of 9. ๐
It's also valid for an answer m= line to include no SDP candidate attributes and have the default destination set to the IP address values 0.0.0.0/:: and the port value to 9. This implies that the answering agent is only going to use peer-reflexive candidates, or that additional candidates will be provided in subsequent signaling messages. ๐ฆ
Once the answerer has sent the answer, it can start performing connectivity checks towards the peer candidates that were provided in the offer. ๐
If the offer does not indicate support of ICE (Section 4.2.5), the answerer MUST NOT accept the usage of ICE. If the answerer still accepts the offer, the answerer MUST NOT include any ICE-related SDP attributes in the answer. Instead, the answerer generates the answer according to normal offer/answer procedures [RFC3264]. ๐ โโ๏ธ no ICE for you, offer
If the answerer detects a possibility of an ICE mismatch, the procedures described in Section 4.2.5 are followed. ๐
4.3.3. Receiving the Initial Answer ๐ฌ
When an offerer receives an initial answer that indicates the answerer supports ICE, it can start performing connectivity checks towards the peer candidates that were provided in the answer. ๐
If the answer does not indicate that the answerer supports ICE, or if the answerer included ice-mismatch attributes for all the active data streams in the answer, the offerer MUST terminate the usage of ICE for the entire session, and [RFC3264] procedures MUST be followed instead. ๐ญ
On the other hand, if the answer indicates support for ICE but includes ice-mismatch in certain active data streams, then the offerer MUST terminate the usage of ICE procedures, and [RFC3264] procedures MUST be used instead for only those data streams. Also, ICE procedures MUST be used for data streams where an ice-mismatch attribute was not included. โ๏ธ
If the offerer detects an ICE mismatch for one or more data streams in the answer, as described in Section 4.2.5, the offerer MUST terminate the usage of ICE for the entire session. The subsequent actions taken by the offerer are implementation dependent and are out of the scope of this specification. ๐ธ
4.3.4. Concluding ICE ๐
Once the agent has successfully nominated a pair [RFC8445], the state of the checklist associated with that pair is set to Completed. Once the state of each checklist is set to either Completed or Failed, for each Completed checklist, the agent checks whether the nominated pair matches the default candidate pair. If there are one or more pairs that do not match, and the peer did not indicate support for the 'ice2' ice-option, the controlling agent MUST generate a subsequent offer in which the connection address, port, and transport protocol in the c= and m= lines associated with each data stream match the corresponding local information of the nominated pair for that data stream (Section 4.4.1.2.2). If the peer did indicate support for the 'ice2' ice-option, the controlling agent does not immediately need to generate an updated offer in order to align a connection address, port, and protocol with a nominated pair. However, later in the session, whenever the controlling agent does send a subsequent offer, it MUST do the alignment as described above. ๐งฉ
If there are one or more checklists with the state set to Failed, the controlling agent MUST generate a subsequent offer in order to remove the associated data streams by setting the port value of those data streams to zero (Section 4.4.1.1.2), even if the peer did indicate support for the 'ice2' ice-option. If needed, that offer is used to align the connection address, port, and transport protocol, as described above. ๐ฅ
As described in [RFC8445], once the controlling agent has nominated a candidate pair for a checklist, the agent MUST NOT nominate another pair for that checklist during the lifetime of the ICE session (i.e., until ICE is restarted). ๐ one pair per checklist, periodt
[RFC8863] provides a mechanism for allowing the ICE process to run long enough to find working candidate pairs, by waiting for potential peer-reflexive candidates, even though no candidate pairs were received from the peer or all current candidate pairs associated with a checklist have either failed or been discarded. โณ
4.4. Subsequent Offer/Answer Exchanges ๐
Either agent MAY generate a subsequent offer at any time allowed by [RFC3264]. This section defines the rules for constructing subsequent offers and answers. ๐ง
Should a subsequent offer fail, ICE processing continues as if the subsequent offer had never been made. ๐
4.4.1. Sending Subsequent Offer ๐ซ
4.4.1.1. Procedures for All Implementations ๐
4.4.1.1.1. ICE Restart ๐โจ
An agent MAY restart ICE processing for an existing data stream [RFC8445]. It's totally optional, but when it happens it's a whole glow-up ๐
Here's the tea: the restart rules mean that setting the connection address in the c= line to 0.0.0.0 (for IPv4) or :: (for IPv6) will also cause an ICE restart ๐ So ICE implementations MUST NOT use that for call hold ๐ซ. Instead, they MUST use inactive and sendonly as described in [RFC3264] ๐
To restart ICE, an agent MUST change both the ice-pwd and the ice-ufrag for the data stream in an offer. It's allowed to use a session-level attribute in one offer and then give the same ice-pwd or ice-ufrag as a media-level attribute in a later offer. This MUST NOT be considered as ICE restart ๐
The agent sets the rest of the ICE-related fields in the SDP for this data stream the same way it would in an initial offer of this data stream (Section 4.2.1). So the set of candidates MAY include some, none, or all of the previous candidates for that data stream, and MAY include a totally new set of candidates ๐ฆ The agent MAY modify the attribute values of the SDP ice-options and SDP ice-pacing attributes, and it MAY change its role using the SDP ice-lite attribute. But the agent MUST NOT modify the SDP ice-options, ice-pacing, and ice-lite attributes in a subsequent offer unless that offer is sent in order to request an ICE restart ๐ซถ
4.4.1.1.2. Removing a Data Stream ๐ โโ๏ธ
If an agent removes a data stream by setting its port to zero, it MUST NOT include any candidate attributes for that data stream, and it SHOULD NOT include any other ICE-related attributes defined in Section 5 for that data stream ๐
4.4.1.1.3. Adding a Data Stream ๐ฑ
If an agent wants to add a new data stream, it sets the fields in the SDP for this data stream as if this were an initial offer for that data stream (Section 4.2.1). This kicks off ICE processing for this data stream โญ
4.4.1.2. Procedures for Full Implementations ๐
This section describes additional procedures for full implementations, covering existing data streams ๐ธ
4.4.1.2.1. Before Nomination ๐ง
When an offerer sends a subsequent offer, in each m= section for which a candidate pair has not yet been nominated, the offer MUST include the same set of ICE-related information that the offerer included in the previous offer or answer. The agent MAY include additional candidates it did not offer previously, but which it has gathered since the last offer/answer exchange, including peer-reflexive candidates โจ
The agent MAY change the default destination for media. As with initial offers, there MUST be a set of candidate attributes in the offer matching this default destination ๐
4.4.1.2.2. After Nomination ๐
Once a candidate pair has been nominated for a data stream, the connection address, port, and transport protocol in each c= and m= line associated with that data stream MUST match the data associated with the nominated pair for that data stream. On top of that, the offerer only includes SDP candidate attributes (one per component) representing the local candidates of the nominated candidate pair. The offerer MUST NOT include any other SDP candidate attributes in the subsequent offer ๐
Also, if the agent is controlling, it MUST include the remote-candidates attribute for each data stream whose checklist is in the Completed state. The attribute contains the remote candidates corresponding to the nominated pair in the valid list for each component of that data stream. It's needed to avoid a race condition ๐ญ where the controlling agent chooses its pairs, but the updated offer beats the connectivity checks to the controlled agent, which doesn't even know these pairs are valid, let alone selected. See Appendix B for elaboration on this race condition ๐ฅ
4.4.1.3. Procedures for Lite Implementations ๐
If the ICE state is Running, a lite implementation MUST include all of its candidates for each component of each data stream in candidate attributes in any subsequent offer. The candidates are formed exactly the same way as the procedures for initial offers ๐ฆ
A lite implementation MUST NOT add additional host candidates in a subsequent offer, and MUST NOT modify the username fragments and passwords. If an agent needs to offer additional candidates, or to modify the username fragments and passwords, it MUST request an ICE restart (Section 4.4.1.1.1) for that data stream ๐
If ICE has completed for a data stream, and the agent is controlled, the default destination for that data stream MUST be set to the remote candidate of the candidate pair for that component in the valid list. For a lite implementation, there is always just a single candidate pair in the valid list for each component of a data stream. Additionally, the agent MUST include a candidate attribute for each default destination ๐
If the ICE state is Completed, and the agent is controlling (which only happens when both agents are lite), the agent MUST include the remote-candidates attribute for each data stream. The attribute contains the remote candidates from the candidate pairs in the valid list (one pair for each component of each data stream) ๐ธ
4.4.2. Sending Subsequent Answer ๐
If ICE is Completed for a data stream, and the offer for that data stream lacked the remote-candidates attribute, the rules for constructing the answer are identical to those for the offerer, except that the answerer MUST NOT include the remote-candidates attribute in the answer ๐
A controlled agent receives an offer with the remote-candidates attribute for a data stream when its peer has concluded ICE processing for that data stream. This attribute is in the offer to deal with a race condition between the receipt of the offer and the receipt of the Binding response that tells the answerer which candidate will be selected by ICE. See Appendix B for an explanation of this race condition. So, processing an offer with this attribute depends on who wins the race ๐
The agent forms a candidate pair for each component of the data stream by:
- Setting the remote candidate equal to the offerer's default destination for that component (i.e., the contents of the
m=andc=lines for RTP, and thertcpattribute for RTCP) - Setting the local candidate equal to the transport address for that same component in the
remote-candidatesattribute in the offer.
The agent then checks whether each of these candidate pairs is present in the valid list. If a particular pair is not in the valid list, the check has "lost" the race. Call such a pair a "losing pair" ๐ฌ
The agent finds all the pairs in the checklist whose remote candidates equal the remote candidate in the losing pair:
- If none of the pairs is In-Progress, and at least one is Failed, it is most likely that a network failure, such as a network partition or serious packet loss, has occurred. The agent SHOULD generate an answer for this data stream as if the
remote-candidatesattribute had not been present, and then restart ICE for this stream ๐ฅบ - If at least one of the pairs is In-Progress, the agent SHOULD wait for those checks to complete, and as each one completes, redo the processing in this section until there are no losing pairs โณ
Once there are no losing pairs, the agent can generate the answer. It MUST set the default destination for media to the candidates in the remote-candidates attribute from the offer (each of which will now be the local candidate of a candidate pair in the valid list). It MUST include a candidate attribute in the answer for each candidate in the remote-candidates attribute in the offer ๐ซถ
4.4.2.1. ICE Restart ๐
If the offerer in a subsequent offer requested an ICE restart (Section 4.4.1.1.1) for a data stream, and the answerer accepts the offer, the answerer follows the procedures for generating an initial answer ๐ฑ
For a given data stream, the answerer MAY include the same candidates that were used in the previous ICE session, but it MUST change the SDP ice-pwd and ice-ufrag attribute values ๐ฆ
The answerer MAY modify the attribute values of the SDP ice-options and SDP ice-pacing attributes, and it MAY change its role using the SDP ice-lite attribute. The answerer MUST NOT modify the SDP ice-options, ice-pacing, and ice-lite attributes in a subsequent answer unless the answer is sent for an offer that was used to request an ICE restart (Section 4.4.1.1.1). If any of the SDP attributes have been modified in a subsequent offer that is not used to request an ICE restart, the answerer MUST reject the offer ๐ซ
4.4.2.2. Lite Implementation Specific Procedures ๐ท
If the received offer contains the remote-candidates attribute for a data stream, the agent forms a candidate pair for each component of the data stream by:
- Setting the remote candidate equal to the offerer's default destination for that component (i.e., the contents of the
m=andc=lines for RTP, and thertcpattribute for RTCP). - Setting the local candidate equal to the transport address for that same component in the
remote-candidatesattribute in the offer.
The state of the checklist associated with that data stream is set to Completed โ
Furthermore, if the agent believed it was controlling, but the offer contained the remote-candidates attribute, both agents believe they are controlling. In this case, both would have sent updated offers around the same time ๐ตโ๐ซ
However, the signaling protocol carrying the offer/answer exchanges will have resolved this glare condition, so that one agent is always the 'winner' by having its offer received before its peer has sent an offer. The winner takes the role of controlling, so the loser (the answerer under consideration in this section) MUST change its role to controlled ๐ฅ
Consequently, if the agent was controlling based on the rules in Section 8.2 of [RFC8445] and was going to send an updated offer, it no longer needs to ๐
Besides the potential role change, change in the valid list, and state changes, the construction of the answer is performed identically to the construction of an offer ๐
4.4.3. Receiving Answer for a Subsequent Offer ๐ฌ
4.4.3.1. Procedures for Full Implementations โจ
okay so there are times when the offerer gets an SDP answer that has NO ICE candidates in it, even though the first answer totally had them ๐ญ. one "unexpected" answer like that can happen when an ICE-unaware Back-to-Back User Agent (B2BUA) pops in a media server during call hold, using third party call control procedures [RFC3725]. (skipping the messy details on how that works ๐) the result is that an answer the B2BUA built lands at the holding UA, and since the B2BUA doesn't know about ICE, that answer has no ICE candidates. ๐
getting an answer with no ICE attributes here might feel unexpected, but it doesn't necessarily wreck the user experience. ๐ซถ
when the offerer gets an answer that shows ICE support, it does one of the following things ๐ฅ:
- If the offer was a restart, the agent MUST perform ICE restart procedures as specified in Section 4.4.3.1.1. ๐
- If the offer/answer exchange removed a data stream, or an answer rejected an offered data stream, an agent MUST flush the valid list for that data stream. It MUST also terminate any STUN transactions in progress for that data stream. ๐
- If the offer/answer exchange added a new data stream, the agent MUST create a new checklist for it (and an empty valid list to start of course), which in turn triggers the candidate processing procedures [RFC8445]. ๐ฑ
- If the checklist state associated with a data stream is Running, the agent recomputes the checklist. If a pair on the new checklist was also on the previous checklist, its candidate pair state is copied over. Otherwise, its candidate pair state is set to Frozen. If none of the checklists are active (meaning that the candidate pair states in each checklist are Frozen), appropriate procedures in [RFC8445] are performed to move candidate pair(s) to the Waiting state to further continue ICE processing. ๐งฉ
- If the ICE state is Completed, and the SDP answer conforms to Section 4.4.2, the agent MUST remain in the Completed ICE state. ๐
However, if the ICE support is no longer indicated in the SDP answer, the agent MUST fall back to [RFC3264] procedures and SHOULD NOT drop the dialog because of the missing ICE support or unexpected answer. When the agent sends a new offer, it MUST perform an ICE restart. ๐
4.4.3.1.1. ICE Restarts ๐
the agent MUST remember the nominated pair in the valid list for each component of the data stream, called the "previous selected pair", prior to the restart. ๐ the agent will keep sending media using this pair, as described in Section 12 of [RFC8445]. once these destinations are noted, the agent MUST flush the valid lists and checklists, and then recompute the checklist and its states, thus triggering the candidate processing procedures [RFC8445]. main character restart energy ๐ฆ
4.4.3.2. Procedures for Lite Implementations ๐ท
if ICE is restarting for a data stream, the agent MUST create a new valid list for that data stream. It MUST remember the nominated pair in the previous valid list for each component of the data stream, called the "previous selected pairs", and continue to send media there as described in Section 12 of [RFC8445]. The state of each checklist for each data stream MUST change to Running, and the ICE state MUST be set to Running. ๐
5. Grammar ๐
this specification defines eight new SDP attributes: the "candidate", "remote-candidates", "ice-lite", "ice-mismatch", "ice-ufrag", "ice-pwd", "ice-pacing", and "ice-options" attributes. ๐
this section also gives you non-normative examples of the attributes defined. ๐
the syntax for the attributes follows Augmented BNF as defined in [RFC5234]. โจ
5.1. "candidate" Attribute ๐ซ
the "candidate" attribute is a media-level attribute only. It contains a transport address for a candidate that can be used for connectivity checks. ๐
candidate-attribute = "candidate" ":" foundation SP component-id SP
transport SP
priority SP
connection-address SP ;from RFC 4566
port ;port from RFC 4566
SP cand-type
[SP rel-addr]
[SP rel-port]
*(SP cand-extension)
foundation = 1*32ice-char
component-id = 1*3DIGIT
transport = "UDP" / transport-extension
transport-extension = token ; from RFC 3261
priority = 1*10DIGIT
cand-type = "typ" SP candidate-types
candidate-types = "host" / "srflx" / "prflx" / "relay" / token
rel-addr = "raddr" SP connection-address
rel-port = "rport" SP port
cand-extension = extension-att-name SP extension-att-value
extension-att-name = token
extension-att-value = *VCHAR
ice-char = ALPHA / DIGIT / "+" / "/"
this grammar holds the main info about a candidate: its IP address, port, and transport protocol, plus its properties: the foundation, component ID, priority, type, and related transport address. ๐ง
<connection-address>: is taken from RFC 4566 [RFC4566]. It is the IP address of the candidate, allowing for IPv4 addresses, IPv6 addresses, and fully qualified domain names (FQDNs). When parsing this field, an agent can tell an IPv4 address from an IPv6 address by checking for a colon in its value, since the presence of a colon indicates IPv6. An agent generating local candidates MUST NOT use FQDN addresses. An agent processing remote candidates MUST ignore "candidate" lines that include candidates with FQDNs or IP address versions that are not supported or recognized. The procedures for generation and handling of FQDN candidates, as well as how agents indicate support for such procedures, need to be specified in an extension specification. ๐<port>: is also taken from RFC 4566 [RFC4566]. It is the port of the candidate. ๐ช<transport>: indicates the transport protocol for the candidate. This specification only defines UDP. However, extensibility is provided to allow for future transport protocols to be used with ICE, by extending the subregistry "ICE Transport Protocols" under the "Interactive Connectivity Establishment (ICE)" registry. ๐<foundation>: is composed of 1 to 32<ice-char>s. It is an identifier that is equivalent for two candidates that are of the same type, share the same base, and come from the same STUN server. The foundation is used to optimize ICE performance in the Frozen algorithm as described in [RFC8445]. ๐ง<component-id>: is a positive integer between 1 and 256 (inclusive) that identifies the specific component of the data stream for which this is a candidate. It MUST start at 1 and MUST increment by 1 for each component of a particular candidate. For data streams based on RTP, candidates for the actual RTP media MUST have a component ID of 1, and candidates for RTCP MUST have a component ID of 2. See Section 13 of [RFC8445] for additional discussion on extending ICE to new data streams. ๐ข<priority>: is a positive integer between 1 and(2**31 - 1)inclusive. The procedures for computing a candidate's priority are described in Section 5.1.2 of [RFC8445]. ๐<cand-type>: encodes the type of candidate. This specification defines the values "host", "srflx", "prflx", and "relay" for host, server-reflexive, peer-reflexive, and relayed candidates, respectively. Specifications for new candidate types MUST define how, if at all, various steps in the ICE processing differ from the ones defined by this specification. ๐ท๏ธ<rel-addr>and<rel-port>: convey transport addresses related to the candidate, useful for diagnostics and other purposes.<rel-addr>and<rel-port>MUST be present for server-reflexive, peer-reflexive, and relayed candidates. If a candidate is server-reflexive or peer-reflexive,<rel-addr>and<rel-port>are equal to the base for that server-reflexive or peer-reflexive candidate. If the candidate is relayed,<rel-addr>and<rel-port>are equal to the mapped address in the Allocate response that provided the client with that relayed candidate (see Section 6.3 of [RFC5766]). If the candidate is a host candidate,<rel-addr>and<rel-port>MUST be omitted. ๐
In some cases, e.g., for privacy reasons, an agent may not want to reveal the related address and port. In this case the address MUST be set to "0.0.0.0" (for IPv4 candidates) or "::" (for IPv6 candidates) and the port to "9". ๐
the "candidate" attribute can itself be extended. The grammar allows for new name/value pairs to be added at the end of the attribute. Such extensions MUST be made through IETF Review or IESG Approval [RFC8126], and the assignments MUST contain the specific extension and a reference to the document defining the usage of the extension. ๐งฉ
an implementation MUST ignore any name/value pairs it doesn't understand. ๐ซ
here's an example SDP line for a UDP server-reflexive "candidate" attribute for the RTP component ๐:
a=candidate:2 1 UDP 1694498815 192.0.2.3 45664 typ srflx raddr 203.0.113.141 rport 8998
5.2. "remote-candidates" Attribute ๐ธ
the syntax of the "remote-candidates" attribute is defined using Augmented BNF as defined in [RFC5234]. The "remote-candidates" attribute is a media-level attribute only. ๐
remote-candidate-att = "remote-candidates:" remote-candidate
0*(SP remote-candidate)
remote-candidate = component-id SP connection-address SP port
the attribute contains a connection-address and port for each component. The ordering of components is irrelevant. However, a value MUST be present for each component of a data stream. This attribute MUST be included in an offer by a controlling agent for a data stream that is Completed, and MUST NOT be included in any other case. ๐ฏ
here are some examples of "remote-candidates" SDP lines for the RTP and RTCP components ๐ฆ:
a=remote-candidates:1 192.0.2.3 45664
a=remote-candidates:2 192.0.2.3 45665
5.3. "ice-lite" and "ice-mismatch" Attributes ๐
the syntax of the "ice-lite" and "ice-mismatch" attributes, both of which are flags, is:
ice-lite = "ice-lite"
ice-mismatch = "ice-mismatch"
"ice-lite" is a session-level attribute only, and indicates that an agent is a lite implementation. "ice-mismatch" is a media-level attribute and is only reported in the answer. It indicates that the offer arrived with a default destination for a media component that didn't have a corresponding "candidate" attribute. Including the "ice-mismatch" attribute for a given data stream implies that even though both agents support ICE, ICE procedures MUST NOT be used for this data stream, and [RFC3264] procedures MUST be used instead. ๐จ
5.4. "ice-ufrag" and "ice-pwd" Attributes ๐
okay bestie, these two attributes carry the username fragment and password that ICE uses for message integrity, so they're basically the bouncers of the whole operation ๐ Here's their grammar:
ice-pwd-att = "ice-pwd:" password
ice-ufrag-att = "ice-ufrag:" ufrag
password = 22*256ice-char
ufrag = 4*256ice-char
So ice-pwd and ice-ufrag can show up at either the session-level or the media-level ๐ If both have them, the media-level value wins โจ Think of the session-level one as a default that covers every data stream, unless a media-level one overrides it ๐ Either way, there MUST be an "ice-pwd" and an "ice-ufrag" attribute for each data stream ๐ซถ And if two data streams share the same "ice-ufrag", they MUST have the same "ice-pwd" too, no exceptions ๐ญ
These values MUST be chosen randomly at the very beginning of a session. The same goes when ICE is restarting for an agent ๐ฒ
[RFC8445] wants the "ice-ufrag" to hold at least 24 bits of randomness, and the "ice-pwd" to hold at least 128 bits of randomness ๐ Because the grammar packs 6 bits of information into each character, that works out to "ice-ufrag" being at least 4 characters long, and "ice-pwd" being at least 22 characters long ๐งฎ You're allowed to go longer than 4 and 22 characters, MAY do it, all the way up to 256 characters ๐ฆ That upper limit exists so implementations can size their buffers, and the big ceiling leaves room to add more randomness over time ๐ธ
Now here's the spicy part. The STUN username attribute value tops out at 512 characters, and bandwidth matters too, so the "ice-ufrag" MUST NOT be longer than 32 characters when you're sending it ๐ But when you're receiving, an implementation MUST accept up to 256 characters ๐ Be generous when you listen, careful when you talk ๐
Here's a sample of what these SDP lines look like ๐
a=ice-pwd:asd88fgpdd777uzjYhagZg
a=ice-ufrag:8hhY
5.5. "ice-pacing" Attribute โฑ๏ธ
The "ice-pacing" attribute is session-level, and it says how fast the sender wants its connectivity checks to go, measured as the Ta interval in milliseconds โจ If you want the scoop on picking a pacing value, check out Section 14.2 of [RFC8445] ๐ Here's the grammar:
ice-pacing-att = "ice-pacing:" pacing-value
pacing-value = 1*10DIGIT
If the attribute isn't in an offer or an answer, it defaults to 50 ms, which is the recommended value in [RFC8445] ๐ซง
Now, no matter what Ta value each agent picks, [RFC8445] says all the transactions from all agents combined (in case one implementation runs several agents at once) won't be sent more often than once every 5 ms ๐ฆ And once both agents have shared the pacing value they want, they both go with the larger of the two numbers ๐ Iconic cooperation ๐ซถ
Here's an "ice-pacing" line with a value of '50' ๐
a=ice-pacing:50
5.6. "ice-options" Attribute ๐งฉ
The "ice-options" attribute works at both session-level and media-level ๐ It's a list of tokens naming the options the agent supports ๐ The grammar goes like this:
ice-options = "ice-options:" ice-option-tag
*(SP ice-option-tag)
ice-option-tag = 1*ice-char
So if an offer has "ice-options", that means the agent supports a certain extension and is totally down to use it, as long as the peer agent also includes the same extension in its answer โจ Sometimes the agents need extra extension-specific negotiation to figure out how that extension actually gets used in the session ๐ค The details of those negotiation procedures, if there are any, MUST be defined by the specification that defines the extension (Section 10.2) ๐
Here's an "ice-options" line with 'ice2' and 'rtp+ecn' [RFC6679] in it ๐ฆ
a=ice-options:ice2 rtp+ecn
6. Keepalives ๐
All the ICE agents MUST follow the procedures in Section 11 of [RFC8445] for sending keepalives ๐ซถ As [RFC8445] explains, keepalives get sent no matter whether the data stream is inactive, sendonly, recvonly, or sendrecv, and no matter whether there's a bandwidth attribute or what its value is ๐ธ And here's a bonus clue: an agent can tell its peer supports ICE by seeing "candidate" attributes for each media session ๐ต๏ธโโ๏ธ
7. SIP Considerations ๐
Quick heads-up: ICE is NOT meant for NAT traversal of SIP signaling. Nope, that's assumed to be handled by another mechanism [RFC5626] ๐ โโ๏ธ
When ICE is used with SIP, forking can turn one offer into a bunch of answers ๐ฟ In that case, ICE runs completely in parallel and independently for each answer ๐ซง It treats the combo of the offer plus each answer as its own independent offer/answer exchange, with its own local candidates, pairs, checklists, states, and so on ๐
7.1. Latency Guidelines โณ
ICE needs a series of STUN-based connectivity checks to happen between endpoints โจ These checks kick off at the answerer once it generates its answer, and at the offerer once it receives the answer ๐ They can take a while, so the messages you pick for offers and answers can change how laggy things feel to the user ๐ญ Two latency numbers really matter here. The first is the post-pickup delay, which is the time between when a user "answers the phone" and when whatever they say can actually reach the caller ๐ง The second is the post-dial delay, which is the time between when a user types in the destination address and ringback starts because the called user agent has successfully started alerting ๐
There are two cases to think about: one where the offer is in the initial INVITE, and one where it shows up in a response ๐
7.1.1. Offer in INVITE ๐
To cut down on post-dial delays, it is RECOMMENDED that the caller start gathering candidates before it actually sends its initial INVITE, so the candidates can ride along in the INVITE ๐ The caller can kick this off on user interface cues that a call is pending, like keypad activity or the phone going off-hook ๐ฑ
When the offer comes in, the answerer SHOULD generate an answer in a provisional response as soon as it finishes gathering candidates ๐ซถ ICE requires that a provisional response with an SDP be sent reliably. You can do that with the existing Provisional Response Acknowledgment (PRACK) mechanism from [RFC3262], or with an ICE-specific optimization where the agent retransmits the provisional response using the exponential backoff timers described in [RFC3262] ๐ Those retransmissions MUST stop once a STUN Binding request arrives with a transport address matching the candidate address for one of the data streams signaled in that SDP, or once the answer goes out in a 2xx response ๐ If no Binding request shows up before the last retransmit, the agent does NOT treat the session as terminated ๐ And for ICE-lite peers, the agent MUST stop retransmitting the 18x response after sending it four times, since no Binding request is going to come, and the number four was picked arbitrarily to keep the 18x retransmits in check ๐ง
Once the answer has been sent, the agent SHOULD start its connectivity checks ๐โโ๏ธ Once candidate pairs for each component of a data stream land in the valid list, the answerer can start sending media on that data stream ๐ถ
Hold up though: before that point, any media that needs to go back toward the caller (like SIP early media [RFC3960]) MUST NOT be transmitted ๐ซ That's why implementations SHOULD hold off on alerting the called party until candidates for each component of each data stream have entered the valid list ๐ For a PSTN gateway, that means the setup message into the PSTN gets delayed until that point ๐ก It bumps up the post-dial delay, but it totally eliminates 'ghost rings' ๐ป A ghost ring is when the called party hears the phone ring, picks up, hears nothing, and can't be heard either ๐ญ This trick works without needing support for or use of preconditions [RFC3312] ๐ It also guarantees that not a single packet of media gets clipped, so the post-pickup delay is zero โจ And if an agent decides to delay local alerting like this, it SHOULD generate a 180 response once alerting begins ๐
7.1.2. Offer in Response ๐
Besides cases where the offer is in an INVITE and the answer comes in the provisional and/or 200 OK response, ICE also works when the offer shows up in a response ๐ซ These setups are common in third party call control [RFC3725] ๐ In those cases, ICE agents SHOULD generate their offers in a reliable provisional response (which MUST utilize [RFC3262]), and they shouldn't alert the user when the INVITE arrives ๐ The answer will come back in a PRACK ๐ซง This lets ICE processing finish before alerting, so there's no post-pickup delay, but call setup takes longer as a tradeoff ๐ข Once ICE completes, the callee can alert the user, and then generate a 200 OK when they answer ๐ That 200 OK contains no SDP, since the offer/answer exchange is already done ๐ท
Or, agents MAY put the offer in a 2xx instead, and then the answer arrives in the ACK ๐ฆ When that happens, the callee alerts the user as soon as the INVITE lands, and the ICE exchanges only happen after the user answers ๐ฒ That cuts down call-setup delay, but it can cause big post-pickup delays and media clipping ๐ฌ
7.2. SIP Option Tags and Media Feature Tags ๐ท๏ธ
[RFC5768] defines a SIP option tag and a media feature tag for use with ICE ๐ธ ICE implementations using SIP SHOULD support this specification, since it uses a feature tag in registrations to help interoperability through signaling intermediaries ๐ค
7.3. Interactions with Forking ๐
ICE gets along really well with forking. In fact, ICE fixes some of the problems forking causes ๐ Without ICE, when a call forks and the caller gets several incoming data streams, it has no way to tell which data stream belongs to which callee ๐ตโ๐ซ
With ICE, that problem goes away โจ The connectivity checks that happen before media is sent carry username fragments, and those fragments get correlated to a specific callee ๐ Any media packets that show up later on the same candidate pair as the connectivity check get associated with that same callee ๐ฏ So the caller can do this correlation as long as it has received an answer ๐
7.4. Interactions with Preconditions โจ
Okay, so QoS preconditions (defined in [RFC3312] and [RFC4032]) only care about the transport addresses listed as the default targets for media in an offer/answer ๐ฏ. If ICE changes where media gets received, that change shows up in an updated offer that moves the default destination to match what ICE picked. ๐ From the outside, it looks like any other re-INVITE, so RFCs 3312 and 4032 handle it fully, even though the destination is changing because ICE is negotiating "in the background" ๐ซถ
Here's the key bit ๐ An agent SHOULD NOT indicate that QoS preconditions have been met until the checks have finished and picked the candidate pairs that'll actually carry media. Don't claim you're ready before you are, bestie ๐ญ
ICE also has interactions with connectivity preconditions [RFC5898]. Those are described over there, so go read them if you want the full tea ๐ต Also, the procedures in Section 7.1 describe their own kind of "preconditions," but they have less functionality than the explicit preconditions in [RFC5898]. Not the same level of iconic ๐
7.5. Interactions with Third Party Call Control
ICE works with Flows I, III, and IV from [RFC3725] ๐ฆ Flow I works even if the controller doesn't support or know about ICE. Flow IV works as long as the controller passes the ICE attributes along without changing them. Flow II is fundamentally incompatible with ICE ๐ญ Each agent thinks it's the answerer, so neither one ever generates a re-INVITE. Not it ๐
The flows for continued operation (see Section 7 of [RFC3725]) need some extra behavior from ICE implementations to work. Specifically, if an agent gets a mid-dialog re-INVITE that has no offer, it MUST restart ICE for each data stream and go through gathering new candidates again ๐ On top of that, that list of candidates SHOULD include the ones currently being used for media, so the good stuff isn't left out โจ
8. Interactions with Application Layer Gateways and SIP
Okay, the NAT crowd ๐ Application Layer Gateways (ALGs) are functions inside a Network Address Translation (NAT) device that look inside packets and modify them, so application protocols can get through NAT ๐ง Session Border Controllers (SBCs) are close cousins of ALGs, but they're way less invisible because they actually sit there as application-layer SIP intermediaries. ICE has interactions with both SBCs and ALGs, so let's spill ๐ซถ
If an ALG is SIP aware but not ICE aware, ICE will still work through it, as long as the ALG correctly modifies the SDP. A correct ALG behaves like this ๐
- The ALG does not modify the
m=andc=lines or thertcpattribute if they contain external addresses. - If the
m=andc=lines contain internal addresses, the modification depends on the state of the ALG:- If the ALG already has a binding that maps an external port to an internal connection address and port matching the values in the
m=andc=lines orrtcpattribute, the ALG uses that binding instead of creating a new one. - If the ALG does not already have a binding, it creates a new one and modifies the SDP, rewriting the
m=andc=lines andrtcpattribute.
- If the ALG already has a binding that maps an external port to an internal connection address and port matching the values in the
Unfortunately, a lot of ALGs are known to work poorly in these corner cases ๐ ICE does not try to work around broken ALGs, because that's outside its scope. ICE can still help diagnose these problems, which usually show up as a mismatch between the set of candidates and the m= and c= lines and rtcp attributes. That's what the ice-mismatch attribute is for ๐
ICE works best through ALGs when the signaling runs over TLS ๐ This stops the ALG from messing with the SDP messages and interfering with ICE. Implementations that are expected to be deployed behind ALGs SHOULD provide for TLS transport of the SDP. Protect that SDP, babe ๐ก๏ธ
If an SBC is SIP aware but not ICE aware, the result depends on how the SBC behaves. If it's acting as a proper Back-to-Back User Agent (B2BUA), the SBC will strip out any SDP attributes it doesn't understand, including the ICE attributes ๐ So the call looks to both endpoints like the other side doesn't support ICE. ICE then gets disabled, and media flows through the SBC if the SBC asked for that. ๐ค But if the SBC passes the ICE attributes through untouched and still changes the default destination for media (in the m= and c= lines and the rtcp attribute), that gets caught as an ICE mismatch, and ICE processing is aborted for the call. ICE isn't a tool for "working around" SBCs, and it's not going to be one. If an SBC is present, ICE won't be used and the SBC techniques take precedence ๐
9. Security Considerations
Okay, this part is serious, so put your listening ears on ๐จ The generic ICE security considerations are defined in [RFC8445], and the generic SDP offer/answer security considerations are defined in [RFC3264]. These security considerations also apply to implementations of this document ๐
9.1. IP Address Privacy
In some cases, like for privacy reasons, an agent may not want to reveal the related address and port ๐ In that case the address MUST be set to "0.0.0.0" (for IPv4 candidates) or "::" (for IPv6 candidates), and the port to '9'. Hide your address, but do it the right way ๐ฆ
9.2. Attacks on the Offer/Answer Exchanges
โ ๏ธ Okay, this one is actually scary, so read it twice.
An attacker who can modify or disrupt the offer/answer exchanges themselves can easily launch a bunch of attacks with ICE ๐ฑ They could aim media at the target of a DoS attack, they could insert themselves into the data stream, and more. These are similar to the general security considerations for offer/answer exchanges, and the security considerations in [RFC3264] apply. These attacks need techniques for message integrity and encryption for offers and answers, and when SIP is used, those are covered by the TLS mechanism [RFC3261]. So the usage of TLS with ICE is RECOMMENDED ๐๐
9.3. The Voice Hammer Attack
The voice hammer attack is an amplification attack, and it can happen even if the attacker is an authenticated and valid participant in a session ๐ Here's how it goes: the attacker starts sessions with other agents and sneakily includes the connection address and port of a DoS target as the destination for media signaled in the SDP. That causes serious amplification. One offer/answer exchange can start a continuing flood of media packets, possibly at high rates (think video sources) ๐ญ
ICE can help prevent this attack. If ICE is used, the agent that gets the malicious SDP will first run connectivity checks to the media target before sending any media there โ If that target is a third-party host, the checks won't succeed, so media never gets sent. The ICE extension defined in [RFC7675] can be used to protect even further against voice hammer attacks ๐ซถ
Unfortunately, ICE doesn't help if it isn't used. In that case, an attacker could just send the offer without the ICE parameters ๐ But in environments where the set of clients is known and limited to ones that support ICE, the server can reject any offers or answers that don't indicate ICE support. Gatekeeping, but make it cute ๐
SIP user agents (UA) [RFC3261] that aren't willing to receive non-ICE answers MUST include an "ice" option tag [RFC5768] in the SIP Require header field in their offer ๐ UAs that reject non-ICE offers will usually use a 421 response code, together with an option tag "ice" in the Require header field of the response.
10. IANA Considerations
Okay, IANA time ๐ The original ICE specification defined seven new SDP attributes, following the procedures of Section 8.2.4 of [RFC4566]. The registration info from that original spec is included here, with changes to add the Mux Category [RFC8859]. This section also defines a new SDP attribute, "ice-pacing" โจ
10.1. SDP Attributes
10.1.1. "candidate" Attribute
Attribute Name: candidate
Type of Attribute: media-level
Subject to charset: No
Purpose: This attribute is used with Interactive Connectivity
Establishment (ICE), and provides one of many possible candidate
addresses for communication. These addresses are validated with
an end-to-end connectivity check using Session Traversal Utilities
for NAT (STUN).
Appropriate Values: See Section 5 of RFC 8839.
Contact Name: IESG
Contact Email: iesg@ietf.org
Reference: RFC 8839
Mux Category: TRANSPORT
10.1.2. "remote-candidates" Attribute
Attribute Name: remote-candidates
Type of Attribute: media-level
Subject to charset: No
Purpose: This attribute is used with Interactive Connectivity
Establishment (ICE), and provides the identity of the remote
candidates that the offerer wishes the answerer to use in its
answer.
Appropriate Values: See Section 5 of RFC 8839.
Contact Name: IESG
Contact Email: iesg@ietf.org
Reference: RFC 8839
Mux Category: TRANSPORT
10.1.3. "ice-lite" Attribute
Attribute Name: ice-lite
Type of Attribute: session-level
Subject to charset: No
Purpose: This attribute is used with Interactive Connectivity
Establishment (ICE), and indicates that an agent has the minimum
functionality required to support ICE inter-operation with a peer
that has a full implementation.
Appropriate Values: See Section 5 of RFC 8839.
Contact Name: IESG
Contact Email: iesg@ietf.org
Reference: RFC 8839
Mux Category: NORMAL
10.1.4. "ice-mismatch" Attribute
Attribute Name: ice-mismatch
Type of Attribute: media-level
Subject to charset: No
Purpose: This attribute is used with Interactive Connectivity
Establishment (ICE), and indicates that an agent is ICE capable,
but did not proceed with ICE due to a mismatch of candidates with
the default destination for media signaled in the SDP.
Appropriate Values: See Section 5 of RFC 8839.
Contact Name: IESG
Contact e-mail: iesg@ietf.org
Reference: RFC 8839
Mux Category: NORMAL
10.1.5. "ice-pwd" Attribute
Attribute Name: ice-pwd
Type of Attribute: session- or media-level
Subject to charset: No
Purpose: This attribute is used with Interactive Connectivity
Establishment (ICE), and provides the password used to protect
STUN connectivity checks.
Appropriate Values: See Section 5 of RFC 8839.
Contact Name: IESG
Contact e-mail: iesg@ietf.org
Reference: RFC 8839
Mux Category: TRANSPORT
10.1.6. "ice-ufrag" Attribute
Attribute Name: ice-ufrag
Type of Attribute: session- or media-level
Subject to charset: No
Purpose: This attribute is used with Interactive Connectivity
Establishment (ICE), and provides the fragments used to construct
the username in STUN connectivity checks.
Appropriate Values: See Section 5 of RFC 8839.
Contact Name: IESG
Contact e-mail: iesg@ietf.org
Reference: RFC 8839
Mux Category: TRANSPORT
10.1.7. "ice-options" Attribute
Attribute Name: ice-options
Long Form: ice-options
Type of Attribute: session-level
Subject to charset: No
Purpose: This attribute is used with Interactive Connectivity
Establishment (ICE), and indicates the ICE options or extensions
used by the agent.
Appropriate Values: See Section 5 of RFC 8839.
Contact Name: IESG
Contact e-mail: iesg@ietf.org
Reference: RFC 8839
Mux Category: NORMAL
10.1.8. "ice-pacing" Attribute ๐
okay so this one's a new SDP attribute, "ice-pacing" ๐ Here's the full spec, no cap:
Attribute Name: ice-pacing
Type of Attribute: session-level
Subject to charset: No
Purpose: This attribute is used with Interactive Connectivity
Establishment (ICE) to indicate desired connectivity check pacing
values.
Appropriate Values: See Section 5 of RFC 8839.
Contact Name: IESG
Contact e-mail: iesg@ietf.org
Reference: RFC 8839
Mux Category: NORMAL
10.2. Interactive Connectivity Establishment (ICE) Options Registry ๐ธ
bestie, IANA keeps a registry for "ice-options" identifiers ๐๏ธ New entries go in under the Specification Required policy from "Guidelines for Writing an IANA Considerations Section in RFCs" [RFC8126], so it's not a free-for-all, it's giving organized โจ
ICE options can technically be any length according to the syntax in Section 5.6 ๐ BUT they are RECOMMENDED to stay at 20 characters or less. The reason is simple: shorter means smaller messages and easier parsing, which is lowkey iconic ๐ฆ ICE options are defined at the session level.
A registration request MUST include the following info:
- The ICE option identifier you want to register ๐
- Name and email address of the organization or individuals who have change control ๐ง
- A short description of the ICE extension the option relates to ๐
- Reference(s) to the specification that defines the ICE option and the related extensions ๐
10.3. Candidate Attribute Extension Subregistry Establishment ๐
this section makes a brand new subregistry called "Candidate Attribute Extensions" ๐ It lives under the SDP Parameters registry at http://www.iana.org/assignments/sdp-parameters.
The whole point of this subregistry is to register SDP "candidate" attribute extensions ๐ง
To get in, a "candidate" extension has to meet the "Specification Required" policies defined in [RFC8126]. No shortcuts, periodt ๐
"candidate" attribute extensions MUST follow the 'cand-extension' syntax ๐ซถ The attribute extension name MUST follow the 'extension-att-name' syntax, and the attribute extension value MUST follow the 'extension-att-value' syntax. Super strict, super clean โจ
A registration request MUST include the following info:
- The name of the attribute extension ๐ท๏ธ
- Name and email address of the organization or individuals who have change control ๐ง
- A short description of the attribute extension ๐
- A reference to a specification that describes the semantics, usage, and possible values of the attribute extension ๐
11. Changes from RFC 5245 ๐
okay so the big glow-up is actually documented in [RFC8445] ๐ That one covers the changes to the common SIP procedures, like removing aggressive nomination, changing how candidate pair states are calculated, scheduling connectivity checks, and calculating timer values. Iconic behavior from that doc ๐
This document then adds its own SDP offer/answer specific changes, and here they are:
- SDP offer/answer realization and usage of the 'ice2' option ๐
- Definition and usage of the SDP "ice-pacing" attribute โญ
- Explicit text saying an ICE agent must not generate candidates with FQDNs, and must discard such candidates if it receives them from the peer agent ๐ โโ๏ธ (it's giving boundaries)
- Relaxing the requirement to include the SDP "rtcp" attribute ๐ฆ
- Generic clarifications of SDP offer/answer procedures ๐ง
- ICE mismatch is now optional. An agent can choose not to trigger mismatch and instead treat the default candidate as an additional candidate ๐
- FQDNs and "0.0.0.0"/"::" IP addresses with port "9" default candidates do not trigger ICE mismatch ๐ญ main character energy for the default candidate
12. References ๐ง
12.1. Normative References ๐
okay these are the must-reads, the ones this spec leans on hard ๐ซถ
- [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. - [RFC3261] Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston, A., Peterson, J., Sparks, R., Handley, M., and E. Schooler, "SIP: Session Initiation Protocol", RFC 3261, DOI
10.17487/RFC3261, June 2002,https://www.rfc-editor.org/info/rfc3261. - [RFC3262] Rosenberg, J. and H. Schulzrinne, "Reliability of Provisional Responses in Session Initiation Protocol (SIP)", RFC 3262, DOI
10.17487/RFC3262, June 2002,https://www.rfc-editor.org/info/rfc3262. - [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. - [RFC3312] Camarillo, G., Ed., Marshall, W., Ed., and J. Rosenberg, "Integration of Resource Management and Session Initiation Protocol (SIP)", RFC 3312, DOI
10.17487/RFC3312, October 2002,https://www.rfc-editor.org/info/rfc3312. - [RFC3556] Casner, S., "Session Description Protocol (SDP) Bandwidth Modifiers for RTP Control Protocol (RTCP) Bandwidth", RFC 3556, DOI
10.17487/RFC3556, July 2003,https://www.rfc-editor.org/info/rfc3556. - [RFC3605] Huitema, C., "Real Time Control Protocol (RTCP) attribute in Session Description Protocol (SDP)", RFC 3605, DOI
10.17487/RFC3605, October 2003,https://www.rfc-editor.org/info/rfc3605. - [RFC4032] Camarillo, G. and P. Kyzivat, "Update to the Session Initiation Protocol (SIP) Preconditions Framework", RFC 4032, DOI
10.17487/RFC4032, March 2005,https://www.rfc-editor.org/info/rfc4032. - [RFC4566] Handley, M., Jacobson, V., and C. Perkins, "SDP: Session Description Protocol", RFC 4566, DOI
10.17487/RFC4566, July 2006,https://www.rfc-editor.org/info/rfc4566. - [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. - [RFC5389] Rosenberg, J., Mahy, R., Matthews, P., and D. Wing, "Session Traversal Utilities for NAT (STUN)", RFC 5389, DOI
10.17487/RFC5389, October 2008,https://www.rfc-editor.org/info/rfc5389. - [RFC5766] Mahy, R., Matthews, P., and J. Rosenberg, "Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN)", RFC 5766, DOI
10.17487/RFC5766, April 2010,https://www.rfc-editor.org/info/rfc5766. - [RFC5768] Rosenberg, J., "Indicating Support for Interactive Connectivity Establishment (ICE) in the Session Initiation Protocol (SIP)", RFC 5768, DOI
10.17487/RFC5768, April 2010,https://www.rfc-editor.org/info/rfc5768. - [RFC6336] Westerlund, M. and C. Perkins, "IANA Registry for Interactive Connectivity Establishment (ICE) Options", RFC 6336, DOI
10.17487/RFC6336, July 2011,https://www.rfc-editor.org/info/rfc6336. - [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. - [RFC8445] Keranen, A., Holmberg, C., and J. Rosenberg, "Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal", RFC 8445, DOI
10.17487/RFC8445, July 2018,https://www.rfc-editor.org/info/rfc8445.
12.2. Informative References ๐
these are the extra-credit reads, good to know but not required ๐
- [RFC3725] Rosenberg, J., Peterson, J., Schulzrinne, H., and G. Camarillo, "Best Current Practices for Third Party Call Control (3pcc) in the Session Initiation Protocol (SIP)", BCP 85, RFC 3725, DOI
10.17487/RFC3725, April 2004,https://www.rfc-editor.org/info/rfc3725. - [RFC3960] Camarillo, G. and H. Schulzrinne, "Early Media and Ringing Tone Generation in the Session Initiation Protocol (SIP)", RFC 3960, DOI
10.17487/RFC3960, December 2004,https://www.rfc-editor.org/info/rfc3960. - [RFC5245] Rosenberg, J., "Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal for Offer/Answer Protocols", RFC 5245, DOI
10.17487/RFC5245, April 2010,https://www.rfc-editor.org/info/rfc5245. - [RFC5626] Jennings, C., Ed., Mahy, R., Ed., and F. Audet, Ed., "Managing Client-Initiated Connections in the Session Initiation Protocol (SIP)", RFC 5626, DOI
10.17487/RFC5626, October 2009,https://www.rfc-editor.org/info/rfc5626. - [RFC5898] Andreasen, F., Camarillo, G., Oran, D., and D. Wing, "Connectivity Preconditions for Session Description Protocol (SDP) Media Streams", RFC 5898, DOI
10.17487/RFC5898, July 2010,https://www.rfc-editor.org/info/rfc5898. - [RFC6679] Westerlund, M., Johansson, I., Perkins, C., O'Hanlon, P., and K. Carlberg, "Explicit Congestion Notification (ECN) for RTP over UDP", RFC 6679, DOI
10.17487/RFC6679, August 2012,https://www.rfc-editor.org/info/rfc6679. - [RFC7675] Perumal, M., Wing, D., Ravindranath, R., Reddy, T., and M. Thomson, "Session Traversal Utilities for NAT (STUN) Usage for Consent Freshness", RFC 7675, DOI
10.17487/RFC7675, October 2015,https://www.rfc-editor.org/info/rfc7675. - [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI
10.17487/RFC8126, June 2017,https://www.rfc-editor.org/info/rfc8126. - [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. - [RFC8863] Holmberg, C. and J. Uberti, "Interactive Connectivity Establishment Patiently Awaiting Connectivity (ICE PAC)", RFC 8863, DOI
10.17487/RFC8863, January 2021,https://www.rfc-editor.org/info/rfc8863.
Appendix A. Examples โจ
okay so this is the part where we get to see the whole thing actually working, bestie ๐ the example is the one from Section 15 of [RFC8445], and the offer (message 5) gets encoded in SDP. I've folded the long lines so they fit, because we are not about wrapping chaos ๐
v=0
o=jdoe 2890844526 2890842807 IN IP6 $L-PRIV-1.IP
s=
c=IN IP6 $NAT-PUB-1.IP
t=0 0
a=ice-options:ice2
a=ice-pacing:50
a=ice-pwd:asd88fgpdd777uzjYhagZg
a=ice-ufrag:8hhY
m=audio $NAT-PUB-1.PORT RTP/AVP 0
b=RS:0
b=RR:0
a=rtpmap:0 PCMU/8000
a=candidate:1 1 UDP 2130706431 $L-PRIV-1.IP $L-PRIV-1.PORT typ host
a=candidate:2 1 UDP 1694498815 $NAT-PUB-1.IP $NAT-PUB-1.PORT typ
srflx raddr $L-PRIV-1.IP rport $L-PRIV-1.PORT
Now the offer with the variables swapped for their real values, so you can see the actual bits ๐ฆ (folded again for clarity):
v=0
o=jdoe 2890844526 2890842807 IN IP6 fe80::6676:baff:fe9c:ee4a
s=
c=IN IP6 2001:db8:8101:3a55:4858:a2a9:22ff:99b9
t=0 0
a=ice-options:ice2
a=ice-pacing:50
a=ice-pwd:asd88fgpdd777uzjYhagZg
a=ice-ufrag:8hhY
m=audio 45664 RTP/AVP 0
b=RS:0
b=RR:0
a=rtpmap:0 PCMU/8000
a=candidate:1 1 UDP 2130706431 fe80::6676:baff:fe9c:ee4a 8998
typ host
a=candidate:2 1 UDP 1694498815 2001:db8:8101:3a55:4858:a2a9:22ff:99b9
45664 typ srflx raddr fe80::6676:baff:fe9c:ee4a rport 8998
And the resulting answer looks like this ๐ธ
v=0
o=bob 2808844564 2808844564 IN IP4 $R-PUB-1.IP
s=
c=IN IP4 $R-PUB-1.IP
t=0 0
a=ice-options:ice2
a=ice-pacing:50
a=ice-pwd:YH75Fviy6338Vbrhrlp8Yh
a=ice-ufrag:9uB6
m=audio $R-PUB-1.PORT RTP/AVP 0
b=RS:0
b=RR:0
a=rtpmap:0 PCMU/8000
a=candidate:1 1 UDP 2130706431 $R-PUB-1.IP $R-PUB-1.PORT typ host
With the variables filled in:
v=0
o=bob 2808844564 2808844564 IN IP4 192.0.2.1
s=
c=IN IP4 192.0.2.1
t=0 0
a=ice-options:ice2
a=ice-pacing:50
a=ice-pwd:YH75Fviy6338Vbrhrlp8Yh
a=ice-ufrag:9uB6
m=audio 3478 RTP/AVP 0
b=RS:0
b=RR:0
a=rtpmap:0 PCMU/8000
a=candidate:1 1 UDP 2130706431 192.0.2.1 3478 typ host
Appendix B. The "remote-candidates" Attribute ๐ง
okay so the remote-candidates attribute exists to kill a race condition ๐ญ between the updated offer and the STUN Binding response that moved a candidate into the valid list. Here's the drama: on receipt of message 4, agent L adds a candidate pair to the valid list. If there was only one data stream with one component, L could send an updated offer right then. BUT the check from agent R hasn't gotten its response yet, so R gets the updated offer (message 7) before the response (message 9) and doesn't know yet that the pair is valid. Not it! ๐
โโ๏ธ The fix is that the actual candidates at R that were selected by the offerer (the remote candidates) go inside the offer itself, and the answerer holds its answer until those pairs validate.
Figure 1 is the whole saga ๐
Agent L Network Agent R
|(1) Offer | |
|------------------------------------------>|
|(2) Answer | |
|<------------------------------------------|
|(3) STUN Req. | |
|------------------------------------------>|
|(4) STUN Res. | |
|<------------------------------------------|
|(5) STUN Req. | |
|<------------------------------------------|
|(6) STUN Res. | |
|-------------------->| |
| |Lost |
|(7) Offer | |
|------------------------------------------>|
|(8) STUN Req. | |
|<------------------------------------------|
|(9) STUN Res. | |
|------------------------------------------>|
|(10) Answer | |
|<------------------------------------------|
Figure 1: Race Condition Flow
Appendix C. Why Is the Conflict Resolution Mechanism Needed? ๐ค
okay bestie, so when ICE runs between two peers, one agent acts as controlled and the other as controlling. Rules are defined as a function of implementation type and offerer/answerer to decide who's who. BUT the spec says that in some cases both sides might think they're controlling, or both might think they're controlled. How?? ๐ณ
The both-controlled situation shows up in third party call control cases. Check out this flow:
A Controller B
|(1) INV() | |
|<-------------| |
|(2) 200(SDP1) | |
|------------->| |
| |(3) INV() |
| |------------->|
| |(4) 200(SDP2) |
| |<-------------|
|(5) ACK(SDP2) | |
|<-------------| |
| |(6) ACK(SDP1) |
| |------------->|
Figure 2: Role Conflict Flow
This flow is a variation on flow III of RFC 3725 [RFC3725]. Honestly it's better than flow III because it sends fewer messages ๐ The controller sends an offerless INVITE to agent A, which replies with its offer, SDP1. Then the agent sends an offerless INVITE to agent B, which replies with its offer, SDP2. The controller uses each agent's offer to generate the answers. When this flow is used, ICE runs between agents A and B, but both think they're in the controlling role. Lucky for us, with the role conflict resolution procedures, this flow works properly when ICE is used โจ
At this time there are no documented flows that can end up with both agents believing they're controlled. The conflict resolution procedures still allow for that case, just in case a flow shows up that fits ๐ซถ
Appendix D. Why Send an Updated Offer? ๐
so Section 12.1 of [RFC8445] describes the rules for sending media, and both agents can send media once ICE checks complete, without waiting for an updated offer. Honestly the only purpose of the updated offer is to "correct" the SDP so the default destination for media matches where media is actually going based on ICE (which will be the highest-priority nominated candidate pair) ๐ฏ
BUT why is the updated offer/answer exchange even needed?? In a pure offer/answer environment it wouldn't be. The offerer and answerer agree on the candidates through ICE and then start using them. As far as the agents themselves are concerned, the updated offer gives no new info. In practice though, loads of components along the signaling path read the SDP, like entities doing off-path QoS reservations, NAT traversal components such as ALGs and Session Border Controllers (SBCs), and diagnostic tools that passively monitor the network. For those tools to keep working without changes, the core property of SDP has to stay: the existing, pre-ICE definitions of the media addresses (the "m=" and "c=" lines and the "rtcp" attribute) must be retained. That's why an updated offer must be sent ๐
Acknowledgements ๐
okay so a big chunk of this document was taken from [RFC5245], written by Jonathan Rosenberg. Some of it was also taken from [RFC6336], written by Magnus Westerlund and Colin Perkins ๐ซถ
Many thanks to Flemming Andreasen for the shepherd review feedback ๐
Thanks also to these experts for their reviews and constructive feedback: Thomas Stach, Adam Roach, Peter Saint-Andre, Roman Danyliw, Alissa Cooper, Benjamin Kaduk, Mirja Kรผhlewind, Alexey Melnikov, and รric Vyncke for their detailed reviews ๐
Contributors ๐ธ
The following experts contributed textual and structural improvements for this work:
Thomas Stach
Email: thomass.stach@gmail.com
Authors' Addresses ๐ฆ
Marc Petit-Huguenin Impedance Mismatch
Email: marc@petit-huguenin.org
Suhas Nandakumar Cisco Systems 707 Tasman Dr Milpitas, CA 95035 United States of America
Email: snandaku@cisco.com
Christer Holmberg Ericsson Hirsalantie 11 FI-02420 Jorvas Finland
Email: christer.holmberg@ericsson.com
Ari Kerรคnen Ericsson FI-02420 Jorvas Finland
Email: ari.keranen@ericsson.com
Roman Shpount TurboBridge 4905 Del Ray Avenue, Suite 300 Bethesda, MD 20814 United States of America
Email: rshpount@turbobridge.com
๐ฆ where this page comes from
- ietf: rfc8839 2021-01
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms