[jdev] dealing with looping subscription establishment

Robert McQueen robert.mcqueen at collabora.co.uk
Thu Jun 15 16:02:43 CDT 2006


I'm facing some trouble with my client interoperating with jabberd2.
colltest1 at noise and colltest2 at noise are both accounts with empty rosters
on a jabberd2 server. The logs are from the perspective of colltest1.

When we send an outgoing subscription request. Send:
<presence type="subscribe" to="colltest2 at noise"
id="msg_18064968_cdc9ed2c_11"/>

The server pushes us the pending roster entry. Receive:
<iq xmlns='jabber:client' to='colltest1 at noise/Telepathy'
type='set'><query xmlns='jabber:iq:roster'><item ask='subscribe'
subscription='none' jid='colltest2 at noise'/></query></iq>

The remote client then accepts the request. We get their presence. Receive:
<presence xmlns='jabber:client' to='colltest1 at noise/Telepathy'
from='colltest2 at noise/Gajim' id='16'/>

We get the roster push. Receive:
<iq xmlns='jabber:client' to='colltest1 at noise/Telepathy'
type='set'><query xmlns='jabber:iq:roster'><item subscription='to'
jid='colltest2 at noise'/></query></iq>

And we get the notification of presence=subscribed. Received:
<presence xmlns='jabber:client' from='colltest2 at noise' id='19'
type='subscribed' to='colltest1 at noise'/>

Note that these three seems to be in the reverse order to the example in
the RFC. As detailed in the RFC, we send presence=subscribe as an
acknowledgement to the presence=subscribed. Send:
<presence type="subscribe" to="colltest2 at noise"
id="msg_18064968_cdc9ed2c_12"/>

Now the fun starts. jabberd2 doesn't seem to understand this as an
acknowledgement, but another subscription request. We arrive at the
unusual state of subscription=to ask=subscribe. Receive:
<iq xmlns='jabber:client' to='colltest1 at noise/Telepathy'
type='set'><query xmlns='jabber:iq:roster'><item ask='subscribe'
subscription='to' jid='colltest2 at noise'/></query></iq>

Then the server talks to itself and realises this is silly. Receive:
<iq xmlns='jabber:client' to='colltest1 at noise/Telepathy'
type='set'><query xmlns='jabber:iq:roster'><item subscription='to'
jid='colltest2 at noise'/></query></iq>

Another presence=subscribed. Receive:
<presence xmlns='jabber:client' from='colltest2 at noise'
id='msg_18064968_cdc9ed2c_12' to='colltest1 at noise' type='subscribed'/>

And then we get their presence again. Receive:
<presence xmlns='jabber:client' to='colltest1 at noise/Telepathy'
from='colltest2 at noise/Gajim' id='16' />

Unfortunately, we ack the presence=subscribed with another
presence=subscribe, and the loop starts again and goes infinitely. This
doesn't happen on any other XMPP servers I've found.

My first instinct to fix this was not to ack presence=subscribed,
unsubscribed or unsubscribe unless they actually result in a state
change against our local idea of subscription states, so the loop can
only go around once.

This fix does stop the looping, but unfortunately means that on any
other working server where we get pushed the changed roster item before
the presence, we won't ack presence sub'd/unsub'd/unsub at all, which
sucks. I can't ignore the subscription state changes in roster pushes
because I use the ask=... to know when another resource requested
authorisation, and I really don't want to start mangling that (working)
code just for the benefit of jabberd2.

So, how important is it that we send these acks? Does it matter that my
fix means we don't send them sometimes? Can anyone think of a better
solution that I've missed?

As a total side point, is there any point acknowledging roster push IQs?
Most servers I've seen just send the ack back to us, which we then ignore.

Regards,
Rob



More information about the JDev mailing list