Subject: [xmpp] 3921bis and directed presence

From: Waqas Hussain <[email-masked]>
Date: Mon, 4 Oct 2010 18:05:34 +0500

Directed presence and it's interaction with other stanzas and state is
underspecified.

Things to consider:

1. How it interacts with incoming presence probes
2. How it interacts with subscription changes
3. How it interacts with outgoing directed presence and presence broadcasts
4. How it interacts with incoming presence
Extra 1: How the above interactions change when the remote JID is or
is not subscribed to the user
Extra 2: How the above interactions change with full JIDs (remote or
user's) vs bare JIDs (remote vs user's)

The following are some of the cases. The interactions are complex
enough that we can probably come up with more.

1. How it interacts with incoming presence probes

What is already specified: If we get a probe from a JID to which we
sent directed presence, we should reply with a blank available
presence.

What if the directed presence was sent to full JID A, but probe is
from full JID B, to either the local full JID? To the local bare JID?
What if the probe is from a full JID, and directed presence was sent
by two local resources to two different full JIDs?

2. How it interacts with subscription changes

Subscription changes often cause stanzas to be auto-sent. e.g.,
unavailable presence may be sent if we take remove a contact. But if
we have sent the contact a directed presence, do we clear that from
our directed presence tables? Or should we perhaps skip the
unavailable presence?

3. How it interacts with outgoing directed presence and presence broadcasts

Do we clear that directed presence from our local tables when a
directed presence had been sent, but now a presence is being sent as
part of a broadcast?
Do we clear all full JID in our directed presence tables if the user
sends an unavailable to a bare JID?

4. How it interacts with incoming presence

We should probably clear our local directed presence tables on getting
an unavailable presence from the remote JID. I don't think this is
specified, but seems obvious.
But what if the directed presence was to the bare JID, while the
unavailable if from a full JID? The opposite? What if both were full
JIDs?
What if we get an unavailable to the user's bare JID, but a directed
presence had been sent from a full JID which isn't available (hasn't
sent initial presence)? We shouldn't clear that directed presence
then?

5. How do we apply resource limits?

What do we do if the user is sending directed presence to a million
remote JIDs, leading to a huge table on the server?

The current implementation of the above in Prosody is a directed
presence table, maintained per local client session, which just stores
JIDs (without considering full vs. bare). We set entries on outgoing
directed presence, and clear them on outgoing directed unavailable
presence. I discussed this a bit with Dave Cridland, and it appears
M-Link pretty much does the same thing. This makes us compliant except
for the responding to probes part. I suspect doing The Right Thing(tm)
for all above cases is going to add quite some complexity.

--
Waqas Hussain

---

From: Peter Saint-Andre <[email-masked]>
Date: Mon, 04 Oct 2010 16:37:47 -0600

> Directed presence and it's interaction with other stanzas and state is

Perhaps. I think that some of the matters you discuss here are best left
to the professional judgment of server developers.

> by two local resources to two different full JIDs?

I think it is fine to base these decisions on a bare JID in all cases
(if my client sent directed presence to full@domain/A but my server
receives the probe from full@domain/B then it's OK for my server to
reply to the probe, etc.). Do you think we need to spell out every
possible combination? Do you think there are security concerns about
authorization based on full JIDs vs. bare JIDs?

> our directed presence tables? Or should we perhaps skip the

If I have removed your authorization to see my presence, then my server
needs to send unavailable to you. Why would my having sent you directed
presence change that?

> directed presence had been sent, but now a presence is being sent as

I think that broadcast presence trumps directed presence if you are in
my roster and authorized to receive broadcast presence from me. If you
are not authorized to receive broadbast presence from me (e.g., not in
my roster), then if I send broadcast presence of type "available" you
wouldn't receive that (since you're not authorized to receive it). The
only exception is presence of type unavailable.

> for all above cases is going to add quite some complexity.

Peter

-- 
Peter Saint-Andre
https://stpeter.im/

---

From: Peter Saint-Andre <[email-masked]>
Date: Mon, 04 Oct 2010 16:43:46 -0600

Oops, sent prematurely. More comments inline.

>> sends an unavailable to a bare JID?

I think so.

>> specified, but seems obvious.

I don't think you clear out your local directed presence tables here,
because directed presence is not necessarily bi-directional. Just clear
it when your client sends unavailable or goes offline.

>> unavailable if from a full JID? The opposite? What if both were full

If you don't clear the table, there's no need to worry about these
scenarios.

>> sent initial presence)? We shouldn't clear that directed presence

I don't see a strong need to do so. Use your best judgment.

>> remote JIDs, leading to a huge table on the server?

Nuke 'em. See Section 13.12 of 3920bis.

>> directed presence, and clear them on outgoing directed unavailable

Yes, I would expect that many servers are implemented that way.

>> I discussed this a bit with Dave Cridland, and it appears
>> for the responding to probes part. 

In what way are you not compliant?

>> I suspect doing The Right Thing(tm)

That depends on what the right thing is. :)

Peter

-- 
Peter Saint-Andre
https://stpeter.im/

---

From: Peter Saint-Andre <[email-masked]>
Date: Tue, 05 Oct 2010 12:44:38 -0600

>> to the professional judgment of server developers.

I suggest:

###

4.6.  Directed Presence

   This section supplements and in some respects modifies the rules for
   client and server processing of presence notifications and presence
   probes, but only for the special case of directed presence.

4.6.1.  General Considerations

   In general, a client sends directed presence when it wishes to share
   availability information with an entity that is not subscribed to its
   presence, typically on a temporary basis.  Common uses of directed
   presence include casual one-to-one chat sessions as described under
   Section 5.1 and multi-user chat rooms as described in [XEP-0045].

   The temporary relationship established by sharing directed presence
   with another entity is secondary to the permanent relationship
   established through a presence subscription.  Therefore, the acts of
   creating, modifying, or cancelling a presence subscription MUST take
   precedence over the rules specified in the following subsections.
   For example, if a user shares directed presence with a contact but
   then adds the contact to the user's roster by completing the presence
   subscription "handshake", the user's server MUST treat the contact
   just as it would any normal subscriber.  Similarly, if a user then
   cancels the contact's subscription to the user's presence, the user's
   server MUST send unavailable presence to the contact (even if the
   user has sent directed presence to the contact).

###

>> authorization based on full JIDs vs. bare JIDs?

I suggest:

###

4.6.6.  Server Processing of Presence Probes

   If a user's client has sent directed presence to another entity
   (e.g., a one-to-one chat partner or a multi-user chat room), after
   some time the entity or its server might want to know if the client
   is still online.  This scenario is especially common in the case of
   multi-user chat rooms, in which the user might be a participant for a
   long period of time.  If the user's client goes offline without the
   chat room being informed (either by the client or the client's
   server), the user's representation in the room might become a "ghost"
   which appears to be participating but which in fact is no longer
   present in the room.  To detect such "ghosts", some multi-user chat
   room implementations send presence probes to users that have joined
   the room.

   In the case of directed presence, the probing entity SHOULD send the
   probe to the full JID from which it received directed presence, not
   the user's bare JID without a resourcepart, because the temporary
   "authorization" involved with directed presence is based on a full
   JID.  When the user's server receives a probe, it MUST first apply
   any logic associated with presence subscriptions as described under
   Section 4.3.2.  If the probing entity does not have a subscription to
   the user's presence, then the server MUST check if the user has sent
   directed presence to the entity during its current session; if so,
   the server SHOULD answer the probe with only mere presence of type
   "available" or "unavailable" (i.e., not including child elements) and
   only for that full JID (i.e., not for any other resources that might
   be currently associated with the user's bare JID).

###

>> needs to send unavailable to you. Why would my having sent you directed

See "General Considerations" above.

>>> sends an unavailable to a bare JID?

I think this is covered by the "General Considerations".

> If you don't clear the table, there's no need to worry about these

Sorry, I wasn't thinking clearly. Yes, it makes sense to clear out the
table if you receive unavailable presence from the entity to which you
sent directed presence.

I propose adding the following paragraph to the "General Considerations":

   XMPP servers typically implement directed presence by keeping a list
   of the entities to which a user has sent directed presence during the
   user's current session, the clearing the list when the user goes
   offline.  The server MUST remove any entity to which the user sends
   directed unavailable presence and SHOULD remove any entity that sends
   unavailable presence to the user.

> I don't see a strong need to do so. Use your best judgment.

I'm a bit confused about this scenario. Could you describe it in more
detail?

> That depends on what the right thing is. :)

Perhaps the text proposed above gets us closer to the right thing.

Peter

-- 
Peter Saint-Andre
https://stpeter.im/

---

From: Peter Saint-Andre <[email-masked]>
Date: Tue, 05 Oct 2010 14:48:40 -0600

To summarize and for ease of review, here is the text I currently have
in my working copy...

###

4.6.  Directed Presence

   This section supplements the rules for client and server processing
   of presence notifications and presence probes, but only for the
   special case of directed presence.

   The temporary relationship established by sharing directed presence
   with another entity is secondary to the permanent relationship
   established through a presence subscription.  Therefore, the acts of
   creating, modifying, or cancelling a presence subscription MUST take
   precedence over the rules specified in the following subsections.
   For example, if a user shares directed presence with a contact but
   then adds the contact to the user's roster by completing the presence
   subscription "handshake", the user's server MUST treat the contact
   just as it would any normal subscriber as described under Section 3,
   for example by sending subsequent presence broadcasts to the contact.
   Similarly, if the user then cancels the contact's subscription to the
   user's presence, the user's server MUST handle the cancellation just
   as it normally would as described under Section 3.2, which includes
   sending unavailable presence to the contact even if the user has sent
   directed presence to the contact.

   XMPP servers typically implement directed presence by keeping a list
   of the entities (bare JIDs or full JIDs) to which a user has sent
   directed presence during the user's current session for a given
   resource (full JID), then clearing the list when the user goes
   offline.  The server MUST remove any entity to which the user sends
   directed unavailable presence and SHOULD remove any entity that sends
   unavailable presence to the user.

4.6.2.  Client Generation of Directed Presence

   As noted, directed presence is a client-generated presence stanza
   with a 'to' attribute whose value is the bare JID or full JID of the
   other entity and with either no 'type' attribute (indicating
   availability) or a 'type' attribute whose value is "unavailable".

4.6.3.  Server Processing of Outbound Directed Presence

   When the user's server receives a directed presence stanza, it SHOULD
   process it according to the following rules.

   1.  If the user sends directed available or unavailable presence to a
       contact that is in the user's roster with a subscription type of
       "from" or "both" after having sent initial presence and before
       sending unavailable presence broadcast (i.e., during the user's
       presence session), the user's server MUST locally deliver or
       remotely route the full XML of that presence stanza but SHOULD
       NOT otherwise modify the contact's status regarding presence
       broadcast (i.e., it SHOULD include the contact's JID in any
       subsequent presence broadcasts initiated by the user).

   2.  If the user sends directed presence to an entity that is not in
       the user's roster with a subscription type of "from" or "both"
       after having sent initial presence and before sending unavailable
       presence broadcast (i.e., during the user's presence session),
       the user's server MUST locally deliver or remotely route the full
       XML of that presence stanza to the entity but MUST NOT modify the
       contact's status regarding available presence broadcast (i.e., it
       MUST NOT include the entity's JID in any subsequent broadcasts of
       available presence initiated by the user); however, if the
       available resource from which the user sent the directed presence
       becomes unavailable, the user's server MUST route that
       unavailable presence to the entity (if the user has not yet sent
       directed unavailable presence to that entity).

   3.  If the user sends directed presence without first sending initial
       presence or after having sent unavailable presence broadcast
       (i.e., the resource is connected but not available), the user's
       server MUST treat the entity to which the user sends directed
       presence as in case #2 above.

4.6.4.  Server Processing of Inbound Directed Presence

   From the perspective of the contact's server, there is no significant
   difference between presence broadcast and directed presence, so the
   contact's server follows the rules for processing of inbound presence
   defined under Section 4.3.2, Section 4.4.3, and Section 4.5.3.

4.6.5.  Client Processing of Inbound Directed Presence

   From the perspective of the contact's client, there is no significant
   difference between presence broadcast and directed presence, so the
   contact's client follows the rules for processing of inbound presence
   defined under Section 4.4.3.

###

---

From: Waqas Hussain <[email-masked]>
Date: Wed, 6 Oct 2010 23:49:25 +0500

>  JID.  When the user's server receives a probe, it MUST first apply

Probes being to the full JID is good. Could we also have it be from
the full JID the directed presence was sent to?

>   unavailable presence to the user.

s/the clearing the/then clearing the/

"to which the user sends directed unavailable presence" - shouldn't
undirected unavailable presence also count? And perhaps undirected
available presence too. Directed presence state is effectively us
maintaining a local version of what the remote contact thinks our
presence is. So we should change our local state to match what the
remote user sees.

> I'm a bit confused about this scenario. Could you describe it in more

Basically: If a resource which isn't available sends a directed
presence to a contact, and then the contact sends an unavailable
presence to the user's bare JID, should the resource's directed
presence table be cleared? The resource isn't available, so doesn't
actually get the unavailable presence. To maintain perfect consistency
in how both users see each other, perhaps that unavailable presence
should be sent to that resource, and directed presence cleared (i.e.,
broadcasts should take directed presence into account while
determining resource availability).

This may be too major a change at this point (it changes the
definition of AVAILABLE RESOURCE to take directed presence into
account).

> Perhaps the text proposed above gets us closer to the right thing.

+1

--
Waqas Hussain

---

From: Peter Saint-Andre <[email-masked]>
Date: Wed, 06 Oct 2010 13:29:47 -0600

Hi Waqas, thanks for the feedback. Comments inline.

> the full JID the directed presence was sent to?

Changed in my working copy to:

   In the case of directed presence, the probing entity SHOULD send the
   probe from the JID that received directed presence (whether a full
   JID or a bare JID).  The probe SHOULD be sent to the user's full JID,
   not the user's bare JID without a resourcepart, because the temporary
   "authorization" involved with directed presence is based on the full
   JID from which the user sent directed presence to the probing entity.

My reasoning: the user might have sent directed presence to a bare JID,
not a full JID.

> s/the clearing the/then clearing the/

Yep, I already found that one. :)

> undirected unavailable presence also count? 

Yes, that's what we mean by "clearing the list when the user goes
offline" (however, the user could go offline ungracefully).

I've clarified that thusly:

   offline (e.g., by sending a broadcast presence stanza of type
   "unavailable").

> And perhaps undirected
> available presence too. 

No, that doesn't modify the directed presence list -- unless an entity
in the directed presence list is subscribed to the user's presence, but
that's handled by this rule:

   The temporary relationship established by sharing directed presence
   with another entity is secondary to the permanent relationship
   established through a presence subscription.

> Directed presence state is effectively us

Correct.

> presence table be cleared? 

Yes, but we already said that:

   The server MUST remove from the directed presence
   list (or its functional equivalent) any entity to which the user
   sends directed unavailable presence and SHOULD remove any entity that
   sends unavailable presence to the user.

> The resource isn't available, so doesn't

The concept of an available resource governs server handling of presence
(and other) stanzas sent to the user's bare JID. Even if the resource
has not yet sent initial presence to the server (i.e., it's a connected
resource but not an available resource), it is the server's
responsibility to deliver stanzas that are addressed to the full JID of
that resource. Is that not sufficiently clear? Section 10.5.3.3 of
3920bis states:

   If the JID contained in the 'to' attribute is of the form
   <localpart@domainpart/resource> and there is a connected resource
   that exactly matches the full JID, the server SHOULD deliver the
   stanza to that connected resource.

Looking at that text afresh, I realize that it would be best to change
SHOULD to MUST -- after all, it's a core requirement of an XMPP server
to deliver stanzas. :) A client doesn't need to send presence to its
server (3921bis stuff) in order to send and receive stanzas.

Peter

-- 
Peter Saint-Andre
https://stpeter.im/

---

From: Waqas Hussain <[email-masked]>
Date: Thu, 7 Oct 2010 00:50:11 +0500

> server (3921bis stuff) in order to send and receive stanzas.

Well, everything looks good :)

--
Waqas Hussain