XEP-0371: migrate from RFC 5245 to 8445

* Replaced RFC 5245 with RFC 8445
* Introduced ice2 transport attribute for backward compatibility
* Clarified ICE restart procedure
* Clarified remote-candidate usafe with "urn:ietf:rfc:3264"
* Changed remote-candidate notification procedure (sent all at once now)
* Replaced wrong reference to RFC 6455 with correct one: RFC 6544
This commit is contained in:
Sergey Ilinykh 2020-03-11 10:05:23 +03:00 committed by Jonas Schäfer
parent 0ca62351d4
commit a87b76628b
1 changed files with 186 additions and 90 deletions

View File

@ -17,7 +17,7 @@
<dependencies> <dependencies>
<spec>XMPP Core</spec> <spec>XMPP Core</spec>
<spec>XEP-0166</spec> <spec>XEP-0166</spec>
<spec>RFC 5245</spec> <spec>RFC 8445</spec>
<spec>RFC 6544</spec> <spec>RFC 6544</spec>
<spec>draft-ietf-ice-trickle</spec> <spec>draft-ietf-ice-trickle</spec>
</dependencies> </dependencies>
@ -27,6 +27,22 @@
<supersededby/> <supersededby/>
<shortname>jingle-ice</shortname> <shortname>jingle-ice</shortname>
&stpeter; &stpeter;
<revision>
<version>0.3</version>
<date>2020-05-14</date>
<initials>rion</initials>
<remark>
<ul>
<li>Replaced RFC 5245 with RFC 8445</li>
<li>Introduced ice2 transport attribute for backward compatibility</li>
<li>Clarified ICE restart procedure</li>
<li>Clarified remote-candidate usage</li>
<li>Changed remote-candidate notification procedure (sent all at once now)</li>
<li>Replaced wrong reference to RFC 6455 with correct one: RFC 6544</li>
<li>Allow sharing &lt;gathering-complete/&gt; element with remaining candidates</li>
</ul>
</remark>
</revision>
<revision> <revision>
<version>0.2.1</version> <version>0.2.1</version>
<date>2019-07-30</date> <date>2019-07-30</date>
@ -51,7 +67,7 @@
<initials>psa</initials> <initials>psa</initials>
<remark> <remark>
<ul> <ul>
<li>Added a 'tcptype' attribute to support ICE-TCP (RFC 6544) instead of overloading the existing 'type' attribute, with values of "active", "passive", and "so".</li> <li>Added a 'tcptype' attribute to support ICE-TCP (&rfc6544;) instead of overloading the existing 'type' attribute, with values of "active", "passive", and "so".</li>
<li>Modified the syntax of the end-of-candidates indication so that it is wrapped in a &lt;transport/&gt; element in the same namespace.</li> <li>Modified the syntax of the end-of-candidates indication so that it is wrapped in a &lt;transport/&gt; element in the same namespace.</li>
</ul> </ul>
</remark> </remark>
@ -63,7 +79,7 @@
<remark> <remark>
<ul> <ul>
<li>Forked from XEP-0176 (see that specification for older revision history).</li> <li>Forked from XEP-0176 (see that specification for older revision history).</li>
<li>Added support for ICE-TCP (RFC 6544), specifically by allowing a value of "tcp" for the 'protocol' attribute and values of "tcp-active", "tcp-passive", and "tcp-so" for the 'type' attribute.</li> <li>Added support for ICE-TCP (&rfc6544;), specifically by allowing a value of "tcp" for the 'protocol' attribute and values of "tcp-active", "tcp-passive", and "tcp-so" for the 'type' attribute.</li>
<li>Changed title from ICE-UDP to ICE, but retained namespace name for backward compatibility.</li> <li>Changed title from ICE-UDP to ICE, but retained namespace name for backward compatibility.</li>
<li>Corrected data type of foundation attribute from xs:unsignedByte to xs:string.</li> <li>Corrected data type of foundation attribute from xs:unsignedByte to xs:string.</li>
<li>Added a note about not mapping ice-options because it is not needed in XMPP.</li> <li>Added a note about not mapping ice-options because it is not needed in XMPP.</li>
@ -77,18 +93,18 @@
</header> </header>
<section1 topic='Introduction' anchor='intro'> <section1 topic='Introduction' anchor='intro'>
<p>&xep0166; defines a framework for negotiating and managing out-of-band data sessions over XMPP. In order to provide a flexible framework, the base Jingle specification defines neither data transport methods nor application formats, leaving that up to separate specifications.</p> <p>&xep0166; defines a framework for negotiating and managing out-of-band data sessions over XMPP. In order to provide a flexible framework, the base Jingle specification defines neither data transport methods nor application formats, leaving that up to separate specifications.</p>
<p>The current document defines a transport method for establishing and managing data exchanges between XMPP entities by means of the Interactive Connectivity Establishment (ICE) methodology specified in &rfc5245;. The Jingle usage of ICE was also the first technology to send ICE candidates incrementally, a technique that has since become known as "Trickle ICE" &trickle;.</p> <p>The current document defines a transport method for establishing and managing data exchanges between XMPP entities by means of the Interactive Connectivity Establishment (ICE) methodology specified in &rfc8445;. The Jingle usage of ICE was also the first technology to send ICE candidates incrementally, a technique that has since become known as "Trickle ICE" &trickle;.</p>
<p>The process for ICE negotiation is largely the same in Jingle as it is in RFC 5245. There are several differences:</p> <p>The process for ICE negotiation is largely the same in Jingle as it is in &rfc8445;. There are several differences:</p>
<ul> <ul>
<li>Instead of using the Session Initiation Protocol (SIP) as the signalling channel, Jingle uses XMPP as the signalling channel.</li> <li>Instead of using the Session Initiation Protocol (SIP) as the signalling channel, Jingle uses XMPP as the signalling channel.</li>
<li>Syntax from the Session Description Protocol (see &rfc4566;) is mapped to an XML syntax suitable for sending over the XMPP signalling channel.</li> <li>Syntax from the Session Description Protocol (see &rfc4566;) is mapped to an XML syntax suitable for sending over the XMPP signalling channel.</li>
<li>In Jingle, lists of "preferred" candidates are typically sent in the Jingle session-initiate and session-accept messages, in a way that is consistent with the SDP offer / answer model described in &rfc3264; and the process described in RFC 5245.</li> <li>In Jingle, lists of "preferred" candidates are typically sent in the Jingle session-initiate and session-accept messages, in a way that is consistent with the SDP offer / answer model described in &rfc3264; and the process described in &rfc8445;.</li>
<li>Candidates can also be sent in separate transport-info messages either before sending or receiving the session-accept message (to expedite negotiation) or after media begins to flow (to find modify existing candidates, find superior candidates, or adjust to changing network conditions). This usage, which has been part of the Jingle ICE transport method since 2005, has since come to be known as "Trickle ICE"; as defined here the usage is consistent with the IETF specification for Trickle ICE &trickle;.</li> <li>Candidates can also be sent in separate transport-info messages either before sending or receiving the session-accept message (to expedite negotiation) or after media begins to flow (to find modify existing candidates, find superior candidates, or adjust to changing network conditions). This usage, which has been part of the Jingle ICE transport method since 2005, has since come to be known as "Trickle ICE"; as defined here the usage is consistent with the IETF specification for Trickle ICE &trickle;.</li>
</ul> </ul>
<p>As originally defined in XEP-0166 and then &xep0176; the use of ICE in Jingle applied only to negotiations that established a User Datagram Protocol association (see &rfc0768;) and thus resulted in a Jingle datagram transport suitable for media applications where some packet loss is tolerable (e.g., audio and video). However, since the publication of &rfc6544; in 2012 it has also been possible to exchange Transmission Control Protocol (see &rfc0793;) candidates during ICE negotiation. Therefore this document expands the use of ICE in Jingle to also establish a TCP connection and thus result in a Jingle stream transport suitable for media applications where packet loss cannot be tolerated (e.g., file transfer). To reduce the possibility of confusion, the expanded definition provided here is specified in a new XEP, which is intended to supersede XEP-0176.</p> <p>As originally defined in XEP-0166 and then &xep0176; the use of ICE in Jingle applied only to negotiations that established a User Datagram Protocol association (see &rfc0768;) and thus resulted in a Jingle datagram transport suitable for media applications where some packet loss is tolerable (e.g., audio and video). However, since the publication of &rfc6544; in 2012 it has also been possible to exchange Transmission Control Protocol (see &rfc0793;) candidates during ICE negotiation. Therefore this document expands the use of ICE in Jingle to also establish a TCP connection and thus result in a Jingle stream transport suitable for media applications where packet loss cannot be tolerated (e.g., file transfer). To reduce the possibility of confusion, the expanded definition provided here is specified in a new XEP, which is intended to supersede XEP-0176.</p>
</section1> </section1>
<section1 topic='Glossary' anchor='terms'> <section1 topic='Glossary' anchor='terms'>
<p>The reader is referred to RFC 5245 and draft-ietf-ice-trickle for a description of various terms used in the context of ICE. Those terms are not reproduced here.</p> <p>The reader is referred to &rfc8445; and draft-ietf-ice-trickle for a description of various terms used in the context of ICE. Those terms are not reproduced here.</p>
</section1> </section1>
<section1 topic='Requirements' anchor='reqs'> <section1 topic='Requirements' anchor='reqs'>
<p>The Jingle transport method defined herein is designed to meet the following requirements:</p> <p>The Jingle transport method defined herein is designed to meet the following requirements:</p>
@ -134,7 +150,7 @@ INITIATOR RESPONDER
|<------------------------------------>| |<------------------------------------>|
| | | |
]]></code> ]]></code>
<p>Note: The examples in this document follow the scenario described in Section 17 of RFC 5245, except that we substitute the Shakespearean characters "Romeo" and "Juliet" for the generic entities "L" and "R".</p> <p>Note: The examples in this document follow the scenario described in Section 15 of &rfc8445;, except that we substitute the Shakespearean characters "Romeo" and "Juliet" for the generic entities "L" and "R".</p>
</section2> </section2>
<section2 topic='Session Initiation' anchor='protocol-initiate'> <section2 topic='Session Initiation' anchor='protocol-initiate'>
<p>In order for the initiator in a Jingle exchange to start the negotiation, it sends a Jingle "session-initiate" stanza that includes at least one content type, as described in <cite>XEP-0166</cite>. If the initiator wishes to negotiate the ICE transport method for an application format, it MUST include a &TRANSPORT; child element qualified by the 'urn:xmpp:jingle:transports:ice:0' namespace &VNOTE;. This element SHOULD in turn contain one &CANDIDATE; element for each of the initiator's higher-priority transport candidates as determined in accordance with the ICE methodology, but MAY instead be empty (with each candidate to be sent as the payload of a transport-info message).</p> <p>In order for the initiator in a Jingle exchange to start the negotiation, it sends a Jingle "session-initiate" stanza that includes at least one content type, as described in <cite>XEP-0166</cite>. If the initiator wishes to negotiate the ICE transport method for an application format, it MUST include a &TRANSPORT; child element qualified by the 'urn:xmpp:jingle:transports:ice:0' namespace &VNOTE;. This element SHOULD in turn contain one &CANDIDATE; element for each of the initiator's higher-priority transport candidates as determined in accordance with the ICE methodology, but MAY instead be empty (with each candidate to be sent as the payload of a transport-info message).</p>
@ -158,7 +174,8 @@ INITIATOR RESPONDER
</description> </description>
<transport xmlns='urn:xmpp:jingle:transports:ice:0' <transport xmlns='urn:xmpp:jingle:transports:ice:0'
pwd='asd88fgpdd777uzjYhagZg' pwd='asd88fgpdd777uzjYhagZg'
ufrag='8hhy'> ufrag='8hhy'
ice2='true'>
<candidate component='1' <candidate component='1'
foundation='2B78DADC1A9E' foundation='2B78DADC1A9E'
generation='0' generation='0'
@ -188,7 +205,9 @@ INITIATOR RESPONDER
]]></example> ]]></example>
</section2> </section2>
<section2 topic='Syntax' anchor='protocol-syntax'> <section2 topic='Syntax' anchor='protocol-syntax'>
<p>The &TRANSPORT; element's 'pwd' and 'ufrag' attributes MUST be included whenever sending one or more candidates to the other party, e.g., in a session-initiate, session-accept, transport-info, content-add, or transport-replace message. The values for these attributes are separately generated for both the initiator and the responder, in accordance with RFC 5245 and as shown in the examples. The attributes of the &lt;transport/&gt; element are as follows.</p> <p>The &TRANSPORT; element's 'pwd' and 'ufrag' attributes MUST be included whenever sending one or more candidates to the other party, e.g., in a session-initiate, session-accept, transport-info, content-add, or transport-replace message. The values for these attributes are separately generated for both the initiator and the responder, in accordance with &rfc8445; and as shown in the examples.</p>
<p>'ice2' attribute tells about compliancy with &rfc8445;. If the attribute is not set or set to 'false' in &TRANSPORT; element, the recipient can assume &rfc5245;. The value of the attribute may not be changed during lifetime of the transport instance, but it's not an error to skip the attribute in consequent transport-info updates.</p>
<p>The attributes of the &lt;transport/&gt; element are as follows.</p>
<table caption='Transport Attributes'> <table caption='Transport Attributes'>
<tr> <tr>
<th>Name</th> <th>Name</th>
@ -198,16 +217,22 @@ INITIATOR RESPONDER
</tr> </tr>
<tr> <tr>
<td>pwd</td> <td>pwd</td>
<td>A Password as defined in RFC 5245.</td> <td>A Password as defined in &rfc8445;.</td>
<td>a=ice-pwd line</td> <td>a=ice-pwd line</td>
<td>asd88fgpdd777uzjYhagZg</td> <td>asd88fgpdd777uzjYhagZg</td>
</tr> </tr>
<tr> <tr>
<td>ufrag</td> <td>ufrag</td>
<td>A User Fragment as defined in RFC 5245.</td> <td>A Username Fragment as defined in &rfc8445;.</td>
<td>a=ice-ufrag line</td> <td>a=ice-ufrag line</td>
<td>8hhy</td> <td>8hhy</td>
</tr> </tr>
<tr>
<td>ice2</td>
<td>ice2 option as defined in &rfc8445;.</td>
<td>a=ice-options:ice2</td>
<td>true</td>
</tr>
</table> </table>
<p>The attributes of the &lt;candidate/&gt; element are as follows.</p> <p>The attributes of the &lt;candidate/&gt; element are as follows.</p>
<table caption='Candidate Attributes'> <table caption='Candidate Attributes'>
@ -219,13 +244,13 @@ INITIATOR RESPONDER
</tr> </tr>
<tr> <tr>
<td>component</td> <td>component</td>
<td>A Component ID as defined in RFC 5245.</td> <td>A Component ID as defined in &rfc8445;.</td>
<td>Component ID value in a=candidate line</td> <td>Component ID value in a=candidate line</td>
<td>1</td> <td>1</td>
</tr> </tr>
<tr> <tr>
<td>foundation</td> <td>foundation</td>
<td>A Foundation as defined in RFC 5245. (Note that version 1.0 of this specification container an error, whereby the data type for the Jingle 'foundation' attribute was defined as xs:unsignedByte; in version 1.1 this was corrected to xs:string, however some existing implementations might not use or expect strings.)</td> <td>A Foundation as defined in &rfc8445;. (Note that version 1.0 of this specification container an error, whereby the data type for the Jingle 'foundation' attribute was defined as xs:unsignedByte; in version 1.1 this was corrected to xs:string, however some existing implementations might not use or expect strings.)</td>
<td>Foundation value in a=candidate line</td> <td>Foundation value in a=candidate line</td>
<td>2B78DADC1A9E</td> <td>2B78DADC1A9E</td>
</tr> </tr>
@ -261,44 +286,43 @@ INITIATOR RESPONDER
</tr> </tr>
<tr> <tr>
<td>priority</td> <td>priority</td>
<td>A Priority as defined in RFC 5245. <td>A Priority as defined in &rfc8445;.
<note>In accordance with the rules specified in Section 4.1.1 of RFC 5245, the priority values shown in the examples within this document have been calculated as follows. The "type preference" for host candidates is stipulated to be "126" and for server reflexive candidates "100". The "local preference" for network 0 is stipulated to be "4096", for network 1 "2048", and for network 2 "1024".</note> <note>In accordance with the rules specified in Section 5.1.2 of &rfc8445;, the priority values shown in the examples within this document have been calculated as follows. The "type preference" for host candidates is stipulated to be "126", "110" for peer reflexive and for server reflexive candidates "100". The "local preference" for network 0 is stipulated to be "4096", for network 1 "2048", and for network 2 "1024".</note>
</td> </td>
<td>Priority value in a=candidate line</td> <td>Priority value in a=candidate line</td>
<td>2130706431</td> <td>2130706431</td>
</tr> </tr>
<tr> <tr>
<td>protocol</td> <td>protocol</td>
<td>The protocol to be used. The values allowed by this specification are "udp" (see RFC 5245) and "tcp" (see RFC 6455).</td> <td>The protocol to be used. The values allowed by this specification are "udp" (see &rfc8445;) and "tcp" (see &rfc6544;).</td>
<td>Transport protocol field in a=candidate line</td> <td>Transport protocol field in a=candidate line</td>
<td>udp</td> <td>udp</td>
</tr> </tr>
<tr> <tr>
<td>rel-addr</td> <td>rel-addr</td>
<td>A related address as defined in RFC 5245.</td> <td>A related address as defined in &rfc8445;.</td>
<td>Value of raddr attribute in a=candidate line</td> <td>Value of raddr attribute in a=candidate line</td>
<td>10.0.1.1</td> <td>10.0.1.1</td>
</tr> </tr>
<tr> <tr>
<td>rel-port</td> <td>rel-port</td>
<td>A related port as defined in RFC 5245.</td> <td>A related port as defined in &rfc8445;.</td>
<td>Value of rport attribute in a=candidate line</td> <td>Value of rport attribute in a=candidate line</td>
<td>8998</td> <td>8998</td>
</tr> </tr>
<tr> <tr>
<td>tcptype</td> <td>tcptype</td>
<td>A TCP candidate type as defined in RFC 6455. The allowable values are "active" for TCP active candidates, "passive" for TCP passive candidates, and "so" for TCP simultaneous-open candidates.</td> <td>A TCP candidate type as defined in &rfc6544;. The allowable values are "active" for TCP active candidates, "passive" for TCP passive candidates, and "so" for TCP simultaneous-open candidates.</td>
<td>Value of tcptype attribute in a=candidate line</td> <td>Value of tcptype attribute in a=candidate line</td>
<td>so</td> <td>so</td>
</tr> </tr>
<tr> <tr>
<td>type</td> <td>type</td>
<td>An ICE candidate type as defined in RFC 5245. The allowable values are "host" for host candidates, "prflx" for peer reflexive candidates, "relay" for relayed candidates, and "srflx" for server reflexive candidates. Note that TCP candidate types (RFC 6455) are handled via the 'tcptype' attribute.</td> <td>An ICE candidate type as defined in &rfc8445;. The allowable values are "host" for host candidates, "prflx" for peer reflexive candidates, "relay" for relayed candidates, and "srflx" for server reflexive candidates. Note that TCP candidate types (&rfc6544;) are handled via the 'tcptype' attribute.</td>
<td>Value of typ attribute in a=candidate line</td> <td>Value of typ attribute in a=candidate line</td>
<td>srflx</td> <td>srflx</td>
</tr> </tr>
</table> </table>
<p>Note this specification does not provide an equivalent of the "ice-options" attribute defined in Section 15.5 of RFC 5245, since it is not needed in XMPP given the existence of the Service Discovery extension (XEP-0030).</p>
</section2> </section2>
<section2 topic='Response' anchor='protocol-response'> <section2 topic='Response' anchor='protocol-response'>
<p>As described in <cite>XEP-0166</cite>, to acknowledge receipt of the session initiation request, the responder immediately returns an IQ-result.</p> <p>As described in <cite>XEP-0166</cite>, to acknowledge receipt of the session initiation request, the responder immediately returns an IQ-result.</p>
@ -346,90 +370,153 @@ INITIATOR RESPONDER
</section2> </section2>
<section2 topic='Candidate Negotiation' anchor='protocol-candidates'> <section2 topic='Candidate Negotiation' anchor='protocol-candidates'>
<p>The initiator and responder negotiate connectivity over ICE by exchanging XML-formatted transport candidates for the channel. This negotiation proceeds immediately in order to maximize the possibility that connectivity can be established (and therefore media can be exchanged) as quickly as possible. In order to expedite session establishment, the initiator SHOULD include transport candidates in its session-initiate message but MAY also send additional transport candidates as soon as it learns of them, even before receiving the IQ-result that acknowledges the session-initiate message (i.e., the initiator MUST consider the session to be live as soon as it sends the session-initiate message). <note>Given in-order delivery as mandated by &xmppcore;, the responder will receive such transport-info messages after receiving the session-initiate message; if not, it is appropriate for the responder to return &lt;unknown-session/&gt; errors since according to its state machine the session does not exist.</note></p> <p>The initiator and responder negotiate connectivity over ICE by exchanging XML-formatted transport candidates for the channel. This negotiation proceeds immediately in order to maximize the possibility that connectivity can be established (and therefore media can be exchanged) as quickly as possible. In order to expedite session establishment, the initiator SHOULD include transport candidates in its session-initiate message but MAY also send additional transport candidates as soon as it learns of them, even before receiving the IQ-result that acknowledges the session-initiate message (i.e., the initiator MUST consider the session to be live as soon as it sends the session-initiate message). <note>Given in-order delivery as mandated by &xmppcore;, the responder will receive such transport-info messages after receiving the session-initiate message; if not, it is appropriate for the responder to return &lt;unknown-session/&gt; errors since according to its state machine the session does not exist.</note></p>
<p>The first step in negotiating connectivity is for each party to send transport candidates to the other party. <note>The fact that both parties send candidates means that Jingle requires each party to be a full implementation of ICE, not a lite implementation as specified in RFC 5245.</note> These candidates SHOULD be gathered by following the procedure specified in Section 4.1.1 of RFC 5245 (typically by communicating with a standalone STUN server in order to discover the client's public IP address and port) and prioritized by following the procedure specified in Section 4.1.2 of RFC 5245.</p> <p>The first step in negotiating connectivity is for each party to send transport candidates to the other party. <note>The fact that both parties send candidates means that Jingle requires each party to be a full implementation of ICE, not a lite implementation as specified in &rfc8445;.</note> These candidates SHOULD be gathered by following the procedure specified in Section 5.1.1 of &rfc8445; (typically by communicating with a standalone STUN server in order to discover the client's public IP address and port) and prioritized by following the procedure specified in Section 5.1.2 of &rfc8445;.</p>
<p>Each candidate shall be sent as a &lt;candidate/&gt; child of a &TRANSPORT; element qualified by the 'urn:xmpp:jingle:transports:ice:0' namespace. The &TRANSPORT; element is sent via a Jingle message of type session-initiate, session-accept, or transport-info.</p> <p>Each candidate shall be sent as a &lt;candidate/&gt; child of a &TRANSPORT; element qualified by the 'urn:xmpp:jingle:transports:ice:0' namespace. The &TRANSPORT; element is sent via a Jingle message of type session-initiate, session-accept, or transport-info.</p>
<p>Either party MAY include multiple &lt;candidate/&gt; elements in one &TRANSPORT; element, especially in the session-initiate and session-accept messages sent at the beginning of the session negotiation. Including multiple candidates in the session-initiate and session-accept messages can help to ensure interoperability with entities that implement the SDP offer/answer model described in <cite>RFC 3264</cite>; in particular, an entity SHOULD include multiple candidates in its session-initiate or session-accept message if the other party advertises support for the "urn:ietf:rfc:3264" service discovery feature as described in the <link url='#support-sdp'>SDP Offer / Answer Support</link> section of this document. However, including one candidate per subsequent transport-info message typically results in a faster negotiation because the candidates most likely to succeed are sent first (in the session-info and session-accept messages) and it is not necessary to gather all candidates before beginning to send any candidates; furthermore, because certain candidates can be more "expensive" in terms of bandwidth or processing power, either party might not want to advertise the existence of such candidates unless it is necessary to do so after other candidates have failed.</p> <p>Either party MAY include multiple &lt;candidate/&gt; elements in one &TRANSPORT; element, especially in the session-initiate and session-accept messages sent at the beginning of the session negotiation. Including multiple candidates in the session-initiate and session-accept messages can help to ensure interoperability with entities that implement the SDP offer/answer model described in <cite>RFC 3264</cite>; in particular, an entity SHOULD include multiple candidates in its session-initiate or session-accept message if the other party advertises support for the "urn:ietf:rfc:3264" service discovery feature as described in the <link url='#support-sdp'>SDP Offer / Answer Support</link> section of this document. However, including one candidate per subsequent transport-info message typically results in a faster negotiation because the candidates most likely to succeed are sent first (in the session-info and session-accept messages) and it is not necessary to gather all candidates before beginning to send any candidates; furthermore, because certain candidates can be more "expensive" in terms of bandwidth or processing power, either party might not want to advertise the existence of such candidates unless it is necessary to do so after other candidates have failed.</p>
<p>If the party that receives a candidate in a Jingle message can successfully process a given candidate or set of candidates, it returns an IQ-result (if not, for example because the candidate data is improperly formatted, it returns an IQ-error). At this point, the receiving entity is only indicating receipt of the candidate or set of candidates, not telling the other party that the candidate will be used.</p> <p>If the party that receives a candidate in a Jingle message can successfully process a given candidate or set of candidates, it returns an IQ-result (if not, for example because the candidate data is improperly formatted, it returns an IQ-error). At this point, the receiving entity is only indicating receipt of the candidate or set of candidates, not telling the other party that the candidate will be used.</p>
<p>The initiator can keep sending candidates (without stopping to receive an acknowledgement of receipt from the responder for each candidate) until it has exhausted its supply of possible or desirable transport candidates. The responder can also keep sending potential candidates, which the initiator will acknowledge.</p> <p>The initiator can keep sending candidates (without stopping to receive an acknowledgement of receipt from the responder for each candidate) until it has exhausted its supply of possible or desirable transport candidates. The responder can also keep sending potential candidates, which the initiator will acknowledge.</p>
</section2> </section2>
<section2 topic='Connectivity Checks' anchor='protocol-checks'> <section2 topic='Connectivity Checks' anchor='protocol-checks'>
<p>As the initiator and responder receive candidates, they probe the candidates for connectivity. In performing these connectivity checks, each party SHOULD follow the procedure specified in Section 7 of RFC 5245. The following business rules apply:</p> <p>As the initiator and responder receive candidates, they probe the candidates for connectivity. In performing these connectivity checks, each party SHOULD follow the procedure specified in Section 7 of &rfc8445;. The following business rules apply:</p>
<ol> <ol>
<li>Each party sends a STUN Binding Request (see &rfc5389;) from each local candidate it generated to each remote candidate it received.</li> <li>Each party sends a STUN Binding Request (see &rfc5389;) from each local candidate it generated to each remote candidate it received.</li>
<li>In accordance with RFC 5245, the STUN Binding Requests MUST include the PRIORITY attribute (computed according to Section 7.1.1.1. of RFC 5245).</li> <li>In accordance with &rfc8445;, the STUN Binding Requests MUST include the PRIORITY attribute (computed according to Section 7.1.2.1. of &rfc8445;).</li>
<li>For the purposes of the Jingle ICE Transport Method, both parties are full ICE implementations and therefore the controlling role MUST be assumed by the initiator and the controlled role MUST be assumed by the responder.</li> <li>For the purposes of the Jingle ICE Transport Method, both parties are full ICE implementations and therefore the controlling role MUST be assumed by the initiator and the controlled role MUST be assumed by the responder.</li>
<li>The STUN Binding Requests generated by the initiator MAY include the USE-CANDIDATE attribute to indicate that the initiator wishes to cease checks for this component.</li> <li>The STUN Binding Requests generated by the initiator MAY include the USE-CANDIDATE attribute to indicate that the initiator wishes to cease checks for this component.</li>
<li>The STUN Binding Requests generated by the initiator MUST include the ICE-CONTROLLING attribute.</li> <li>The STUN Binding Requests generated by the initiator MUST include the ICE-CONTROLLING attribute.</li>
<li>The STUN Binding Requests generated by the responder MUST include the ICE-CONTROLLED attribute.</li> <li>The STUN Binding Requests generated by the responder MUST include the ICE-CONTROLLED attribute.</li>
<li>The parties MUST use STUN short term credentials to authenticate requests and perform message integrity checks. As in RFC 5245, the username in the STUN Binding Request is of the form "ufrag-of-peer:ufrag-of-sender" and the password is the value of the 'pwd' attribute provided by the peer. <note>Thus when Romeo sends a STUN Binding Request to Juliet the credentials will be STUN username "9uB6:8hhy" (ufrag provided by Juliet concatenated with ufrag provided by Romeo) and password "YH75Fviy6338Vbrhrlp8Yh" (pwd provided by Juliet) whereas when Juliet sends a STUN Binding Request to Romeo the credentials will be STUN username "8hhy:9uB6" (ufrag provided by Romeo concatenated with ufrag provided by Juliet) and password "asd88fgpdd777uzjYhagZg" (pwd provided by Romeo).</note></li> <li>The parties MUST use STUN short term credentials to authenticate requests and perform message integrity checks. As in &rfc8445;, the username in the STUN Binding Request is of the form "ufrag-of-peer:ufrag-of-sender" and the password is the value of the 'pwd' attribute provided by the peer. <note>Thus when Romeo sends a STUN Binding Request to Juliet the credentials will be STUN username "9uB6:8hhy" (ufrag provided by Juliet concatenated with ufrag provided by Romeo) and password "YH75Fviy6338Vbrhrlp8Yh" (pwd provided by Juliet) whereas when Juliet sends a STUN Binding Request to Romeo the credentials will be STUN username "8hhy:9uB6" (ufrag provided by Romeo concatenated with ufrag provided by Juliet) and password "asd88fgpdd777uzjYhagZg" (pwd provided by Romeo).</note></li>
</ol> </ol>
<p>When it receives a STUN Binding Request, each party MUST return a STUN Binding Response, which indicates either an error case or the success case. As described in Section 7.1.2.2 of RFC 5245, a connectivity check succeeds if <em>all</em> of the following are true:</p> <p>When it receives a STUN Binding Request, each party MUST return a STUN Binding Response, which indicates either an error case or the success case. As described in Section 7.2.5.3 of &rfc8445;, a connectivity check succeeds if <em>all</em> of the following are true:</p>
<ol> <ol>
<li>The STUN transaction generated a success response.</li> <li>The Binding request generated a success response.</li>
<li>The source IP address and port of the response equals the destination IP address and port to which the Binding Request was sent.</li> <li>The source and destination transport addresses in the Binding request and response are symmetric.</li>
<li>The destination IP address and port of the response match the source IP address and port from which the Binding Request was sent.</li>
</ol> </ol>
<p>For the candidates exchanged in the previous section, the connectivity checks would be as follows (this diagram mirrors the example in RFC 5245).</p> <p>For the candidates exchanged in the previous section, the connectivity checks would be as follows (this diagram mirrors the example from section 15.1 of &rfc8445;).</p>
<code><![CDATA[ <code><![CDATA[
INITIATOR NAT RESPONDER ENTITY IP Address Mnemonic name
| | | --------------------------------------------------
| | STUN Binding Request | ICE Agent L (Initiator): 10.0.1.1 L-PRIV-1
| | from 192.0.2.1:3478 | ICE Agent R (Responder): 192.0.2.1 R-PUB-1
| | to 10.0.1.1:8998 | STUN Server: 192.0.2.2 STUN-PUB-1
| | (dropped) | NAT (Public): 192.0.2.3 NAT-PUB-1
| | x====================|
| STUN Binding Request | |
| from 10.0.1.1:8998 | | L NAT STUN R
| to 192.0.2.1:3478 | | |STUN alloc. | | |
| USE-CANDIDATE | | |(1) STUN Req | | |
|======================>| | |S=$L-PRIV-1 | | |
| | STUN Binding Request | |D=$STUN-PUB-1 | | |
| | from 192.0.2.3:45664 | |------------->| | |
| | to 192.0.2.1:3478 | | |(2) STUN Req | |
| | USE-CANDIDATE | | |S=$NAT-PUB-1 | |
| |======================>| | |D=$STUN-PUB-1 | |
| | STUN Binding Response | | |------------->| |
| | from 192.0.2.1:3478 | | |(3) STUN Res | |
| | to 192.0.2.3:45664 | | |S=$STUN-PUB-1 | |
| |<======================| | |D=$NAT-PUB-1 | |
| STUN Binding Response | | | |MA=$NAT-PUB-1 | |
| from 192.0.2.1:3478 | | | |<-------------| |
| to 10.0.1.1:8998 | | |(4) STUN Res | | |
| map 192.0.2.3:45664 | | |S=$STUN-PUB-1 | | |
|<======================| | |D=$L-PRIV-1 | | |
| | | |MA=$NAT-PUB-1 | | |
|<==Media Now Can Flow==| | |<-------------| | |
| | | |(5) L's Candidate Information| |
| | STUN Binding Request | |------------------------------------------->|
| | from 192.0.2.1:3478 | | | | | STUN
| | to 192.0.2.3:45664 | | | | | alloc.
| |<======================| | | |(6) STUN Req |
| STUN Binding Request | | | | |S=$R-PUB-1 |
| from 192.0.2.1:3478 | | | | |D=$STUN-PUB-1 |
| to 10.0.1.1:8998 | | | | |<-------------|
|<======================| | | | |(7) STUN Res |
| STUN Binding Response | | | | |S=$STUN-PUB-1 |
| from 10.0.1.1:8998 | | | | |D=$R-PUB-1 |
| to 192.0.2.1:3478 | | | | |MA=$R-PUB-1 |
| map 192.0.2.1:3478 | | | | |------------->|
|======================>| | |(8) R's Candidate Information| |
| | STUN Binding Response | |<-------------------------------------------|
| | from 192.0.2.3:45664 | | | (9) Bind Req |Begin
| | to 192.0.2.1:3478 | | | S=$R-PUB-1 |Connectivity
| | map 192.0.2.1:3478 | | | D=$L-PRIV-1 |Checks
| |======================>| | | <-------------------|
| | | | | Dropped |
| |==Media Now Can Flow==>| |(10) Bind Req | | |
| | | |S=$L-PRIV-1 | | |
|D=$R-PUB-1 | | |
|------------->| | |
| |(11) Bind Req | |
| |S=$NAT-PUB-1 | |
| |D=$R-PUB-1 | |
| |---------------------------->|
| |(12) Bind Res | |
| |S=$R-PUB-1 | |
| |D=$NAT-PUB-1 | |
| |MA=$NAT-PUB-1 | |
| |<----------------------------|
|(13) Bind Res | | |
|S=$R-PUB-1 | | |
|D=$L-PRIV-1 | | |
|MA=$NAT-PUB-1 | | |
|<-------------| | |
|Data | | |
|===========================================>|
| | | |
| |(14) Bind Req | |
| |S=$R-PUB-1 | |
| |D=$NAT-PUB-1 | |
| |<----------------------------|
|(15) Bind Req | | |
|S=$R-PUB-1 | | |
|D=$L-PRIV-1 | | |
|<-------------| | |
|(16) Bind Res | | |
|S=$L-PRIV-1 | | |
|D=$R-PUB-1 | | |
|MA=$R-PUB-1 | | |
|------------->| | |
| |(17) Bind Res | |
| |S=$NAT-PUB-1 | |
| |D=$R-PUB-1 | |
| |MA=$R-PUB-1 | |
| |---------------------------->|
|Data | | |
|<===========================================|
| | | |
.......
| | | |
|(18) Bind Req | | |
|S=$L-PRIV-1 | | |
|D=$R-PUB-1 | | |
|USE-CAND | | |
|------------->| | |
| |(19) Bind Req | |
| |S=$NAT-PUB-1 | |
| |D=$R-PUB-1 | |
| |USE-CAND | |
| |---------------------------->|
| |(20) Bind Res | |
| |S=$R-PUB-1 | |
| |D=$NAT-PUB-1 | |
| |MA=$NAT-PUB-1 | |
| |<----------------------------|
|(21) Bind Res | | |
|S=$R-PUB-1 | | |
|D=$L-PRIV-1 | | |
|MA=$NAT-PUB-1 | | |
|<-------------| | |
| | | |
]]></code> ]]></code>
<p>Note: Here the initiator (controlling agent) is using "aggressive nomination" as described in Section 8.1.1.2 of RFC 5245 and therefore includes the USE-CANDIDATE attribute in the STUN Binding Requests it sends.</p> <p>Note: aggressive nomination described in RFC 5245 is not used anymore in the updated &rfc8445;. From now on the initiator MUST nominate just one valid candidate pair.</p>
</section2> </section2>
<section2 topic='End-of-Candidates Indication' anchor='protocol-end'> <section2 topic='End-of-Candidates Indication' anchor='protocol-end'>
<p>As explained in the Trickle ICE specification, when a party has completed gathering of ICE candidates it will send an "end-of-candidates indication" to the other party. In Jingle, this takes the form of an informational message as described under <link url='#info'>Informational Messages</link>. This specificaton defines only a standalone "end-of-candidates indication" (i.e., not a way to indicate ICE completion in an offer or answer).</p> <p>As explained in the Trickle ICE specification, when a party has completed gathering of ICE candidates it will send an "end-of-candidates indication" to the other party. In Jingle, this takes the form of an informational message as described under <link url='#info'>Informational Messages</link>. This specificaton defines only a standalone "end-of-candidates indication" (i.e., not a way to indicate ICE completion in an offer or answer).</p>
</section2> </section2>
<section2 topic='Acceptance of Successful Candidate' anchor='protocol-acceptance'> <section2 topic='Acceptance of Successful Candidate' anchor='protocol-acceptance'>
<p>If, based on STUN connectivity checks, the parties determine that they will be able to exchange media between a given pair of local candidates and remote candidates (i.e., the pair is "nominated" and ICE processing is "completed"), they can then begin using that candidate pair to exchange media.</p> <p>If, based on STUN connectivity checks, the parties determine that they will be able to exchange media (i.e., each component has "nominated" candidate pair and ICE processing is "completed"), they proceed with optional remote-candidate notification after which ICE transport is considered to be established. By this moment the parties may exchange media data already since it's allowed even before the candidate pairs nomination according to &rfc8445;</p>
<p>Once the parties have connectivity and therefore the initiator has completed ICE as explained in RFC 5245, the initiator MAY communicate the in-use candidate pair in the signalling channel by sending a transport-info message that contains a &lt;remote-candidate/&gt; element (this maps to the SDP "remote-candidates" attribute as described in Section B.6 of RFC 5245, i.e., remote candidates are "the actual candidates at R that were selected by the offerer", of which there will be only one at this stage of the ICE negotiation).</p> <p>Once the parties have connectivity and therefore the initiator has completed ICE for the media stream as explained in &rfc8445;, the initiator MAY communicate the in-use (nominated) candidate pairs in the signalling channel by sending a transport-info message that contains a &lt;remote-candidate/&gt; element for each component of the data stream (this maps to the SDP "remote-candidates" attribute as described in Appendix B of draft-ietf-mmusic-ice-sip-sdp specification, i.e., remote candidates are "the actual candidates at R that were selected by the offerer").</p>
<p>Note, while in SIP this message is MUST it's just MAY for XMPP. The difference comes from a SIP problem (offer updates) which doesn't exist in XMPP. Basically there is no <strong>transport-info</strong> or any other message which represents candidates of a valid pair and therefore the race condition is not possible. Even so if the responder advertises "urn:ietf:rfc:3264" disco feature and hence may serve as a Jingle-to-SIP proxy the message MUST be sent.</p>
<example caption="Initiator communicates in-use candidate"><![CDATA[ <example caption="Initiator communicates in-use candidate"><![CDATA[
<iq from='romeo@montague.example/dr4hcr0st3lup4c' <iq from='romeo@montague.example/dr4hcr0st3lup4c'
id='pd81b49s' id='pd81b49s'
@ -446,13 +533,16 @@ INITIATOR NAT RESPONDER
<remote-candidate component='1' <remote-candidate component='1'
ip='10.0.1.2' ip='10.0.1.2'
port='9001'/> port='9001'/>
<remote-candidate component='2'
ip='10.0.1.2'
port='9002'/>
</transport> </transport>
</content> </content>
</jingle> </jingle>
</iq> </iq>
]]></example> ]]></example>
<p>(In accordance with Jingle core, the responder will also acknowledge the transport-info message.)</p> <p>(In accordance with Jingle core, the responder will also acknowledge the transport-info message.)</p>
<p>In the unlikely event that one of the parties determines that it cannot establish connectivity even after sending and checking lower-priority candidates, it SHOULD terminate the session as described in <cite>XEP-0166</cite>.</p> <p>In the unlikely event that one of the parties determines that it cannot establish connectivity even after sending and checking lower-priority candidates, it SHOULD terminate the session as described in <cite>XEP-0166</cite>, or alternatively it may do content-remove or transport-replace.</p>
</section2> </section2>
<section2 topic='Negotiating a New Candidate' anchor='protocol-renegotiate'> <section2 topic='Negotiating a New Candidate' anchor='protocol-renegotiate'>
<p>Even after media has begun to flow, either party MAY continue to send additional candidates to the other party (e.g., because the user agent has become aware of a new media proxy or network interface card). Such candidates are shared by sending a transport-info message.</p> <p>Even after media has begun to flow, either party MAY continue to send additional candidates to the other party (e.g., because the user agent has become aware of a new media proxy or network interface card). Such candidates are shared by sending a transport-info message.</p>
@ -494,7 +584,7 @@ INITIATOR NAT RESPONDER
<p>The parties would check the newly-offered candidate for connectivity, as described previously. If the parties determine that media can flow over the candidate, they MAY then use the new candidate in subsequent communications.</p> <p>The parties would check the newly-offered candidate for connectivity, as described previously. If the parties determine that media can flow over the candidate, they MAY then use the new candidate in subsequent communications.</p>
</section2> </section2>
<section2 topic='ICE Restarts' anchor='protocol-restarts'> <section2 topic='ICE Restarts' anchor='protocol-restarts'>
<p>At any time, either party MAY restart the process of ICE negotiation by sending a candidate with a 'generation' value that is greater than the previous generation of candidates; when it does so, it MUST generate new values for the 'pwd' and 'ufrag' attributes, consistent with the definition of an ICE restart in Section 9.1.1.1 of RFC 5245 (because an ICE restart is signalled by a change in the 'pwd' and 'ufrag' attributes, strictly speaking the 'generation' attribute is not absolutely necessary). As explained in RFC 5245, typically the ICE negotiation would be restarted to change the media target (e.g., an IP address change for one of the parties) and certain third-party-call-control scenarios.</p> <p>At any time, either party MAY restart the process of ICE negotiation by sending a candidate with a 'generation' value that is greater than the previous generation of candidates; when it does so, it MUST generate new values for the 'pwd' and 'ufrag' attributes, consistent with the definition of an ICE restart in Section 9 of &rfc8445; (because an ICE restart is signalled by a change in the 'pwd' and 'ufrag' attributes, strictly speaking the 'generation' attribute is not absolutely necessary). As explained in &rfc8445;, typically the ICE negotiation would be restarted to change the media target (e.g., an IP address change for one of the parties) and certain third-party-call-control scenarios.</p>
<example caption="Initiator restarts ICE negotiation"><![CDATA[ <example caption="Initiator restarts ICE negotiation"><![CDATA[
<iq from='romeo@montague.example/dr4hcr0st3lup4c' <iq from='romeo@montague.example/dr4hcr0st3lup4c'
id='kl23fs71' id='kl23fs71'
@ -531,6 +621,7 @@ INITIATOR NAT RESPONDER
type='result'/> type='result'/>
]]></example> ]]></example>
<p>The parties would then exchange new candidates to renegotiate connectivity and would check the new candidates for connectivity, as described previously. If the parties determine that media can flow over one of the new candidates, they can then use the successful candidate in subsequent communications. However, while ICE is being renegotiated the parties can continue to send media with the existing candidate-in-use.</p> <p>The parties would then exchange new candidates to renegotiate connectivity and would check the new candidates for connectivity, as described previously. If the parties determine that media can flow over one of the new candidates, they can then use the successful candidate in subsequent communications. However, while ICE is being renegotiated the parties can continue to send media with the existing candidate-in-use.</p>
<p>Note: If a party has already sent ICE restart and receives any transport-info message before &lt;iq/&gt; stanza of type "result", the transport-info messages have to be acknowledged with &lt;iq/&gt; stanzas of type "result" but dropped afterwards. After the restart was acknowledged, the other party MAY send the same candidates again as a part of the new ICE session. It's also possible both parties will send ICE restart simultaneously. In this case session initiator MUST respond with &lt;tie-break/&gt; error (see &xep0166;).</p>
</section2> </section2>
</section1> </section1>
@ -601,7 +692,8 @@ Romeo Gateway Juliet
</description> </description>
<transport xmlns='urn:xmpp:jingle:transports:ice:0' <transport xmlns='urn:xmpp:jingle:transports:ice:0'
pwd='asd88fgpdd777uzjYhagZg' pwd='asd88fgpdd777uzjYhagZg'
ufrag='8hhy'> ufrag='8hhy'
ice2='true'>
<candidate component='1' <candidate component='1'
foundation='2B78DADC1A9E' foundation='2B78DADC1A9E'
generation='0' generation='0'
@ -720,7 +812,7 @@ Romeo Gateway Juliet
</section1> </section1>
<section1 topic='Informational Messages' anchor='info'> <section1 topic='Informational Messages' anchor='info'>
<p>Informational messages can be sent by either party within the context of Jingle to communicate the status of a Jingle ICE "session". The informational message MUST be an IQ-set containing a &JINGLE; element of type "transport-info", where the informational message is a payload element qualified by the 'urn:xmpp:jingle:transports:ice:info:0' namespace.</p> <p>Informational messages can be sent by either party within the context of Jingle to communicate the status of a Jingle ICE "session". The informational message MUST be an IQ-set containing a &JINGLE; element of type "transport-info", where the informational message is a payload element qualified by the 'urn:xmpp:jingle:transports:ice:0' namespace.</p>
<p>The only payload element defined so far is the &lt;gathering-complete/&gt; element. This element is used only to signal that gathering of ICE candidates has been completed (i.e., to send an "end-of-candidates indication"), as in the following example.</p> <p>The only payload element defined so far is the &lt;gathering-complete/&gt; element. This element is used only to signal that gathering of ICE candidates has been completed (i.e., to send an "end-of-candidates indication"), as in the following example.</p>
<example caption="Responder sends end-of-candidates indication"><![CDATA[ <example caption="Responder sends end-of-candidates indication"><![CDATA[
<iq from='juliet@capulet.example/yn0cl4bnw0yr3vym' <iq from='juliet@capulet.example/yn0cl4bnw0yr3vym'
@ -732,13 +824,16 @@ Romeo Gateway Juliet
initiator='romeo@montague.example/dr4hcr0st3lup4c' initiator='romeo@montague.example/dr4hcr0st3lup4c'
sid='a73sjjvkla37jfea'> sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'> <content creator='initiator' name='this-is-the-audio-content'>
<transport xmlns='urn:xmpp:jingle:transports:ice:0'> <transport xmlns='urn:xmpp:jingle:transports:ice:0'
pwd='asd88fgpdd777uzjYhagZg'
ufrag='8hhy'>
<gathering-complete/> <gathering-complete/>
</transport> </transport>
</content> </content>
</jingle> </jingle>
</iq> </iq>
]]></example> ]]></example>
<p>The &lt;gathering-complete/&gt; element can be combined with remaining candidates or sent alone.</p>
</section1> </section1>
<section1 topic='Determining Support' anchor='support'> <section1 topic='Determining Support' anchor='support'>
@ -898,7 +993,7 @@ Romeo Gateway Juliet
<xs:element name='remote-candidate' <xs:element name='remote-candidate'
type='remoteCandidateElementType' type='remoteCandidateElementType'
minOccurs='1' minOccurs='1'
maxOccurs='1'/> maxOccurs='unbounded'/>
</xs:sequence> </xs:sequence>
<xs:sequence> <xs:sequence>
<xs:any namespace="##other" <xs:any namespace="##other"
@ -909,6 +1004,7 @@ Romeo Gateway Juliet
</xs:choice> </xs:choice>
<xs:attribute name='pwd' type='xs:string' use='optional'/> <xs:attribute name='pwd' type='xs:string' use='optional'/>
<xs:attribute name='ufrag' type='xs:string' use='optional'/> <xs:attribute name='ufrag' type='xs:string' use='optional'/>
<xs:attribute name='ice2' type='xs:boolean' use='optional' default='false'/>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>