mirror of
https://github.com/moparisthebest/xeps
synced 2024-11-28 12:12:22 -05:00
2d4af4ea52
git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@50 4b5297f7-1745-476d-ba37-a9c6900126ab
124 lines
5.0 KiB
XML
124 lines
5.0 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>Best Practice for Closing Idle Streams</title>
|
|
<abstract>This document specifies best practice for closing an idle XMPP stream.</abstract>
|
|
&LEGALNOTICE;
|
|
<number>0190</number>
|
|
<status>Experimental</status>
|
|
<type>Informational</type>
|
|
<jig>Standards JIG</jig>
|
|
<dependencies>
|
|
<spec>XMPP Core</spec>
|
|
</dependencies>
|
|
<supersedes/>
|
|
<supersededby/>
|
|
<shortname>N/A</shortname>
|
|
<author>
|
|
<firstname>Carlo</firstname>
|
|
<surname>von Loesch</surname>
|
|
<email>lynX@jabber.getting.psyced.org</email>
|
|
<jid>lynX@ve.symlynX.com</jid>
|
|
</author>
|
|
<revision>
|
|
<version>0.1</version>
|
|
<date>2006-07-26</date>
|
|
<initials>psa</initials>
|
|
<remark><p>Initial version.</p></remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.0.2</version>
|
|
<date>2006-06-30</date>
|
|
<initials>cvl</initials>
|
|
<remark>Second draft.</remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.0.1</version>
|
|
<date>2006-05-31</date>
|
|
<initials>cvl</initials>
|
|
<remark>First draft.</remark>
|
|
</revision>
|
|
</header>
|
|
|
|
<section1 topic='Introduction' anchor='intro'>
|
|
&BISNOTE;
|
|
<p><cite>RFC 3920</cite> offers several ways on how to terminate an XMPP stream, but
|
|
doesn't always make a clear statement which one to take. This can lead
|
|
to faulty implementations. In particular, closing a stream that hasn't
|
|
been in use for a while is very often achieved using a connection-timeout
|
|
error, then closing the socket. This can lead to loss of data. Therefore
|
|
this document proposes a practice that will avoid such data loss.</p>
|
|
</section1>
|
|
|
|
<!-- section1 topic='How Not to Close an Idle Stream' anchor='dont'>
|
|
<section2 topic='Using a connection-timeout error'>
|
|
<p>Although RFC 3920 provides for an error condition
|
|
<code><![CDATA[ <connection-timeout/> ]]></code>
|
|
such error MUST NOT be used to close an idle connection, unless
|
|
the sender is expecting a message from the other entity, and a timeout
|
|
has occured instead, like during a dialback or SASL negotiation.</p>
|
|
<p>This has been a popular strategy, but it can cause frequent data
|
|
loss each time a connection is timeouted while the other entity just
|
|
started transmitting data.</p>
|
|
</section2>
|
|
<section2 topic='Closing the TCP connection without warning'>
|
|
<p>Several implementations even close the TCP connection without an
|
|
error or a stream shutdown. This has the same effects of data loss
|
|
as the friendlier variant mentioned before. Additionally it leaves
|
|
the other side wondering if the termination was intentional or erroneous.
|
|
This method MUST NOT be put into practice.</p>
|
|
</section2>
|
|
</section1 -->
|
|
|
|
<section1 topic='How to Close an Idle Stream' anchor='do'>
|
|
<section2 topic='Handshake Stream Shutdown'>
|
|
<p>As shown in the basic "session" example in the
|
|
Simplified Stream Examples (4.8 of RFC 3920),
|
|
it is a valid transaction to close the outgoing stream by sending
|
|
<code><![CDATA[ </stream:stream> ]]></code>
|
|
then wait for the other entity to close its stream, like this:
|
|
<code><![CDATA[ </stream:stream> ]]></code>
|
|
and shut down the underlying TCP connection.</p>
|
|
<p>This will ensure that, should the other entity have transmitted
|
|
any data, it will arrive and be processed before the TCP connection
|
|
is terminated.</p>
|
|
<p>Special care MUST be taken that under no circumstance further
|
|
packets may be written to the socket after the stream was closed,
|
|
until the other side shuts down the socket.</p>
|
|
<p>On the outgoing TCP connection you MAY do a read-only shutdown
|
|
of the socket, as long as the other side will safely be able to
|
|
send its stream termination token.</p>
|
|
</section2>
|
|
<section2 topic='Handshake Failure'>
|
|
<p>In case the other entity fails to close the stream within a
|
|
reasonable time frame, the entity that started the handshake is
|
|
entitled to terminate the TCP connection. Since the stream has
|
|
already been closed, it is correct not to produce an error condition.</p>
|
|
</section2>
|
|
</section1>
|
|
|
|
<section1 topic='Conclusion' anchor='conclusion'>
|
|
<p>Please update your implementations to use the 'Handshake Stream Shutdown'
|
|
strategy when shutting down streams you no longer need.</p>
|
|
<p>Even not to shut down idle streams at all is a better strategy than to
|
|
shut them down by creating an error condition, so if your application
|
|
has no necessity for shutting down idle connections, just don't do it.</p>
|
|
</section1>
|
|
|
|
<section1 topic='Security Considerations' anchor='security'>
|
|
<p>This proposal introduces no new security aspects.</p>
|
|
</section1>
|
|
<section1 topic='IANA Considerations' anchor='iana'>
|
|
<p>This proposal requires no interaction with &IANA;.</p>
|
|
</section1>
|
|
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
|
<p>This proposal requires no interaction with the ®ISTRAR;.</p>
|
|
</section1>
|
|
|
|
</xep>
|