[Standards-JIG] rfc3920bis: Stanza Acknowledgements

Dave Cridland dave at cridland.net
Mon Nov 6 16:41:03 UTC 2006

Thanks, this looks like a great start.

On Sun Nov  5 02:12:41 2006, Justin Karneges wrote:
> X. Stanza Acknowledgements
> X.1. Overview
> XMPP includes a method for acknowledging stanza reception, to allow 
> for
> transmission error detection and recovery.
> The following rules apply:
>   1. An initiating entity that complies with this specification 
> MUST include
>      the 'version' attribute set to a value of "1.0" in the initial 
> stream
>      header.
>   2. When a receiving entity that complies with this specification 
> receives
>      an initial stream header that includes the 'version' attribute 
> set to a
>      value of at least "1.0", after sending a stream header in reply
>      (including the version flag), it MUST include an <ack/> element
>      (qualified by the 'urn:ietf:params:xml:ns:xmpp-ack' namespace) 
> along
>      with the list of other stream features it supports.
> X.2. Narrative
> When an initiating entity activates the acknowledgement feature 
> with a
> receiving entity, the steps involved are as follows:
I'd be tempted to seperate out initial connection from reconnection, 

>   1. The initiating entity opens a TCP connection and initiates the 
> stream
>      by sending the opening XML stream header to the receiving 
> entity,
>      including the 'version' attribute set to a value of at least 
> "1.0".
>   2. The receiving entity responds by opening a TCP connection and 
> sending
>      an XML stream header to the initiating entity, including the 
> 'version'
>      attribute set to a value of at least "1.0".
>   3. The receiving entity offers the acknowledgement feature to the
>      initiating entity by including it with the list of other 
> supported
>      stream features.

(Only after authentication)

>   4. The initiating entity issues the enable command (i.e., a 
> <enable/>
>      element qualified by the 'urn:ietf:params:xml:ns:xmpp-ack' 
> namespace)
>      to instruct the receiving entity that it wishes to enable the
>      acknowledgement feature.  The element MAY contain a 'previd' 
> attribute
>      and a 'prevc' attribute, if the initiating entity wishes to 
> recover a
>      previously known acknowledgement session.  The value of the 
> 'previd'
>      attribute is set to the same value as the 'id' attribute of the
>      <stream> in the previous session.  The value of the 'prevc' 
> attribute,
>      if applicable, is set to the last received sequence number 
> (discussed
>      below) by the initiating entity.  If the initiating entity is 
> not
>      recovering a past session, the 'previd' and 'prevc' attributes 
>      be included.

(enable only gets sent after authentication)

>   5. The receiving entity MUST reply with an <enabled/> element 
> qualified by
>      the 'urn:ietf:params:xml:ns:xmpp-ack' namespace.  If the 
> initiating
>      entity provided a 'previd' attribute in the <enable/> element, 
> and the
>      receiving entity supports session recovery, then the receiving 
> entity
>      MAY provide a 'prevc' attribute in the <enabled/> element.  
> The value
>      of this attribute is set to the last received sequence number
>      (discussed below) for the previous session.  If the receiving 
> entity
>      does not support session recovery, or does not recognize the 
> 'previd'
>      as an earlier session, or there is no known last received 
> sequence
>      number for the session, then the attribute MUST NOT be 
> included.

This looks good so far. You might want to note the receiving entity 
might discard old sessions after a fixed timeout in the order of 

Bruce Fitzsimmons's comments make it clear that a sender might want 
to send unacked stanzas anyway, here, in order to reduce the 
round-trip count, and have the receiver drop duplicates. This is 
quite reasonable on some links - it's a trade-off of round-trips to 
latency, however I think it only works when all stanzas have a 'c' 
attribute. (Although I freely admit to not having thought of this 
before, and not having thought it through).

Finally, the server might not realize the client's been disconnected 
before it reconnects. What needs to happen here is that the server 
essentially replays unacked stanzas and ditches the old session, but 
I've yet to remind myself what RFC3920 says about that.

>   6. When a stanza is sent by either the initiating or receiving 
> entity, an
>      'r' attribute ("request ack") or a 'c' attribute ("sequence 
> number")
>      qualified by the 'urn:ietf:params:xml:ns:xmpp-ack' namespace 
> MAY be
>      provided in the top-level element of the stanza to indicate how
>      acknowledgements are to be handled with respect to the stanza. 
>  If no
>      acknowledgement processing is desired for a stanza, then the 
> attribute
>      MUST NOT be included.  Note that only stanzas ('message', 
> 'presence',
>      and 'iq', in the jabber:client or jabber:server namespaces) 
> can have
>      this kind of processing applied.  Non-stanza elements, such as 
> those
>      related to authentication or other stream-level purposes are 
> not to be
>      acknowledged using this protocol.

I would state that the value of "c" MUST be strictly increasing (not 
"monotonically increasing", that means "strictly non-decreasing", 
which'd be bad). I can't see any use-case for anything else.

Furthermore, I would state that any stanza with an "r" attribute MUST 
have a "c" attribute - see below for why.

>   7. When a stanza is received, containing an 'r' attribute 
> ("request ack")
>      with a value of "true", the recipient MUST acknowledge the 
> stanza by
>      sending an <a/> element qualified by the
>      'urn:ietf:params:xml:ns:xmpp-ack' namespace back to the sender.
>      Stanzas not containing an 'r' attribute MUST NOT be 
> acknowledged.
>      Several stanzas MAY be acknowledged at one time by including 
> an 'n'
>      attribute in the <a/> element, set to the integer value of the 
> number
>      of stanzas.  An ack indicates stanza acceptance, in that the 
> stanza is
>      now safe in the receiver's hands and that the receiver will 
> take care
>      of it from that point.  Acks do not indicate successful 
> delivery to a
>      remote entity beyond the receiver.  The sender does not have 
> to wait
>      for an ack to continue sending stanzas.  Acks SHOULD be sent 
> as soon as
>      possible, and MUST NOT be withheld for any condition other 
> than a
>      timeout. For example, a client with a slow connection might 
> want to
>      collect many stanzas over a period of time before acking, and 
> a server
>      might want to throttle incoming stanzas. As acks indicate 
> stanza
>      acceptance, a server that is throttling stanzas MUST defer the 
> acks
>      until the client is no longer being penalized.

Okay, here I diverge more... I would say that a receiver MAY send an 
ack even if not requested, if it is also sending other stanzas. I'm 
not wedded to this by any means, but it might be nice. The intention 
here is to allow a receiver to plonk an <a/> onto the end of a packet 
if it's sending. An alternate here would be to give several possible 
values for 'r', indicating whether you want an ack at all, and if you 
do, whether "sometime" or "immediate". I'm not wedded to that either, 
but I'd love to see some discussion.

Also, I would replace "Acks SHOULD be sent as soon as possible [...]" 
with something like:

Acks SHOULD be sent in a timely manner, however receivers MAY delay 
sending an ack for a short period in order to increase efficiency. 
Receivers MUST NOT delay sending an ack for more than 15 seconds, 
allowing the requesting peer to timeout the connection after 30 

Rationale is that you want mandatory timeouts here, and I too was a 
little confused by what you meant there. Feel free to adjust the 
mandatory timeout figures. The idea is that a client gets to be 
assured that if it asks for an ack, if it hasn't had one for 30 
seconds (in this case) the connection is dead.

Finally, I'd add in a mandatory prevc attribute in the <a/> element, 
to match the mandatory 'c' attribute in an 'r'-enabled stanza. This 
does mean that stanzas MUST be accepted in sequence, which I don't 
think is unreasonable. In turn, this renders the 'n' attribute 

Applycing to no particular section, some notes:

1) A 'c' or 'r' attribute only makes sense on the last stanza in a 
TCP packet. In general, any time you write any stanzas, you may well 
only care about 'c'/'r' attributes on the last one.

2) We need some mechanism for obtaining an ack when we've nothing to 
send. You could, of course, send an unrequested ack here, with 'c' 
and 'r' attributes.

3) But given (1) and (2), that implies that we could stick all the 
'c' and 'r' attributes onto only the <a/>, and append an <a/> to 
flushes to indicate synch points and request acks.

Point (3) is interesting, because it avoids servers having to rewrite 
stanzas (which was complained about, IIRC), *and* gives you a free 
hop-to-hop ping. So maybe that's worth discussing too.

Dave Cridland - mailto:dave at cridland.net - xmpp:dwd at jabber.org
  - acap://acap.dave.cridland.net/byowner/user/dwd/bookmarks/
  - http://dave.cridland.net/
Infotrope Polymer - ACAP, IMAP, ESMTP, and Lemonade

More information about the Standards mailing list