mirror of
https://github.com/moparisthebest/xeps
synced 2024-11-25 02:32:18 -05:00
248 lines
11 KiB
XML
248 lines
11 KiB
XML
<?xml version='1.0' encoding='UTF-8'?>
|
|
<!DOCTYPE xep SYSTEM 'xep.dtd' [
|
|
<!ENTITY % ents SYSTEM 'xep.ent'>
|
|
%ents;
|
|
]>
|
|
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
|
<xep>
|
|
<header>
|
|
<title>XMPP Quickstart</title>
|
|
<abstract>This document defines methods for speeding the process of connecting or reconnecting to an XMPP.</abstract>
|
|
&LEGALNOTICE;
|
|
<number>XXXX</number>
|
|
<status>ProtoXEP</status>
|
|
<type>Standards Track</type>
|
|
<sig>Standards</sig>
|
|
<dependencies>
|
|
<spec>RFC 5077</spec>
|
|
<spec>RFC 6120</spec>
|
|
<spec>XEP-0115</spec>
|
|
<spec>XEP-0198</spec>
|
|
</dependencies>
|
|
<supersedes/>
|
|
<supersededby/>
|
|
<shortname>N/A</shortname>
|
|
&stpeter;
|
|
<revision>
|
|
<version>0.0.1</version>
|
|
<date>2011-08-10</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Rough draft.</p></remark>
|
|
</revision>
|
|
</header>
|
|
<section1 topic='Introduction' anchor='intro'>
|
|
<p>Establishing an XMPP session requires a fairly large number of round trips between the initiating entity and the receiving entity. In many deployment scenarios, it would be helpful to reduce the number of round trips and, in general, the time needed to establish a session. This document defines protocols and best practices to do just that.</p>
|
|
<p>Note: Various parts of this document might be moved to separate documents at some point.</p>
|
|
</section1>
|
|
<section1 topic='Preparing to Connect' anchor='prepare'>
|
|
<p>In accordance with &rfc6120;, before attempting to establish a stream the initiating entity needs to determine the IP address and port at which to connect. Implementations SHOULD cache the results of DNS lookups in order to avoid this step whenever possible.</p>
|
|
<p>XMPP clients SHOULD also cache whatever information they can, especially the roster (see &xep0237;) and &xep0030; information. Servers SHOULD support &xep0237; and SHOULD include &xep0115; data in stream features to facilitate such caching. (Caching of service discovery data also applies to server-to-server connections.)</p>
|
|
</section1>
|
|
<section1 topic='Pipelining' anchor='pipelining'>
|
|
<p>One method of speeding the connection process is pipelining of requests, as in the QUICKSTART extension proposed for SMTP &smtpquickstart;. The application of similar principles to XMPP was originally suggested by Tony Finch.</p>
|
|
<p>In essence, pipelining lets an initiating entity assume that the receiving entity supports the same (or almost the same) features it did on the previous connection attempt. As a result, the initiating entity can proactively send multiple XMPP-related "commands" in a single TCP packet, thus reducing the number of round trips.</p>
|
|
<p>If an XMPP server supports pipelining, then it MUST advertise a stream feature of <pipelining xmlns='urn:xmpp:pipelining:0'/>.</p>
|
|
<p>If both parties support pipelining, they can proceed as follows (the examples use the XML from the client-server stream establishment section of <cite>RFC 6120</cite>, although the same principles apply to server-to-server streams).</p>
|
|
<example caption='Pipelining for Stream Establishment'><![CDATA[
|
|
STEP 1
|
|
C: <stream:stream
|
|
from='juliet@im.example.com'
|
|
to='im.example.com'
|
|
version='1.0'
|
|
xml:lang='en'
|
|
xmlns='jabber:client'
|
|
xmlns:stream='http://etherx.jabber.org/streams'>
|
|
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
|
|
|
|
STEP 2
|
|
S: <stream:stream
|
|
from='im.example.com'
|
|
id='t7AMCin9zjMNwQKDnplntZPIDEI='
|
|
to='juliet@im.example.com'
|
|
version='1.0'
|
|
xml:lang='en'
|
|
xmlns='jabber:client'
|
|
xmlns:stream='http://etherx.jabber.org/streams'>
|
|
<stream:features>
|
|
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
|
|
<required/>
|
|
</starttls>
|
|
<pipelining xmlns='urn:xmpp:pipelining:0'/>
|
|
<c xmlns='http://jabber.org/protocol/caps'
|
|
hash='sha-1'
|
|
node='http://prosody.im/'
|
|
ver='ItBTI0XLDFvVxZ72NQElAzKS9sU='/>
|
|
</stream:features>
|
|
<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
|
|
|
|
STEP 3
|
|
[client and server complete TLS negotiation over the existing TCP connection]
|
|
|
|
STEP 4
|
|
S: <stream:stream
|
|
from='im.example.com'
|
|
id='vgKi/bkYME8OAj4rlXMkpucAqe4='
|
|
to='juliet@im.example.com'
|
|
version='1.0'
|
|
xml:lang='en'
|
|
xmlns='jabber:client'
|
|
xmlns:stream='http://etherx.jabber.org/streams'>
|
|
<stream:features>
|
|
<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
|
|
<mechanism>SCRAM-SHA-1-PLUS</mechanism>
|
|
<mechanism>SCRAM-SHA-1</mechanism>
|
|
<mechanism>PLAIN</mechanism>
|
|
</mechanisms>
|
|
<pipelining xmlns='urn:xmpp:pipelining:0'/>
|
|
<c xmlns='http://jabber.org/protocol/caps'
|
|
hash='sha-1'
|
|
node='http://prosody.im/'
|
|
ver='ItBTI0XLDFvVxZ72NQElAzKS9sU='/>
|
|
</stream:features>
|
|
|
|
STEP 5
|
|
C: <stream:stream
|
|
from='juliet@im.example.com'
|
|
to='im.example.com'
|
|
version='1.0'
|
|
xml:lang='en'
|
|
xmlns='jabber:client'
|
|
xmlns:stream='http://etherx.jabber.org/streams'>
|
|
<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl"
|
|
mechanism="SCRAM-SHA-1">
|
|
biwsbj1qdWxpZXQscj1vTXNUQUF3QUFBQU1BQUFBTlAwVEFBQUFBQUJQVTBBQQ==
|
|
</auth>
|
|
|
|
STEP 6
|
|
S: <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
|
|
cj1vTXNUQUF3QUFBQU1BQUFBTlAwVEFBQUFBQUJQVTBBQWUxMjQ2OTViLTY5Y
|
|
TktNGRlNi05YzMwLWI1MWIzODA4YzU5ZSxzPU5qaGtZVE0wTURndE5HWTBaaT
|
|
AwTmpkbUxUa3hNbVV0TkRsbU5UTm1ORE5rTURNeixpPTQwOTY=
|
|
</challenge>
|
|
|
|
STEP 7
|
|
C: <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
|
|
Yz1iaXdzLHI9b01zVEFBd0FBQUFNQUFBQU5QMFRBQUFBQUFCUFUwQUFlMTI0N
|
|
jk1Yi02OWE5LTRkZTYtOWMzMC1iNTFiMzgwOGM1OWUscD1VQTU3dE0vU3ZwQV
|
|
RCa0gyRlhzMFdEWHZKWXc9
|
|
</response>
|
|
|
|
STEP 8
|
|
S: <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
|
|
dj1wTk5ERlZFUXh1WHhDb1NFaVc4R0VaKzFSU289
|
|
</success>
|
|
<stream:stream
|
|
from='im.example.com'
|
|
id='gPybzaOzBmaADgxKXu9UClbprp0='
|
|
to='juliet@im.example.com'
|
|
version='1.0'
|
|
xml:lang='en'
|
|
xmlns='jabber:client'
|
|
xmlns:stream='http://etherx.jabber.org/streams'>
|
|
<stream:features>
|
|
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
|
|
<pipelining xmlns='urn:xmpp:pipelining:0'/>
|
|
<c xmlns='http://jabber.org/protocol/caps'
|
|
hash='sha-1'
|
|
node='http://prosody.im/'
|
|
ver='ItBTI0XLDFvVxZ72NQElAzKS9sU='/>
|
|
</stream:features>
|
|
|
|
STEP 9
|
|
C: <stream:stream
|
|
from='juliet@im.example.com'
|
|
to='im.example.com'
|
|
version='1.0'
|
|
xml:lang='en'
|
|
xmlns='jabber:client'
|
|
xmlns:stream='http://etherx.jabber.org/streams'>
|
|
<iq id='yhc13a95' type='set'>
|
|
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
|
|
<resource>balcony</resource>
|
|
</bind>
|
|
</iq>
|
|
|
|
STEP 10
|
|
S: <iq id='yhc13a95' type='result'>
|
|
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
|
|
<jid>
|
|
juliet@im.example.com/balcony
|
|
</jid>
|
|
</bind>
|
|
</iq>
|
|
]]></example>
|
|
<p>As can be seen, pipelining needs 10 steps to complete session establishment, as opposed to 16 steps for the non-pipelined process described in <cite>RFC 6120</cite>.</p>
|
|
<p>Naturally, additional round trips are needed for XMPP clients to gather service discovery information, retrieve the roster, etc.</p>
|
|
</section1>
|
|
<section1 topic='Reconnection' anchor='reconnection'>
|
|
<p>The pain of multiple round trips is magnified if the initiating entity needs to reconnect frequently (e.g., because of intermittent network outages). Although &xep0124; can be used to mitigate the pain, BOSH is not appropriate for all scenarios and is not currently used in others (e.g., server-to-server streams).</p>
|
|
<p>The minimize the speed of reconnection, implementations are strongly encouraged to support TLS Session Resumption (&rfc5077;) in addition to the technologies already mentioned.</p>
|
|
</section1>
|
|
<section1 topic='Stream Management Tickets' anchor='tickets'>
|
|
<p>If &xep0198; is used, including support for stream resumption, the server can treat the stream management identifier as a "ticket" for stream resumption (similar to the use of a ticket for TLS session resumption). Here's how.</p>
|
|
<p>First, if an XMPP server allows stream management IDs as stream resumption tickets, then it MUST advertise a stream feature of <tickets xmlns='urn:xmpp:sm:tickets:0'/>.</p>
|
|
<p>During the stream management negotiation, the server will deliver a stream management ID for stream resumption.</p>
|
|
<example caption='Sending a Stream Management ID'><![CDATA[
|
|
C: <enable xmlns='urn:xmpp:sm:3'/>
|
|
|
|
S: <enabled xmlns='urn:xmpp:sm:3' id='37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643' resume='true'/>
|
|
]]></example>
|
|
<p>The server SHOULD do send an ID if TLS has already been negotiated, since the SM-ID might be used as a session resumption ticket.</p>
|
|
<p>Now, when the client reconnects it includes the SM-ID in its opening stream header.</p>
|
|
<example caption='Using the Stream Management ID as a Ticket'><![CDATA[
|
|
C: <stream:stream
|
|
from='juliet@im.example.com'
|
|
sm:id='37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643'
|
|
to='im.example.com'
|
|
version='1.0'
|
|
xml:lang='en'
|
|
xmlns='jabber:client'
|
|
xmlns:sm='urn:xmpp:sm:3'>
|
|
xmlns:stream='http://etherx.jabber.org/streams'>
|
|
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
|
|
]]></example>
|
|
<p>If the server accepts the SM-ID as a ticket, it MUST echo the identifier in its response stream header.</p>
|
|
<example caption='EX'><![CDATA[
|
|
S: <stream:stream
|
|
from='im.example.com'
|
|
id='t7AMCin9zjMNwQKDnplntZPIDEI='
|
|
sm:id='37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643'
|
|
to='juliet@im.example.com'
|
|
version='1.0'
|
|
xml:lang='en'
|
|
xmlns='jabber:client'
|
|
xmlns:sm='urn:xmpp:sm:3'>
|
|
xmlns:stream='http://etherx.jabber.org/streams'>
|
|
<stream:features>
|
|
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
|
|
<required/>
|
|
</starttls>
|
|
<pipelining xmlns='urn:xmpp:pipelining:0'/>
|
|
<tickets xmlns='urn:xmpp:sm:tickets:0'/>
|
|
<c xmlns='http://jabber.org/protocol/caps'
|
|
hash='sha-1'
|
|
node='http://prosody.im/'
|
|
ver='k2Ozf7u+7+uAaYPFbcb9RczI7sY='/>
|
|
</stream:features>
|
|
<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
|
|
]]></example>
|
|
<p>After the client and server negotiate TLS to protect the stream (preferably using TLS session resumption to reduce the number of round trip), the server SHOULD immediately allow the client to start sending stanzas and SHOULD also immediately send a new SM-ID to the client.</p>
|
|
<example caption='Sending a New Stream Management ID'><![CDATA[
|
|
S: <enabled xmlns='urn:xmpp:sm:3' id='9b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b8932307564337c6' resume='true'/>
|
|
]]></example>
|
|
</section1>
|
|
<section1 topic='Security Considerations' anchor='security'>
|
|
<p>A server MUST NOT treat a stream management identifier as a stream resumption ticket unless the original stream was protected by means of TLS.</p>
|
|
<p>A server MUST time out a stream management identifier after a configurable amount of time (typically no more than a few minutes).</p>
|
|
</section1>
|
|
<section1 topic='IANA Considerations' anchor='iana'>
|
|
<p>This document requires no interaction with &IANA;.</p>
|
|
</section1>
|
|
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
|
<p>To follow.</p>
|
|
</section1>
|
|
<section1 topic='Acknowledgements' anchor='ack'>
|
|
<p>Special thanks to Tony Finch for suggesting this work and providing the initial outline of how pipelining would work. Thanks also to Kevin Smith for his early feedback.</p>
|
|
</section1>
|
|
</xep>
|