Jehan is right. This XEP should only list the MUST-Do handshakes.
Feature negotiation is not a MUST. Authentication is another thing and
should not be limited to just SASL.
Michael

On Fri, Aug 26, 2011 at 5:14 PM, Peter Saint-Andre <[email protected]> wrote:
> Yes I am reviewing all of the messages about this proposal before
> publishing it as a XEP.
>
> On 8/26/11 6:57 AM, Jehan Pagès wrote:
>> Hi,
>>
>> I wrote 2 unanswered emails about this XEP proposal, one about the
>> fact the quickstart can be improved, hence skipping one step and also
>> sending a lot less unecessary data (basically all the <features/>) in
>> "quickstart mode" as we could consider the initiating entity already
>> "registered" its authentication "path" during a previous connection;
>> and one about stream resumption, which I think is slightly
>> contradictory to XEP-0198.
>>
>> So as I think they may have been "lost" amongst the many emails on the
>> list, I allow myself to up this. :-)
>> Thanks.
>>
>> Jehan
>>
>> 2011/8/13 Jehan Pagès <[email protected]>:
>>> Hi,
>>>
>>> On Thu, Aug 11, 2011 at 10:46 AM, Waqas Hussain <[email protected]> wrote:
>>>> On Thu, Aug 11, 2011 at 2:28 AM, XMPP Extensions Editor <[email protected]> 
>>>> wrote:
>>>>> The XMPP Extensions Editor has received a proposal for a new XEP.
>>>>>
>>>>> Title: XMPP Quickstart
>>>>>
>>>>> Abstract: This document defines methods for speeding the process of 
>>>>> connecting or reconnecting to an XMPP.
>>>>>
>>>>> URL: http://www.xmpp.org/extensions/inbox/quickstart.html
>>>>>
>>>
>>> I find this XEP very interesting. I would typically use this in
>>> "simple" web implementations where I cannot keep a live client
>>> connection, hence do often short connections.
>>>
>>>>> The XMPP Council will decide at its next meeting whether to accept this 
>>>>> proposal as an official XEP.
>>>>>
>>>>>
>>>>
>>>> Example 1 doesn't take things to their logical extreme.
>>>>
>>>> STEP 1 can be merged with the TLS ClientHello message.
>>>> STEP 4 can be merged with the server's TLS Finished message.
>>>> STEP 5 can be merged with the client's TLS Finished message.
>>>> STEP 9 can be merged with STEP 7.
>>>> If the server handles it just right, STEP 8 and 10 could be merged
>>>> into one TCP packet (in response to 7+9).
>>>>
>>>> If you are not negotiating TLS in the middle, you can start a stream,
>>>> do PLAIN or ANONYMOUS login, request roster, set presence, join a
>>>> chatroom, and send messages, all in the first TCP packet. This makes
>>>> legacy SSL somewhat attractive. The same can be done with BOSH, if you
>>>> skip the stream restart on SASL (which virtually all existing clients
>>>> do?).
>>>>
>>>> Moving on...
>>>>
>>>> Does the client even need to pay attention to the pipelining stream
>>>> feature? When connecting to any server, it can first attempt to use
>>>> full pipelining. If that fails, it can simply reconnect without
>>>> pipelining. It can cache the failures. It would need to do this even
>>>> if the server indicates it can support pipelining, as the server may
>>>> be lying/buggy and e.g., might not support merging TLS negotiation and
>>>> XMPP data in the same TCP packet.
>>>>
>>>> Looking at Example 1 closely, the client pipelined <starttls/> before
>>>> looking at the stream feature, so what's the stream feature for? Is
>>>> the client expected to not pipeline unless it has seen the feature in
>>>> a previous connection to the host? Why? Given that the failure case is
>>>> harmless, and that pipelining might work on many existing servers, why
>>>> wouldn't it want to use it on first connect? Would using it violate
>>>> any specification?
>>>
>>> Actually I think it can be very interesting to have done a "normal"
>>> connection first (where you saw that pipelining feature), in order to
>>> further optimize any further connections. Hence the client could
>>> already know what are the features of the server, what will be the one
>>> it will want to negotiate, and in which order.
>>> In particular, you know there is TLS, which SASL mechanism you will
>>> want to use, if there is compression, and if so, which compression
>>> scheme to use, and so on. What we "earn" here is that, first of all,
>>> the server would never have to send its list of features and the
>>> client would thus never have to process it (even if it skips it when
>>> it sees it while pipelining, that's still useless processing in the
>>> "quickstart" use case).
>>> For instance, in the example 1, because you have done once the whole
>>> normal negotiation and you saw that the server supports pipelining,
>>> you cache that next time you will "quickstart" with TLS+SASL
>>> SCRAM-SHA1+bind. So the example could be like this:
>>>
>>> STEP 1: *same*
>>> C: <stream:stream
>>>     from='[email protected]'
>>>     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: *no need to send features. That's a lot "thinner" packet!*
>>> S: <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
>>>
>>> STEP 3: *same*
>>> [client and server complete TLS negotiation over the existing TCP 
>>> connection]
>>>
>>> STEP 4: *your example was somewhat "bad"! The initiating identity has
>>> to restart the stream, not the receiving one (cf. RFC 6120), though we
>>> could imagine in quickstart, it does not matter much.*
>>> C: <stream:stream
>>>     from='[email protected]'
>>>     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 5: *server restarts as well and directly responds the SASL auth,
>>> no features!*
>>> S: <stream:stream
>>>     from='im.example.com'
>>>     id='vgKi/bkYME8OAj4rlXMkpucAqe4='
>>>     to='[email protected]'
>>>     version='1.0'
>>>     xml:lang='en'
>>>     xmlns='jabber:client'
>>>     xmlns:stream='http://etherx.jabber.org/streams'>
>>> <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
>>>     cj1vTXNUQUF3QUFBQU1BQUFBTlAwVEFBQUFBQUJQVTBBQWUxMjQ2OTViLTY5Y
>>>     TktNGRlNi05YzMwLWI1MWIzODA4YzU5ZSxzPU5qaGtZVE0wTURndE5HWTBaaT
>>>     AwTmpkbUxUa3hNbVV0TkRsbU5UTm1ORE5rTURNeixpPTQwOTY=
>>>   </challenge>
>>>
>>> STEP 6:
>>> C: <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
>>>     Yz1iaXdzLHI9b01zVEFBd0FBQUFNQUFBQU5QMFRBQUFBQUFCUFUwQUFlMTI0N
>>>     jk1Yi02OWE5LTRkZTYtOWMzMC1iNTFiMzgwOGM1OWUscD1VQTU3dE0vU3ZwQV
>>>     RCa0gyRlhzMFdEWHZKWXc9
>>>   </response>
>>>
>>> STEP 7: *ok here the server could restart the stream because it knows
>>> first the success of the negotiation (but it does not change much. It
>>> could restart its side at step 9). Still no features sent!*
>>> S: <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
>>>     dj1wTk5ERlZFUXh1WHhDb1NFaVc4R0VaKzFSU289
>>>   </success>
>>>   <stream:stream
>>>     from='im.example.com'
>>>     id='gPybzaOzBmaADgxKXu9UClbprp0='
>>>     to='[email protected]'
>>>     version='1.0'
>>>     xml:lang='en'
>>>     xmlns='jabber:client'
>>>     xmlns:stream='http://etherx.jabber.org/streams'>
>>>
>>> STEP 8:
>>> C: <stream:stream
>>>     from='[email protected]'
>>>     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 9:
>>> S: <iq id='yhc13a95' type='result'>
>>>     <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
>>>       <jid>
>>>         [email protected]/balcony
>>>       </jid>
>>>     </bind>
>>>   </iq>
>>>
>>> So here we have 1 step less and in particular, the server never sends
>>> any features, which spare some useless data processing on both side.
>>>
>>> NOTE: actually if the client is *sure* the authentication will work,
>>> it can merge steps 6 and 8. As a consequence, the server can merge 7
>>> and 9, saving, in all, 2 additional round trips! The whole process
>>> would be only 7 roundtrips. Of course the downside of this is that a
>>> failed authentication cannot be saved (as you already sent "wrongly"
>>> the restarted stream headers, which would hence make a stream error,
>>> and a stream must re-negotiated from the start). I would say that
>>> could be 2 cases:
>>> 1/ if the client is user-driven, then you might want to do the 9-steps
>>> process. Indeed in case of auth-error, you might want to pop-up the
>>> user and ask him to type again its password to retry authentication
>>> without having to redo the whole negotiation.
>>> 2/ if the client is a bot, you can just imagine that a failed
>>> negotiation has no solution right now. So you do the 7-steps process
>>> by assuming it will go all right.
>>>
>>> So I guess you provided the stream features here because RFC-6120
>>> writes that the receiving entity MUST send a <features/>. But as we
>>> are in a special case of quickstart stream, we could imagine new
>>> characteristics, couldn't we?
>>>
>>> Actually I think the more logical would be to have a dedicated stream
>>> attribute prefixed by the pipelining namespace. Then if the client
>>> wants to pipeline, it adds this attribute to its initial stream
>>> header:
>>> <stream:stream
>>>     from='[email protected]'
>>>     to='im.example.com'
>>>     version='1.0'
>>>     pipe:pipeline='true'
>>>     xml:lang='en'
>>>     xmlns='jabber:client'
>>>     xmlns:stream='http://etherx.jabber.org/streams'
>>>     xmlns:pipe='urn:xmpp:pipelining:0'>
>>>
>>> Then the server knows for sure it is in "pipeline" mode and does not
>>> need to send any features, hence saving many roundtrips (up to 9 steps
>>> in our example!) and much processing of features. In any other case,
>>> the server can "guess" the client is trying to pipeline (by checking
>>> how many "commands" are in the single first TCP packet), but that
>>> implies first to check at the lower (TCP) level (which I don't find
>>> nice here), and second it implies that 2 commands in a single TCP
>>> packet are necessarily an attempt to pipeline while nothing forbids an
>>> entity to have several commands in a single packet, or at the opposite
>>> "break" into several packets (that's how TCP works after all). So as
>>> this is in fact not necessarily true, that makes pipelining either
>>> limited or unreliable. With an additional stream attribute here, we
>>> make this reliable, hence we allow additional optimizations (like
>>> removing all the <features/>).
>>>
>>> What do you think? This way, I think this would make such a feature
>>> extremely more interesting.
>>>
>>> Jehan
>>>
>
>
> --
> Peter Saint-Andre
> https://stpeter.im/
>
>
>

Reply via email to