Subscription process not following Jabber protocol standards

Hi,

I’'ve been having problems with the subscription process using my client (ie. trying to add and subscribe to a user). As a result of my debugging, it seems to me that the server is sending a stray packet that it should not be sending.

I have pasted the following snippet from http://www.jabber.org/protocol/subscriptions.html :


  1. The Jabber User’‘s client then sends a packet of type=’‘subscribe’’ to the contact:

JABBER USER SENDS:

<presence

to=’‘contact@host’’

type=’‘subscribe’’>

I would like to add you to my roster.

  1. The Jabber User’‘s client then receives a second “roster push” from the server with the Contact in the pending sub-state of the ‘‘none’’ subscription state; this pending sub-state is denoted by the inclusion of the ask=’‘subscribe’’ attribute in the roster item:

JABBER USER RECEIVES:

<iq type=’‘set’’>

<query xmlns=’‘jabber:iq:roster’’>

<item

jid=’‘contact@host’’

subscription=’‘none’’

name=’‘contact’’

ask=’‘subscribe’’/>

  1. Once the Jabber User’‘s client sends the packet of type=’‘subscribe’’, that packet is delivered to the Contact (we will assume for the moment that the Contact is online):

CONTACT RECEIVES:

<presence

to=’‘contact@host’’

type=’‘subscribe’’

from=’‘jabberuser@host’’>

I would like to add you to my roster.


I have discovered that, in addition to step 4, “CONTACT” also receives a packet like this:

<iq type=’‘set’’>

<query xmlns=’‘jabber:iq:roster’’>

<item

jid=’‘jabberuser@host’’

subscription=’‘none’’

ask=’‘subscribe’’/>

This is exactly like the packet that “JABBERUSER” receives in step 3, except that this packet is addressed to ‘‘jabberuser@host’’, and the ‘‘name’’ attribute is missing (which makes sense). I’'m sure that this packet should not be sent, as the protocol docs do not mention it.

Please let me know if this is indeed a bug, as it is messing up my client…

Hi,

You’'ve caught some bugs (or at least unclear example) in the subscription protocol document not the server.

First, the name attribute in the roster is only sent if the roster item being described has had it’‘s name set at least once before. So the description below is misleading/wrong since the <presence> subscribe could not have set the name to ‘‘contact’’ with what you’'ve seen of the conversation.

However, it is possible to create roster items without subscribing (setting up group and nickname information) using a iq:roster ‘‘set’’. Later, when you send the <presence> subscribe request, the name attribute will be set when sent (which could be what is being shown). Often clients will do this to “prepare” a roster item before subscribing to it.

As for the contact, they also receive roster updates. Think of the subscription request as automatically creating a roster item for both parties, sender and receiver. the server sees this roster change (a new roster item created) and sends a roster push to notify clients of the change.

Your client needs to be able to handle unexpected roster pushes in some manner (and roster items with subscribe states set to ‘‘none’’ and ask flags on). The server will often change a roster (in particular in response to a roster remove request). Most Jabber clients display the new roster items with an ‘‘unknown’’ icon next to them until the ask flag is cleared.

So the standards document is misleading. I’'ll speak with Peter about clearing that up.

However, you will need to adjust your client to accommodate this behavior.

What is causing your client to crash? I may be able to help.

Sorry, I didn’‘t read your post and the subscription document correctly. The example of the protocol does use the technique of setting the roster item details before subscribing to it. (the process outlined in step 1) which is why the name=’‘contact’’ is present in the roster push of step 2.

Hi Iain,

All roster pushes to my client are “unexpected”, in that my handling of incoming Jabber messages is completely decoupled from my sending out Jabber messages.

The problem is caused my this extra roster push to CONTACT:

<iq type=’‘set’’>

<query xmlns=’‘jabber:iq:roster’’>

<item

jid=’‘jabberuser@host’’

subscription=’‘none’’

ask=’‘subscribe’’/>

It is this particular roster push that I do not expect on the client side. Why? According to my reading of the protocol documents, if I receive a roster item with “ask=subscribe”, it means that I have sent a subscription request to this item/user, and I am “Waiting for Authorization”.

Now, if the target item/user ALSO receives a roster push with “ask=subscribe”, then THAT client also interprets it as “I have sent a subscription to this item, and I am Waiting for Authorization”, when in reality, that item/user is being was being subscribed TO.

If user A sends a subscription to user B, then I would think that the roster push sent to user A should have “ask=subscribe”, and the roster push to user B should NOT have “ask=subscribe”. The Tipic server did not include the roster push to user B, which is why my client worked with it.

But it’‘s not really the fact that there is an extra roster push…it’‘s because the extra roster push has “ask=subscribe” in it, when I think it shouldn’'t. If the roster push to user B did not have “ask=subscribe” in it, I think my client would work fine…

I could be wrong…which would mean that “ask=subscribe” could mean both “I have sent out a subscription request” and “I have received a subscription request”. In that case, I would not know how to differentiate between the two.

Please help me since I’'m confused!

Thanks,

Aman

Ok, I see what you’‘re saying. That makes a lot of sense. I rechecked jabberd’‘s behavior and I think I’'ve got it wrong. Jabberd (and Tipic) is not doing roster pushes as I thought.

This is actually good news for me because it is easier to support this behavior than the one I had. I’'ll make the change and push it into Alpha 4.

Related to this topic is the situation where you send a subscription request to a user, but that user is offline.

I would expect that when that user comes online, they would receive this subscription request in the form <presence type=“subscribe”…>, but this packet does not get sent to the user. Instead, in their roster push, they get the “ask=subscribe” attribute, which confuses not just my client, but the Exodus client as well.

Presumably, they should receive a , and not the “ask=subscribe” attribute in the roster push…

I entered that issue along with the roster change since now there is no other way for the user to know a presence update occured (roster items won’'t be sent). The change may require a slight schema change to hold a flag… or I may reuse the ask status field.

Thanks