[Standards] Security consideration for XEP-0198

Dave Cridland dave at cridland.net
Thu May 8 09:00:09 UTC 2014

On 8 May 2014 02:47, John Williams (johnwi3) <johnwi3 at cisco.com> wrote:

> Although not mentioned, I would expect many server implementations would
> choose to impose limits on how much unacknowledged traffic they will
> buffer. XEP-0198 leaves a lot of freedom to the implementer.
Good. :-)

> The primary goal of XEP-0198 is to optimize reconnection for clients with
> unreliable connection (or hopping from wired/wireless). A resume may fail,
> but if it succeeds quite often then it is a useful optimization.
The primary goal is to increase reliability in the face of intermittent
connectivity. Reconnection - that is, allowing an XMPP session to span
multiple sequential TCP sessions - is part of that.

> If you assume you have no evidence that the client connection has failed
> (but your buffer has hit its limit), you could simply discard the oldest
> unacked packet and make space for the newer packet.


> In many cases the client will catch up and no harm is done. If you are not
> so lucky, and you need a stanzas you discarded for a resume request - oh
> well the resume will fail. This simple implementation is sufficient for
> optimizing reconnection most of the time, but occasionally it means someone
> has to take the slower session recreation path.
That's an interesting case. So you're hoping the client will give you an
<a/> with a sufficiently high value that you would have discarded the
stanzas anyway?

> I don’t believe it was the goal of XEP-0198 to guarantee a stanza is
> either delivered or bounced. I am not sure if you are trying to achieve
> this guarantee by bouncing new stanzas once the buffer overflows.
Modulo the obvious blurb about whether a stanza needs bouncing on a
delivery failure, that is, kind of, the goal.

The primary goal, as I said, is reliability. That doesn't really mean
"always deliver", but "if delivery fails, we need to know about it". If
every link uses 198, then in principle a message should always be
delivered, or bounced - and moreover, a 184 acknowledgement will itself
reliably make it back.

The Two Generals problem basically says this is impossible, of course, but
what 198 does is try to remove or limit as many corner cases as possible.
The case where the 2G problem kicks in is limited to if we never get an
<a/> and cannot re-establish the link. In this case, the fate of the stanza
is always unknown. The stanza's fate is temporarily unknown while waiting
for an <a/>, too.

Quite what to do when the stanza's fate is unknown is an implementation
dependent thing, but typically we eventually stick messages into offline
storage, bounce iqs, and drop presence, and otherwise treat them as if they
weren't delivered, on the assumption that a duplicate is better than an

What concerns me with your proposal above is that there's simply no way to
bounce, or redirect, a stanza once it's been discarded, so it becomes lost,
and the reliability is degraded as a result. Across one link this probably
doesn't matter, but from an end-to-end perspective I think it does.

> I don’t think this will work well.  This implementation is liable to fail
> to deliver traffic the client, and the client would be totally oblivious.
> Events from pub-sub nodes might have been missed, changes in occupants and
> roles within a chat room, etc....
Right, XMPP has strict ordering requirements, and we don't want to start
bouncing stanzas in the middle of a session, because we lack the protocol
functionality to deal with that.

If a session stops, we have the server emit unavailable presence, which
leaves chatrooms, and so on; and the client, knowing it's now a new session
on a failed resume, will perform resynchronization as needed.

> I believe the only way to make this guarantee is to kill the session upon
> overflow. All the unacked packets are available to bounce, the client will
> have to reconnect and establish a new session (resume would fail), and the
> client would rebuild their state. The price of this guarantee is that it
> could cause a bad experience for users on slow connections, or cause
> problems when there are heavy bursts of traffic.
> Dave's suggestion could help detect dead/unresponsive connections sooner,
> but you still have to deal with the problem of buffering stanzas while you
> are waiting. You probably want to send <r> stanzas anytime your buffer
> creeps up so that you can solicit an <a> stanza well before you hit your
> overflow point.
Yes, quite.

> Note:
> xep-0198 allows clients to send <a> stanzas even if there was no <r> from
> the server. When you see an <a> from the client that might not correlate to
> the <r> you sent. I suppose you could keep waiting for the <a> that has 'h'
> equal to the  value you would expect for the <r> you sent.

I'm not sure it matters. The <r/> is merely a requirement to send an <a/>,
but any <a/> can be processed independently.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.jabber.org/pipermail/standards/attachments/20140508/b2238f02/attachment.html>

More information about the Standards mailing list