tech-invite   World Map     

3GPP     Specs     Glossaries     Architecture     IMS     UICC       IETF     RFCs     Groups     SIP     ABNFs       Search

RFC 3921

 
 
 

Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence

Part 3 of 4, p. 45 to 74
Prev RFC Part       Next RFC Part

 


prevText      Top      Up      ToC       Page 45 
8.4.  Unsubscribing

   At any time after subscribing to a contact's presence information, a
   user MAY unsubscribe.  While the XML that the user sends to make this
   happen is the same in all instances, the subsequent subscription
   state is different depending on the subscription state obtaining when
   the unsubscribe "command" is sent.  Both possible scenarios are
   described below.

8.4.1.  Case #1: Unsubscribing When Subscription is Not Mutual

   In the first case, the user has a subscription to the contact's
   presence information but the contact does not have a subscription to
   the user's presence information (i.e., the subscription is not yet
   mutual).

   1.  If the user wants to unsubscribe from the contact's presence
       information, the user MUST send a presence stanza of type
       "unsubscribe" to the contact:

   <presence to='contact@example.org' type='unsubscribe'/>

   2.  As a result, the user's server (1) MUST send a roster push to all
       of the user's available resources that have requested the roster,
       containing an updated roster item for the contact with the
       'subscription' attribute set to a value of "none"; and (2) MUST
       route the presence stanza of type "unsubscribe" to the contact,
       first stamping the 'from' address as the bare JID
       (<user@example.com>) of the user:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>

Top      Up      ToC       Page 46 
   3.  Upon receiving the presence stanza of type "unsubscribe"
       addressed to the contact, the contact's server (1) MUST initiate
       a roster push to all available resources associated with the
       contact that have requested the roster, containing an updated
       roster item for the user with the 'subscription' attribute set to
       a value of "none" (if the contact is unavailable or has not
       requested the roster, the contact's server MUST modify the roster
       item and send that modified item the next time the contact
       requests the roster); and (2) MUST deliver the "unsubscribe"
       state change notification to the contact:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='none'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>

   4.  Upon receiving the presence stanza of type "unsubscribe", the
       contact SHOULD acknowledge receipt of that subscription state
       notification through either "affirming" it by sending a presence
       stanza of type "unsubscribed" to the user or "denying" it by
       sending a presence stanza of type "subscribed" to the user; this
       step does not necessarily affect the subscription state (see
       Subscription States (Section 9) for details), but instead lets
       the contact's server know that it MUST no longer send
       notification of the subscription state change to the contact (see
       Section 9.4).

   5.  The contact's server then (1) MUST send a presence stanza of type
       "unsubscribed" to the user; and (2) SHOULD send unavailable
       presence from all of the contact's available resources to the
       user:

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>

Top      Up      ToC       Page 47 
   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>

   6.  When the user's server receives the presence stanzas of type
       "unsubscribed" and "unavailable", it MUST deliver them to the
       user:

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>

   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>

   7.  Upon receiving the presence stanza of type "unsubscribed", the
       user SHOULD acknowledge receipt of that subscription state
       notification through either "affirming" it by sending a presence
       stanza of type "unsubscribe" to the contact or "denying" it by
       sending a presence stanza of type "subscribe" to the contact;
       this step does not necessarily affect the subscription state (see
       Subscription States (Section 9) for details), but instead lets
       the user's server know that it MUST no longer send notification
       of the subscription state change to the user (see Section 9.4).

8.4.2.  Case #2: Unsubscribing When Subscription is Mutual

   In the second case, the user has a subscription to the contact's
   presence information and the contact also has a subscription to the
   user's presence information (i.e., the subscription is mutual).

   1.  If the user wants to unsubscribe from the contact's presence
       information, the user MUST send a presence stanza of type
       "unsubscribe" to the contact:

   <presence to='contact@example.org' type='unsubscribe'/>

   2.  As a result, the user's server (1) MUST send a roster push to all
       of the user's available resources that have requested the roster,
       containing an updated roster item for the contact with the
       'subscription' attribute set to a value of "from"; and (2) MUST
       route the presence stanza of type "unsubscribe" to the contact,
       first stamping the 'from' address as the bare JID
       (<user@example.com>) of the user:

Top      Up      ToC       Page 48 
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='from'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>

   3.  Upon receiving the presence stanza of type "unsubscribe"
       addressed to the contact, the contact's server (1) MUST initiate
       a roster push to all available resources associated with the
       contact that have requested the roster, containing an updated
       roster item for the user with the 'subscription' attribute set to
       a value of "to" (if the contact is unavailable or has not
       requested the roster, the contact's server MUST modify the roster
       item and send that modified item the next time the contact
       requests the roster); and (2) MUST deliver the "unsubscribe"
       state change notification to the contact:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='to'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>

   4.  Upon receiving the presence stanza of type "unsubscribe", the
       contact SHOULD acknowledge receipt of that subscription state
       notification through either "affirming" it by sending a presence
       stanza of type "unsubscribed" to the user or "denying" it by
       sending a presence stanza of type "subscribed" to the user; this

Top      Up      ToC       Page 49 
       step does not necessarily affect the subscription state (see
       Subscription States (Section 9) for details), but instead lets
       the contact's server know that it MUST no longer send
       notification of the subscription state change to the contact (see
       Section 9.4).

   5.  The contact's server then (1) MUST send a presence stanza of type
       "unsubscribed" to the user; and (2) SHOULD send unavailable
       presence from all of the contact's available resources to the
       user:

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>

   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>

   6.  When the user's server receives the presence stanzas of type
       "unsubscribed" and "unavailable", it MUST deliver them to the
       user:

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>

   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>

   7.  Upon receiving the presence stanza of type "unsubscribed", the
       user SHOULD acknowledge receipt of that subscription state
       notification through either "affirming" it by sending a presence
       stanza of type "unsubscribe" to the contact or "denying" it by
       sending a presence stanza of type "subscribe" to the contact;
       this step does not necessarily affect the subscription state (see
       Subscription States (Section 9) for details), but instead lets
       the user's server know that it MUST no longer send notification
       of the subscription state change to the user (see Section 9.4).

   Note: Obviously this does not result in removal of the roster item
   from the user's roster, and the contact still has a subscription to
   the user's presence information.  In order to both completely cancel

Top      Up      ToC       Page 50 
   a mutual subscription and fully remove the roster item from the
   user's roster, the user SHOULD update the roster item with
   subscription='remove' as defined under Removing a Roster Item and
   Cancelling All Subscriptions (Section 8.6).

8.5.  Cancelling a Subscription

   At any time after approving a subscription request from a user, a
   contact MAY cancel that subscription.  While the XML that the contact
   sends to make this happen is the same in all instances, the
   subsequent subscription state is different depending on the
   subscription state obtaining when the cancellation was sent.  Both
   possible scenarios are described below.

8.5.1.  Case #1: Cancelling When Subscription is Not Mutual

   In the first case, the user has a subscription to the contact's
   presence information but the contact does not have a subscription to
   the user's presence information (i.e., the subscription is not yet
   mutual).

   1.  If the contact wants to cancel the user's subscription, the
       contact MUST send a presence stanza of type "unsubscribed" to the
       user:

   <presence to='user@example.com' type='unsubscribed'/>

   2.  As a result, the contact's server (1) MUST send a roster push to
       all of the contact's available resources that have requested the
       roster, containing an updated roster item for the user with the
       'subscription' attribute set to a value of "none"; (2) MUST route
       the presence stanza of type "unsubscribed" to the user, first
       stamping the 'from' address as the bare JID
       (<contact@example.org>) of the contact; and (3) SHOULD send
       unavailable presence from all of the contact's available
       resources to the user:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='none'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>

Top      Up      ToC       Page 51 
   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>

   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>

   3.  Upon receiving the presence stanza of type "unsubscribed"
       addressed to the user, the user's server (1) MUST initiate a
       roster push to all of the user's available resources that have
       requested the roster, containing an updated roster item for the
       contact with the 'subscription' attribute set to a value of
       "none" (if the user is unavailable or has not requested the
       roster, the user's server MUST modify the roster item and send
       that modified item the next time the user requests the roster);
       (2) MUST deliver the "unsubscribed" state change notification to
       all of the user's available resources; and (3) MUST deliver the
       unavailable presence to all of the user's available resources:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='none'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>

   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>

   4.  Upon receiving the presence stanza of type "unsubscribed", the
       user SHOULD acknowledge receipt of that subscription state
       notification through either "affirming" it by sending a presence
       stanza of type "unsubscribe" to the contact or "denying" it by
       sending a presence stanza of type "subscribe" to the contact;

Top      Up      ToC       Page 52 
       this step does not necessarily affect the subscription state (see
       Subscription States (Section 9) for details), but instead lets
       the user's server know that it MUST no longer send notification
       of the subscription state change to the user (see Section 9.4).

8.5.2.  Case #2: Cancelling When Subscription is Mutual

   In the second case, the user has a subscription to the contact's
   presence information and the contact also has a subscription to the
   user's presence information (i.e., the subscription is mutual).

   1.  If the contact wants to cancel the user's subscription, the
       contact MUST send a presence stanza of type "unsubscribed" to the
       user:

   <presence to='user@example.com' type='unsubscribed'/>

   2.  As a result, the contact's server (1) MUST send a roster push to
       all of the contact's available resources that have requested the
       roster, containing an updated roster item for the user with the
       'subscription' attribute set to a value of "to"; (2) MUST route
       the presence stanza of type "unsubscribed" to the user, first
       stamping the 'from' address as the bare JID
       (<contact@example.org>) of the contact; and (3) SHOULD send
       unavailable presence from all of the contact's available
       resources to all of the user's available resources:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='to'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>

   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>

Top      Up      ToC       Page 53 
   3.  Upon receiving the presence stanza of type "unsubscribed"
       addressed to the user, the user's server (1) MUST initiate a
       roster push to all of the user's available resources that have
       requested the roster, containing an updated roster item for the
       contact with the 'subscription' attribute set to a value of
       "from" (if the user is unavailable or has not requested the
       roster, the user's server MUST modify the roster item and send
       that modified item the next time the user requests the roster);
       and (2) MUST deliver the "unsubscribed" state change notification
       to all of the user's available resources; and (3) MUST deliver
       the unavailable presence to all of the user's available
       resources:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='from'
           name='MyContact'>
         <group>MyBuddies</group>
       </item>
     </query>
   </iq>

   <presence
       from='contact@example.org'
       to='user@example.com'
       type='unsubscribed'/>

   <presence
       from='contact@example.org/resource'
       to='user@example.com'
       type='unavailable'/>

   4.  Upon receiving the presence stanza of type "unsubscribed", the
       user SHOULD acknowledge receipt of that subscription state
       notification through either "affirming" it by sending a presence
       stanza of type "unsubscribe" to the contact or "denying" it by
       sending a presence stanza of type "subscribe" to the contact;
       this step does not necessarily affect the subscription state (see
       Subscription States (Section 9) for details), but instead lets
       the user's server know that it MUST no longer send notification
       of the subscription state change to the user (see Section 9.4).

   Note: Obviously this does not result in removal of the roster item
   from the contact's roster, and the contact still has a subscription
   to the user's presence information.  In order to both completely
   cancel a mutual subscription and fully remove the roster item from

Top      Up      ToC       Page 54 
   the contact's roster, the contact should update the roster item with
   subscription='remove' as defined under Removing a Roster Item and
   Cancelling All Subscriptions (Section 8.6).

8.6.  Removing a Roster Item and Cancelling All Subscriptions

   Because there may be many steps involved in completely removing a
   roster item and cancelling subscriptions in both directions, the
   roster management protocol includes a "shortcut" method for doing so.
   The process may be initiated no matter what the current subscription
   state is by sending a roster set containing an item for the contact
   with the 'subscription' attribute set to a value of "remove":

   <iq type='set' id='remove1'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='remove'/>
     </query>
   </iq>

   When the user removes a contact from his or her roster by setting the
   'subscription' attribute to a value of "remove", the user's server
   (1) MUST automatically cancel any existing presence subscription
   between the user and the contact (both 'to' and 'from' as
   appropriate); (2) MUST remove the roster item from the user's roster
   and inform all of the user's available resources that have requested
   the roster of the roster item removal; (3) MUST inform the resource
   that initiated the removal of success; and (4) SHOULD send
   unavailable presence from all of the user's available resources to
   the contact:

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribed'/>

Top      Up      ToC       Page 55 
   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='contact@example.org'
           subscription='remove'/>
     </query>
   </iq>

   <iq type='result' id='remove1'/>

   <presence
       from='user@example.com/resource'
       to='contact@example.org'
       type='unavailable'/>

   Upon receiving the presence stanza of type "unsubscribe", the
   contact's server (1) MUST initiate a roster push to all available
   resources associated with the contact that have requested the roster,
   containing an updated roster item for the user with the
   'subscription' attribute set to a value of "to" (if the contact is
   unavailable or has not requested the roster, the contact's server
   MUST modify the roster item and send that modified item the next time
   the contact requests the roster); and (2) MUST also deliver the
   "unsubscribe" state change notification to all of the contact's
   available resources:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='to'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribe'/>

   Upon receiving the presence stanza of type "unsubscribed", the
   contact's server (1) MUST initiate a roster push to all available
   resources associated with the contact that have requested the roster,
   containing an updated roster item for the user with the
   'subscription' attribute set to a value of "none" (if the contact is
   unavailable or has not requested the roster, the contact's server

Top      Up      ToC       Page 56 
   MUST modify the roster item and send that modified item the next time
   the contact requests the roster); and (2) MUST also deliver the
   "unsubscribe" state change notification to all of the contact's
   available resources:

   <iq type='set'>
     <query xmlns='jabber:iq:roster'>
       <item
           jid='user@example.com'
           subscription='none'
           name='SomeUser'>
         <group>SomeGroup</group>
       </item>
     </query>
   </iq>

   <presence
       from='user@example.com'
       to='contact@example.org'
       type='unsubscribed'/>

   Upon receiving the presence stanza of type "unavailable" addressed to
   the contact, the contact's server MUST deliver the unavailable
   presence to all of the user's available resources:

   <presence
       from='user@example.com/resource'
       to='contact@example.org'
       type='unavailable'/>

   Note: When the user removes the contact from the user's roster, the
   end state of the contact's roster is that the user is still in the
   contact's roster with a subscription state of "none"; in order to
   completely remove the roster item for the user, the contact needs to
   also send a roster removal request.

9.  Subscription States

   This section provides detailed information about subscription states
   and server handling of subscription-related presence stanzas (i.e.,
   presence stanzas of type "subscribe", "subscribed", "unsubscribe",
   and "unsubscribed").

9.1.  Defined States

   There are nine possible subscription states, which are described here
   from the user's (not contact's) perspective:

Top      Up      ToC       Page 57 
   1.  "None" = contact and user are not subscribed to each other, and
       neither has requested a subscription from the other

   2.  "None + Pending Out" = contact and user are not subscribed to
       each other, and user has sent contact a subscription request but
       contact has not replied yet

   3.  "None + Pending In" = contact and user are not subscribed to each
       other, and contact has sent user a subscription request but user
       has not replied yet (note: contact's server SHOULD NOT push or
       deliver roster items in this state, but instead SHOULD wait until
       contact has approved subscription request from user)

   4.  "None + Pending Out/In" = contact and user are not subscribed to
       each other, contact has sent user a subscription request but user
       has not replied yet, and user has sent contact a subscription
       request but contact has not replied yet

   5.  "To" = user is subscribed to contact (one-way)

   6.  "To + Pending In" = user is subscribed to contact, and contact
       has sent user a subscription request but user has not replied yet

   7.  "From" = contact is subscribed to user (one-way)

   8.  "From + Pending Out" = contact is subscribed to user, and user
       has sent contact a subscription request but contact has not
       replied yet

   9.  "Both" = user and contact are subscribed to each other (two-way)

9.2.  Server Handling of Outbound Presence Subscription Stanzas

   Outbound presence subscription stanzas enable the user to manage his
   or her subscription to the contact's presence information (via the
   "subscribe" and "unsubscribe" types), and to manage the contact's
   access to the user's presence information (via the "subscribed" and
   "unsubscribed" types).

   Because it is possible for the user's server and the contact's server
   to lose synchronization regarding subscription states, the user's
   server MUST without exception route all outbound presence stanzas of
   type "subscribe" or "unsubscribe" to the contact so that the user is
   able to resynchronize his or her subscription to the contact's
   presence information if needed.

Top      Up      ToC       Page 58 
   The user's server SHOULD NOT route a presence stanza of type
   "subscribed" or "unsubscribed" to the contact if the stanza does not
   result in a subscription state change from the user's perspective,
   and MUST NOT make a state change.  If the stanza results in a
   subscription state change, the user's server MUST route the stanza to
   the contact and MUST make the appropriate state change.  These rules
   are summarized in the following tables.

   Table 1: Recommended handling of outbound "subscribed" stanzas

   +----------------------------------------------------------------+
   |  EXISTING STATE          |  ROUTE?  |  NEW STATE               |
   +----------------------------------------------------------------+
   |  "None"                  |  no      |  no state change         |
   |  "None + Pending Out"    |  no      |  no state change         |
   |  "None + Pending In"     |  yes     |  "From"                  |
   |  "None + Pending Out/In" |  yes     |  "From + Pending Out"    |
   |  "To"                    |  no      |  no state change         |
   |  "To + Pending In"       |  yes     |  "Both"                  |
   |  "From"                  |  no      |  no state change         |
   |  "From + Pending Out"    |  no      |  no state change         |
   |  "Both"                  |  no      |  no state change         |
   +----------------------------------------------------------------+

   Table 2: Recommended handling of outbound "unsubscribed" stanzas

   +----------------------------------------------------------------+
   |  EXISTING STATE          |  ROUTE?  |  NEW STATE               |
   +----------------------------------------------------------------+
   |  "None"                  |  no      |  no state change         |
   |  "None + Pending Out"    |  no      |  no state change         |
   |  "None + Pending In"     |  yes     |  "None"                  |
   |  "None + Pending Out/In" |  yes     |  "None + Pending Out"    |
   |  "To"                    |  no      |  no state change         |
   |  "To + Pending In"       |  yes     |  "To"                    |
   |  "From"                  |  yes     |  "None"                  |
   |  "From + Pending Out"    |  yes     |  "None + Pending Out"    |
   |  "Both"                  |  yes     |  "To"                    |
   +----------------------------------------------------------------+

9.3.  Server Handling of Inbound Presence Subscription Stanzas

   Inbound presence subscription stanzas request a subscription-related
   action from the user (via the "subscribe" type), inform the user of
   subscription-related actions taken by the contact (via the
   "unsubscribe" type), or enable the contact to manage the user's
   access to the contact's presence information (via the "subscribed"
   and "unsubscribed" types).

Top      Up      ToC       Page 59 
   When the user's server receives a subscription request for the user
   from the contact (i.e., a presence stanza of type "subscribe"), it
   MUST deliver that request to the user for approval if the user has
   not already granted the contact access to the user's presence
   information and if there is no pending inbound subscription request;
   however, the user's server SHOULD NOT deliver the new request if
   there is a pending inbound subscription request, since the previous
   subscription request will have been recorded.  If the user has
   already granted the contact access to the user's presence
   information, the user's server SHOULD auto-reply to an inbound
   presence stanza of type "subscribe" from the contact by sending a
   presence stanza of type "subscribed" to the contact on behalf of the
   user; this rule enables the contact to resynchronize the subscription
   state if needed.  These rules are summarized in the following table.

   Table 3: Recommended handling of inbound "subscribe" stanzas

   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  yes       |  "None + Pending In"     |
   |  "None + Pending Out"    |  yes       |  "None + Pending Out/In" |
   |  "None + Pending In"     |  no        |  no state change         |
   |  "None + Pending Out/In" |  no        |  no state change         |
   |  "To"                    |  yes       |  "To + Pending In"       |
   |  "To + Pending In"       |  no        |  no state change         |
   |  "From"                  |  no *      |  no state change         |
   |  "From + Pending Out"    |  no *      |  no state change         |
   |  "Both"                  |  no *      |  no state change         |
   +------------------------------------------------------------------+

   * Server SHOULD auto-reply with "subscribed" stanza

   When the user's server receives a presence stanza of type
   "unsubscribe" for the user from the contact, if the stanza results in
   a subscription state change from the user's perspective then the
   user's server SHOULD auto-reply by sending a presence stanza of type
   "unsubscribed" to the contact on behalf of the user, MUST deliver the
   "unsubscribe" stanza to the user, and MUST change the state.  If no
   subscription state change results, the user's server SHOULD NOT
   deliver the stanza and MUST NOT change the state.  These rules are
   summarized in the following table.

Top      Up      ToC       Page 60 
   Table 4: Recommended handling of inbound "unsubscribe" stanzas

   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  no        |  no state change         |
   |  "None + Pending Out"    |  no        |  no state change         |
   |  "None + Pending In"     |  yes *     |  "None"                  |
   |  "None + Pending Out/In" |  yes *     |  "None + Pending Out"    |
   |  "To"                    |  no        |  no state change         |
   |  "To + Pending In"       |  yes *     |  "To"                    |
   |  "From"                  |  yes *     |  "None"                  |
   |  "From + Pending Out"    |  yes *     |  "None + Pending Out     |
   |  "Both"                  |  yes *     |  "To"                    |
   +------------------------------------------------------------------+

   * Server SHOULD auto-reply with "unsubscribed" stanza

   When the user's server receives a presence stanza of type
   "subscribed" for the user from the contact, it MUST NOT deliver the
   stanza to the user and MUST NOT change the subscription state if
   there is no pending outbound request for access to the contact's
   presence information.  If there is a pending outbound request for
   access to the contact's presence information and the inbound presence
   stanza of type "subscribed" results in a subscription state change,
   the user's server MUST deliver the stanza to the user and MUST change
   the subscription state.  If the user already has access to the
   contact's presence information, the inbound presence stanza of type
   "subscribed" does not result in a subscription state change;
   therefore the user's server SHOULD NOT deliver the stanza to the user
   and MUST NOT change the subscription state.  These rules are
   summarized in the following table.

   Table 5: Recommended handling of inbound "subscribed" stanzas

   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  no        |  no state change         |
   |  "None + Pending Out"    |  yes       |  "To"                    |
   |  "None + Pending In"     |  no        |  no state change         |
   |  "None + Pending Out/In" |  yes       |  "To + Pending In"       |
   |  "To"                    |  no        |  no state change         |
   |  "To + Pending In"       |  no        |  no state change         |
   |  "From"                  |  no        |  no state change         |
   |  "From + Pending Out"    |  yes       |  "Both"                  |
   |  "Both"                  |  no        |  no state change         |
   +------------------------------------------------------------------+

Top      Up      ToC       Page 61 
   When the user's server receives a presence stanza of type
   "unsubscribed" for the user from the contact, it MUST deliver the
   stanza to the user and MUST change the subscription state if there is
   a pending outbound request for access to the contact's presence
   information or if the user currently has access to the contact's
   presence information.  Otherwise, the user's server SHOULD NOT
   deliver the stanza and MUST NOT change the subscription state.  These
   rules are summarized in the following table.

   Table 6: Recommended handling of inbound "unsubscribed" stanzas

   +------------------------------------------------------------------+
   |  EXISTING STATE          |  DELIVER?  |  NEW STATE               |
   +------------------------------------------------------------------+
   |  "None"                  |  no        |  no state change         |
   |  "None + Pending Out"    |  yes       |  "None"                  |
   |  "None + Pending In"     |  no        |  no state change         |
   |  "None + Pending Out/In" |  yes       |  "None + Pending In"     |
   |  "To"                    |  yes       |  "None"                  |
   |  "To + Pending In"       |  yes       |  "None + Pending In"     |
   |  "From"                  |  no        |  no state change         |
   |  "From + Pending Out"    |  yes       |  "From"                  |
   |  "Both"                  |  yes       |  "From"                  |
   +------------------------------------------------------------------+

9.4.  Server Delivery and Client Acknowledgement of Subscription
      Requests and State Change Notifications

   When a server receives an inbound presence stanza of type "subscribe"
   (i.e., a subscription request) or of type "subscribed",
   "unsubscribe", or "unsubscribed" (i.e., a subscription state change
   notification), in addition to sending the appropriate roster push (or
   updated roster when the roster is next requested by an available
   resource), it MUST deliver the request or notification to the
   intended recipient at least once.  A server MAY require the recipient
   to acknowledge receipt of all state change notifications (and MUST
   require acknowledgement in the case of subscription requests, i.e.,
   presence stanzas of type "subscribe").  In order to require
   acknowledgement, a server SHOULD send the request or notification to
   the recipient each time the recipient logs in, until the recipient
   acknowledges receipt of the notification by "affirming" or "denying"
   the notification, as shown in the following table:

Top      Up      ToC       Page 62 
   Table 7: Acknowledgement of subscription state change notifications

   +--------------------------------------------------+
   |  STANZA TYPE   |  ACCEPT        |  DENY          |
   +--------------------------------------------------+
   |  subscribe     |  subscribed    |  unsubscribed  |
   |  subscribed    |  subscribe     |  unsubscribe   |
   |  unsubscribe   |  unsubscribed  |  subscribed    |
   |  unsubscribed  |  unsubscribe   |  subscribe     |
   +--------------------------------------------------+

   Obviously, given the foregoing subscription state charts, some of the
   acknowledgement stanzas will be routed to the contact and result in
   subscription state changes, while others will not.  However, any such
   stanzas MUST result in the server's no longer sending the
   subscription state notification to the user.

   Because a user's server MUST automatically generate outbound presence
   stanzas of type "unsubscribe" and "unsubscribed" upon receiving a
   roster set with the 'subscription' attribute set to a value of
   "remove" (see Removing a Roster Item and Cancelling All Subscriptions
   (Section 8.6)), the server MUST treat a roster remove request as
   equivalent to sending both of those presence stanzas for purposes of
   determining whether to continue sending subscription state change
   notifications of type "subscribe" or "subscribed" to the user.

10.  Blocking Communication

   Most instant messaging systems have found it necessary to implement
   some method for users to block communications from particular other
   users (this is also required by sections 5.1.5, 5.1.15, 5.3.2, and
   5.4.10 of [IMP-REQS]).  In XMPP this is done by managing one's
   privacy lists using the 'jabber:iq:privacy' namespace.

   Server-side privacy lists enable successful completion of the
   following use cases:

   o  Retrieving one's privacy lists.

   o  Adding, removing, and editing one's privacy lists.

   o  Setting, changing, or declining active lists.

   o  Setting, changing, or declining the default list (i.e., the list
      that is active by default).

   o  Allowing or blocking messages based on JID, group, or subscription
      type (or globally).

Top      Up      ToC       Page 63 
   o  Allowing or blocking inbound presence notifications based on JID,
      group, or subscription type (or globally).

   o  Allowing or blocking outbound presence notifications based on JID,
      group, or subscription type (or globally).

   o  Allowing or blocking IQ stanzas based on JID, group, or
      subscription type (or globally).

   o  Allowing or blocking all communications based on JID, group, or
      subscription type (or globally).

   Note: Presence notifications do not include presence subscriptions,
   only presence information that is broadcasted to entities that are
   subscribed to a user's presence information.  Thus this includes
   presence stanzas with no 'type' attribute or of type='unavailable'
   only.

10.1.  Syntax and Semantics

   A user MAY define one or more privacy lists, which are stored by the
   user's server.  Each <list/> element contains one or more rules in
   the form of <item/> elements, and each <item/> element uses
   attributes to define a privacy rule type, a specific value to which
   the rule applies, the relevant action, and the place of the item in
   the processing order.

   The syntax is as follows:

   <iq>
     <query xmlns='jabber:iq:privacy'>
       <list name='foo'>
         <item
             type='[jid|group|subscription]'
             value='bar'
             action='[allow|deny]'
             order='unsignedInt'>
           [<message/>]
           [<presence-in/>]
           [<presence-out/>]
           [<iq/>]
         </item>
       </list>
     </query>
   </iq>

Top      Up      ToC       Page 64 
   If the type is "jid", then the 'value' attribute MUST contain a valid
   Jabber ID.  JIDs SHOULD be matched in the following order:

   1.  <user@domain/resource> (only that resource matches)

   2.  <user@domain> (any resource matches)

   3.  <domain/resource> (only that resource matches)

   4.  <domain> (the domain itself matches, as does any user@domain,
       domain/resource, or address containing a subdomain)

   If the type is "group", then the 'value' attribute SHOULD contain the
   name of a group in the user's roster.  (If a client attempts to
   update, create, or delete a list item with a group that is not in the
   user's roster, the server SHOULD return to the client an
   <item-not-found/> stanza error.)

   If the type is "subscription", then the 'value' attribute MUST be one
   of "both", "to", "from", or "none" as defined under Roster Syntax and
   Semantics (Section 7.1), where "none" includes entities that are
   totally unknown to the user and therefore not in the user's roster at
   all.

   If no 'type' attribute is included, the rule provides the
   "fall-through" case.

   The 'action' attribute MUST be included and its value MUST be either
   "allow" or "deny".

   The 'order' attribute MUST be included and its value MUST be a
   non-negative integer that is unique among all items in the list.  (If
   a client attempts to create or update a list with non-unique order
   values, the server MUST return to the client a <bad-request/> stanza
   error.)

   The <item/> element MAY contain one or more child elements that
   enable an entity to specify more granular control over which kinds of
   stanzas are to be blocked (i.e., rather than blocking all stanzas).
   The allowable child elements are:

   o  <message/> -- blocks incoming message stanzas
   o  <iq/> -- blocks incoming IQ stanzas
   o  <presence-in/> -- blocks incoming presence notifications
   o  <presence-out/> -- blocks outgoing presence notifications

Top      Up      ToC       Page 65 
   Within the 'jabber:iq:privacy' namespace, the <query/> child of an IQ
   stanza of type "set" MUST NOT include more than one child element
   (i.e., the stanza MUST contain only one <active/> element, one
   <default/> element, or one <list/> element); if a sending entity
   violates this rule, the receiving entity MUST return a <bad-request/>
   stanza error.

   When a client adds or updates a privacy list, the <list/> element
   SHOULD contain at least one <item/> child element; when a client
   removes a privacy list, the <list/> element MUST NOT contain any
   <item/> child elements.

   When a client updates a privacy list, it must include all of the
   desired items (i.e., not a "delta").

10.2.  Business Rules

   1.  If there is an active list set for a session, it affects only the
       session(s) for which it is activated, and only for the duration
       of the session(s); the server MUST apply the active list only and
       MUST NOT apply the default list (i.e., there is no "layering" of
       lists).

   2.  The default list applies to the user as a whole, and is processed
       if there is no active list set for the target session/resource to
       which a stanza is addressed, or if there are no current sessions
       for the user.

   3.  If there is no active list set for a session (or there are no
       current sessions for the user), and there is no default list,
       then all stanzas SHOULD BE accepted or appropriately processed by
       the server on behalf of the user in accordance with the Server
       Rules for Handling XML Stanzas (Section 11).

   4.  Privacy lists MUST be the first delivery rule applied by a
       server, superseding (1) the routing and delivery rules specified
       in Server Rules for Handling XML Stanzas (Section 11), and (2)
       the handling of subscription-related presence stanzas (and
       corresponding generation of roster pushes) specified in
       Integration of Roster Items and Presence Subscriptions (Section
       8).

   5.  The order in which privacy list items are processed by the server
       is important.  List items MUST be processed in ascending order
       determined by the integer values of the 'order' attribute for
       each <item/>.

Top      Up      ToC       Page 66 
   6.  As soon as a stanza is matched against a privacy list rule, the
       server MUST appropriately handle the stanza in accordance with
       the rule and cease processing.

   7.  If no fall-through item is provided in a list, the fall-through
       action is assumed to be "allow".

   8.  If a user updates the definition for an active list, subsequent
       processing based on that active list MUST use the updated
       definition (for all resources to which that active list currently
       applies).

   9.  If a change to the subscription state or roster group of a roster
       item defined in an active or default list occurs during a user's
       session, subsequent processing based on that list MUST take into
       account the changed state or group (for all resources to which
       that list currently applies).

   10. When the definition for a rule is modified, the server MUST send
       an IQ stanza of type "set" to all connected resources, containing
       a <query/> element with only one <list/> child element, where the
       'name' attribute is set to the name of the modified privacy list.
       These "privacy list pushes" adhere to the same semantics as the
       "roster pushes" used in roster management, except that only the
       list name itself (not the full list definition or the "delta") is
       pushed to the connected resources.  It is up to the receiving
       resource to determine whether to retrieve the modified list
       definition, although a connected resource SHOULD do so if the
       list currently applies to it.

   11. When a resource attempts to remove a list or specify a new
       default list while that list applies to a connected resource
       other than the sending resource, the server MUST return a
       <conflict/> error to the sending resource and MUST NOT make the
       requested change.

10.3.  Retrieving One's Privacy Lists

   Example: Client requests names of privacy lists from server:

   <iq from='romeo@example.net/orchard' type='get' id='getlist1'>
     <query xmlns='jabber:iq:privacy'/>
   </iq>

Top      Up      ToC       Page 67 
   Example: Server sends names of privacy lists to client, preceded by
   active list and default list:

   <iq type='result' id='getlist1' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <active name='private'/>
       <default name='public'/>
       <list name='public'/>
       <list name='private'/>
       <list name='special'/>
     </query>
   </iq>

   Example: Client requests a privacy list from server:

   <iq from='romeo@example.net/orchard' type='get' id='getlist2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
     </query>
   </iq>

   Example: Server sends a privacy list to client:

   <iq type='result' id='getlist2' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='1'/>
         <item action='allow' order='2'/>
       </list>
     </query>
   </iq>

   Example: Client requests another privacy list from server:

   <iq from='romeo@example.net/orchard' type='get' id='getlist3'>
     <query xmlns='jabber:iq:privacy'>
       <list name='private'/>
     </query>
   </iq>

Top      Up      ToC       Page 68 
   Example: Server sends another privacy list to client:

   <iq type='result' id='getlist3' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <list name='private'>
         <item type='subscription'
               value='both'
               action='allow'
               order='10'/>
         <item action='deny' order='15'/>
       </list>
     </query>
   </iq>

   Example: Client requests yet another privacy list from server:

   <iq from='romeo@example.net/orchard' type='get' id='getlist4'>
     <query xmlns='jabber:iq:privacy'>
       <list name='special'/>
     </query>
   </iq>

   Example: Server sends yet another privacy list to client:

   <iq type='result' id='getlist4' to='romeo@example.net/orchard'>
     <query xmlns='jabber:iq:privacy'>
       <list name='special'>
         <item type='jid'
               value='juliet@example.com'
               action='allow'
               order='6'/>
         <item type='jid'
               value='benvolio@example.org'
               action='allow'
               order='7'/>
         <item type='jid'
               value='mercutio@example.org'
               action='allow'
               order='42'/>
         <item action='deny' order='666'/>
       </list>
     </query>
   </iq>

   In this example, the user has three lists: (1) 'public', which allows
   communications from everyone except one specific entity (this is the
   default list); (2) 'private', which allows communications only with

Top      Up      ToC       Page 69 
   contacts who have a bidirectional subscription with the user (this is
   the active list); and (3) 'special', which allows communications only
   with three specific entities.

   If the user attempts to retrieve a list but a list by that name does
   not exist, the server MUST return an <item-not-found/> stanza error
   to the user:

   Example: Client attempts to retrieve non-existent list:

   <iq to='romeo@example.net/orchard' type='error' id='getlist5'>
     <query xmlns='jabber:iq:privacy'>
       <list name='The Empty Set'/>
     </query>
     <error type='cancel'>
       <item-not-found
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>

   The user is allowed to retrieve only one list at a time.  If the user
   attempts to retrieve more than one list in the same request, the
   server MUST return a <bad request/> stanza error to the user:

   Example: Client attempts to retrieve more than one list:

   <iq to='romeo@example.net/orchard' type='error' id='getlist6'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
       <list name='private'/>
       <list name='special'/>
     </query>
     <error type='modify'>
       <bad-request
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>

10.4.  Managing Active Lists

   In order to set or change the active list currently being applied by
   the server, the user MUST send an IQ stanza of type "set" with a
   <query/> element qualified by the 'jabber:iq:privacy' namespace that
   contains an empty <active/> child element possessing a 'name'
   attribute whose value is set to the desired list name.

Top      Up      ToC       Page 70 
   Example: Client requests change of active list:

   <iq from='romeo@example.net/orchard' type='set' id='active1'>
     <query xmlns='jabber:iq:privacy'>
       <active name='special'/>
     </query>
   </iq>

   The server MUST activate and apply the requested list before sending
   the result back to the client.

   Example: Server acknowledges success of active list change:

   <iq type='result' id='active1' to='romeo@example.net/orchard'/>

   If the user attempts to set an active list but a list by that name
   does not exist, the server MUST return an <item-not-found/> stanza
   error to the user:

   Example: Client attempts to set a non-existent list as active:

   <iq to='romeo@example.net/orchard' type='error' id='active2'>
     <query xmlns='jabber:iq:privacy'>
       <active name='The Empty Set'/>
     </query>
     <error type='cancel'>
       <item-not-found
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>

   In order to decline the use of any active list, the connected
   resource MUST send an empty <active/> element with no 'name'
   attribute.

   Example: Client declines the use of active lists:

   <iq from='romeo@example.net/orchard' type='set' id='active3'>
     <query xmlns='jabber:iq:privacy'>
       <active/>
     </query>
   </iq>

   Example: Server acknowledges success of declining any active list:

   <iq type='result' id='active3' to='romeo@example.net/orchard'/>

Top      Up      ToC       Page 71 
10.5.  Managing the Default List

   In order to change its default list (which applies to the user as a
   whole, not only the sending resource), the user MUST send an IQ
   stanza of type "set" with a <query/> element qualified by the
   'jabber:iq:privacy' namespace that contains an empty <default/> child
   element possessing a 'name' attribute whose value is set to the
   desired list name.

   Example: User requests change of default list:

   <iq from='romeo@example.net/orchard' type='set' id='default1'>
     <query xmlns='jabber:iq:privacy'>
       <default name='special'/>
     </query>
   </iq>

   Example: Server acknowledges success of default list change:

   <iq type='result' id='default1' to='romeo@example.net/orchard'/>

   If the user attempts to change which list is the default list but the
   default list is in use by at least one connected resource other than
   the sending resource, the server MUST return a <conflict/> stanza
   error to the sending resource:

   Example: Client attempts to change the default list but that list is
   in use by another resource:

   <iq to='romeo@example.net/orchard' type='error' id='default1'>
     <query xmlns='jabber:iq:privacy'>
       <default name='special'/>
     </query>
     <error type='cancel'>
       <conflict
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>

   If the user attempts to set a default list but a list by that name
   does not exist, the server MUST return an <item-not-found/> stanza
   error to the user:

Top      Up      ToC       Page 72 
   Example: Client attempts to set a non-existent list as default:

   <iq to='romeo@example.net/orchard' type='error' id='default1'>
     <query xmlns='jabber:iq:privacy'>
       <default name='The Empty Set'/>
     </query>
     <error type='cancel'>
       <item-not-found
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>

   In order to decline the use of a default list (i.e., to use the
   domain's stanza routing rules at all times), the user MUST send an
   empty <default/> element with no 'name' attribute.

   Example: Client declines the use of the default list:

   <iq from='romeo@example.net/orchard' type='set' id='default2'>
     <query xmlns='jabber:iq:privacy'>
       <default/>
     </query>
   </iq>

   Example: Server acknowledges success of declining any default list:

   <iq type='result' id='default2' to='romeo@example.net/orchard'/>

   If one connected resource attempts to decline the use of a default
   list for the user as a whole but the default list currently applies
   to at least one other connected resource, the server MUST return a
   <conflict/> error to the sending resource:

   Example: Client attempts to decline a default list but that list is
   in use by another resource:

   <iq to='romeo@example.net/orchard' type='error' id='default3'>
     <query xmlns='jabber:iq:privacy'>
       <default/>
     </query>
     <error type='cancel'>
       <conflict
           xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
     </error>
   </iq>

Top      Up      ToC       Page 73 
10.6.  Editing a Privacy List

   In order to edit a privacy list, the user MUST send an IQ stanza of
   type "set" with a <query/> element qualified by the
   'jabber:iq:privacy' namespace that contains one <list/> child element
   possessing a 'name' attribute whose value is set to the list name the
   user would like to edit.  The <list/> element MUST contain one or
   more <item/> elements, which specify the user's desired changes to
   the list by including all elements in the list (not the "delta").

   Example: Client edits a privacy list:

   <iq from='romeo@example.net/orchard' type='set' id='edit1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'>
         <item type='jid'
               value='tybalt@example.com'
               action='deny'
               order='3'/>
         <item type='jid'
               value='paris@example.org'
               action='deny'
               order='5'/>
         <item action='allow' order='68'/>
       </list>
     </query>
   </iq>

   Example: Server acknowledges success of list edit:

   <iq type='result' id='edit1' to='romeo@example.net/orchard'/>

   Note: The value of the 'order' attribute for any given item is not
   fixed.  Thus in the foregoing example if the user would like to add 4
   items between the "tybalt@example.com" item and the
   "paris@example.org" item, the user's client MUST renumber the
   relevant items before submitting the list to the server.

   The server MUST now send a "privacy list push" to all connected
   resources:

   Example: Privacy list push on list edit:

   <iq to='romeo@example.net/orchard' type='set' id='push1'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
     </query>
   </iq>

Top      Up      ToC       Page 74 
   <iq to='romeo@example.net/home' type='set' id='push2'>
     <query xmlns='jabber:iq:privacy'>
       <list name='public'/>
     </query>
   </iq>

   In accordance with the semantics of IQ stanzas defined in
   [XMPP-CORE], each connected resource MUST return an IQ result to the
   server as well:

   Example: Acknowledging receipt of privacy list pushes:

   <iq from='romeo@example.net/orchard'
       type='result'
       id='push1'/>

   <iq from='romeo@example.net/home'
       type='result'
       id='push2'/>

10.7.  Adding a New Privacy List

   The same protocol used to edit an existing list is used to create a
   new list.  If the list name matches that of an existing list, the
   request to add a new list will overwrite the old one.  As with list
   edits, the server MUST also send a "privacy list push" to all
   connected resources.



(page 74 continued on part 4)

Next RFC Part