RFC 8048

Interworking between the Session Initiation Protocol (SIP) and the Extensible Messaging and Presence Protocol (XMPP): Presence

๐Ÿ“… published December 2016, from ietf

Interworking Between SIP and XMPP: Presence ๐Ÿ’–

Okay bestie, this is RFC 8048 ๐ŸŽ€, published by the IETF (Internet Engineering Task Force) in December 2016. It's written by P. Saint-Andre from Filament ๐Ÿฆ‹ and it's a Standards Track doc, so it's the real deal. It has ISSN 2070-1721, and it obsoletes RFC 7248, meaning this one replaces that older version. Its title is "Interworking between the Session Initiation Protocol (SIP) and the Extensible Messaging and Presence Protocol (XMPP): Presence" and it's all about making SIP and XMPP presence systems talk to each other. Iconic ๐Ÿ’…


Abstract โœจ

Okay so the big idea here is a bidirectional protocol mapping ๐Ÿ” that lets presence information flow back and forth between the Session Initiation Protocol (SIP) and the Extensible Messaging and Presence Protocol (XMPP). It also says straight up that this document obsoletes RFC 7248 ๐Ÿ’œ.

Status of This Memo โœจ

This is an Internet Standards Track document. ๐ŸŒธ

It's a product of the Internet Engineering Task Force (IETF), so it reflects the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG) ๐Ÿ‘‘. If you want more on Internet Standards, check Section 2 of RFC 7841.

Info about the current status of this doc, any errata, and how to send feedback lives at http://www.rfc-editor.org/info/rfc8048 ๐Ÿงš

Copyright (c) 2016 IETF Trust and the persons identified as the document authors. All rights reserved. ๐ŸŒˆ

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, which you can find at http://trustee.ietf.org/license-info, as they stand on the publication date. Read these carefully ๐Ÿ™ˆ, because they spell out your rights and restrictions for this document. Any Code Components pulled out of this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as the Simplified BSD License describes.

Table of Contents ๐Ÿ“

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
2.  Intended Audience . . . . . . . . . . . . . . . . . . . . . .   4
3.  Terminology . . . . . . . . . . . . . . . . . . . . . . . . .   5
4.  Architectural Assumptions . . . . . . . . . . . . . . . . . .   5
5.  Presence Authorizations . . . . . . . . . . . . . . . . . . .   6
  5.1.  Overview  . . . . . . . . . . . . . . . . . . . . . . . .   6
  5.2.  XMPP to SIP . . . . . . . . . . . . . . . . . . . . . . .   7
    5.2.1.  Requesting a Presence Authorization . . . . . . . . .   7
    5.2.2.  Refreshing a Notification Dialog  . . . . . . . . . .  11
    5.2.3.  Cancelling a Presence Authorization . . . . . . . . .  11
  5.3.  SIP to XMPP . . . . . . . . . . . . . . . . . . . . . . .  15
    5.3.1.  Requesting a Presence Authorization . . . . . . . . .  15
    5.3.2.  Refreshing a Notification Dialog  . . . . . . . . . .  18
    5.3.3.  Cancelling a Presence Authorization . . . . . . . . .  19
6.  Notifications of Presence Information . . . . . . . . . . . .  19
  6.1.  Overview  . . . . . . . . . . . . . . . . . . . . . . . .  19
  6.2.  XMPP to SIP . . . . . . . . . . . . . . . . . . . . . . .  20
  6.3.  SIP to XMPP . . . . . . . . . . . . . . . . . . . . . . .  25
7.  Polling for Presence Information  . . . . . . . . . . . . . .  27
  7.1.  XMPP to SIP . . . . . . . . . . . . . . . . . . . . . . .  27
  7.2.  SIP to XMPP . . . . . . . . . . . . . . . . . . . . . . .  28
8.  Privacy and Security Considerations . . . . . . . . . . . . .  28
  8.1.  Amplification Attacks . . . . . . . . . . . . . . . . . .  28
  8.2.  Presence Leaks  . . . . . . . . . . . . . . . . . . . . .  29
9.  References  . . . . . . . . . . . . . . . . . . . . . . . . .  30
  9.1.  Normative References  . . . . . . . . . . . . . . . . . .  30
  9.2.  Informative References  . . . . . . . . . . . . . . . . .  31
Appendix A.  Changes from RFC 7248  . . . . . . . . . . . . . . .  33
Acknowledgements  . . . . . . . . . . . . . . . . . . . . . . . .  34
Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .  34

1. Introduction ๐Ÿฆ‹

Okay so presence is basically info about whether an entity is available, like whether you're on the network or free to chat ๐Ÿ’ฌ. Presence features in both SIP and XMPP have a few moving parts:

  • A long-lived authorization for a user to get notifications about a contact's presence across presence and notification sessions. This authorization is formally requested by the user, then approved (or not) by the contact, and it's often tied to a record in an address list or "buddy list" ๐Ÿ“’.
  • An ephemeral presence session, where the contact is online (aka available for interaction) and then goes offline again ๐Ÿ˜ด.
  • An ephemeral notification session, where the user asks the contact for presence notifications. These are implicit in XMPP but explicit in SIP, where they're handled through notification dialogs ๐ŸŽญ.
  • Notifications that get sent from the contact to the user for as long as either the contact's presence session or the user's notification session lasts ๐Ÿ””.

Both specs use the word "subscription", but they mean different things, which is so confusing ๐Ÿ˜ญ. In SIP, a "subscription" is the mechanism where a subscriber (or someone acting for them, like a SIP Presence Server) asks for presence notifications over a relatively short stretch of time. It gets renewed as needed to keep the notifications coming during a presence session. In XMPP, a "subscription" is basically shorthand for a long-lived presence authorization. To avoid mixing these up, this document uses "notification dialog" for a SIP subscription and "presence authorization" for an XMPP subscription ๐Ÿ’….

To help make sure presence systems that follow the instant messaging and presence protocol requirements [RFC2779] can actually interwork, it's important to clearly define protocol mappings between them. Within the IETF, work has gone into two presence technologies ๐ŸŒˆ:

  • Various extensions to the Session Initiation Protocol ([RFC3261]) for presence, in particular [RFC3856]
  • The Extensible Messaging and Presence Protocol (XMPP), which is a formalization of the core XML-streaming protocols originally developed by the Jabber open-source community. The relevant specs are [RFC6120] for the XML-streaming layer and [RFC6121] for basic presence and instant-messaging extensions

One approach to get these protocols interworking is to map each one to the abstract semantics in [RFC3860]. Apparently though, that approach has never been implemented ๐Ÿ™ƒ. This document takes a different route and maps semantics directly from one protocol to the other (so from SIP/SIMPLE (SIP for Instant Messaging and Presence Leveraging Extensions) to XMPP and back again), because that's how existing systems actually solve the interworking problem ๐Ÿ”ฅ.

The architectural assumptions behind these direct mappings are in [RFC7247], including how addresses and error conditions get mapped. The mappings in this document cover basic presence functionality. More advanced stuff, like so-called "rich presence", is out of scope here ๐Ÿ™ˆ.

This document obsoletes RFC 7248. ๐Ÿ’œ

2. Intended Audience ๐ŸŽ€

The documents in this series (which include [RFC7247], [RFC7572], [RFC7573], and [RFC7702]) are for software developers who already have a system built on one of these technologies (e.g., SIP) and want to enable communication from that system to systems built on the other technology (e.g., XMPP) ๐Ÿซถ. We assume readers know the core specs for both SIP [RFC3261] and XMPP [RFC6120], the base document for this series [RFC7247], and these presence-related specs:

  • "A Presence Event Package for the Session Initiation Protocol" [RFC3856]
  • "Presence Information Data Format (PIDF)" [RFC3863]
  • "Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence" [RFC6121]
  • "SIP-Specific Event Notification" [RFC6665]

3. Terminology ๐Ÿงš

A bunch of terms, like "user", "contact", and "notification", are explained in [RFC3261], [RFC3856], [RFC3857], [RFC6120], and [RFC6121]. This document uses some (but not all) of the presence-related terms from the Model for Presence and Instant Messaging [RFC2778]. The term "presence session" is used the way [RFC6121] uses it, meaning a delimited stretch of time when an endpoint is online and available for communications ๐Ÿ’–.

In the flow diagrams, SIP traffic is shown with arrows like ***>, and XMPP traffic is shown with arrows like ...> โœจ. As in [RFC7247], "SIP to XMPP Gateway" and "XMPP to SIP Gateway" get shortened to "S2X GW" and "X2S GW" ๐Ÿ’….

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] ๐Ÿ“œ.

4. Architectural Assumptions ๐ŸŒธ

The fundamental architectural assumptions behind SIP-XMPP interworking are described in [RFC7247] ๐Ÿ›๏ธ.

Note that, in SIP, presence services can be deployed on the server side in two ways ๐Ÿ‘€:

  1. Under this model, described most fully in [RFC3857], a dedicated SIP Presence Server handles events related to the presence event package. Instead of forwarding a SUBSCRIBE message to the SIP user, the Presence Server informs the user of subscription activity using the 'presence.winfo' event package. The SIP User Agent then authorizes the subscribing contact through some interaction with the Presence Server (for instance, using XML Configuration Access Protocol (XCAP) [RFC4825]). So presence updates from the SIP User Agent aren't sent as NOTIFY messages to the XMPP user. Instead, they go as PUBLISH messages to the Presence Server, which then generates NOTIFY messages to all active subscribers ๐Ÿ“ฎ.
  2. Under this model, a SIP Presence Server acts in proxy mode and simply passes the SUBSCRIBE and NOTIFY messages through to the SIP User Agent ๐Ÿ”€.

Because the behavior of the XMPP-to-SIP gateway doesn't change based on which SIP architectural model is used, the diagrams and protocol flows in this document cover both options by labeling the end entity a "SIP User Agent or Presence Server" ๐ŸŽ€.


5. Presence Authorizations ๐Ÿ‘‘

5.1. Overview

okay so bestie, XMPP and presence-aware SIP both let entities (often, but not always, humans ๐Ÿซถ) subscribe to other entities' presence โœจ. XMPP presence is specified in [RFC6121]. Presence using a SIP event package is specified in [RFC3856].

As [RFC6121] explains, XMPP presence authorizations are managed with <presence/> stanzas of type "subscribe", "subscribed", "unsubscribe", and "unsubscribed" ๐Ÿ’Œ. The main states are:

  • "none" (neither the user nor the contact is subscribed to the other's presence information) ๐Ÿฅ€
  • "from" (the contact will receive presence notifications from the user)
  • "to" (the contact will send presence notifications to the user)
  • "both" (both user and contact will receive each other's presence notifications) ๐Ÿ’ž

Now for SIP, which is giving a totally different vibe ๐Ÿ’…. As [RFC3856] describes, the subscriber doesn't explicitly ask for presence authorizations to be created or removed. Instead, subscription activity triggers them. When a SIP user gets an initial SIP SUBSCRIBE event from a contact, the recipient's SIP User Agent or SIP Presence Server asks the user to make an authorization policy decision ๐Ÿค”. That decision gets recorded in the SIP User Agent or SIP Presence Server, so any future notification dialogs from that contact are automatically approved ๐Ÿฆ‹. (Quick aside: SIP and XMPP users and contacts are most generally referenced by a Presence URI like <pres:user@domain>, but they might also show up as a SIP or SIPS (Session Initiation Protocol Secure) URI like <sip:user@domain> or <sips:user@domain>. Since 'pres' URIs are rarely used in practice, the examples in this document use 'sip' URIs ๐ŸŒธ.)

In both SIP and XMPP, presence authorizations are long-lived ๐Ÿ’œ. They're permanent unless someone explicitly cancels them. In SIP, a notification session is usually short-lived by default unless someone explicitly extends it. The default time-to-live of a SIP notification dialog is 3600 seconds, as specified in Section 6.4 of [RFC3856], so the notification dialog has to be explicitly refreshed for the user's notification session to last as long as the contact's presence session โฐ. In XMPP, the user's notification session with a contact is almost always handled automatically by the user's server, based on the user's presence state (see [RFC6121] for details) ๐Ÿงš.

5.2. XMPP to SIP

5.2.1. Requesting a Presence Authorization

Here's the protocol flow diagram ๐Ÿ—บ๏ธ. It shows what needs to happen to set up an authorization so an XMPP user can receive presence notifications from a SIP contact. The text and examples after the diagram walk through it step by step.

XMPP         XMPP         SIP     SIP UA or
Client      Server       Proxy    Presence Server
 |        + X2S GW         |            |
 |            |            |            |
 | (F1) XMPP  |            |            |
 | subscribe  |            |            |
 |...........>|            |            |
 |            | (F2) SIP   |            |
 |            | SUBSCRIBE  |            |
 |            |***********>|            |
 |            |            | (F3) SIP   |
 |            |            | SUBSCRIBE  |
 |            |            |***********>|
 |            |            | (F4) SIP   |
 |            |            | 200 OK     |
 |            |            |<***********|
 |            | (F5) SIP   |            |
 |            | 200 OK     |            |
 |            |<***********|            |
 |            |            | (F6) SIP   |
 |            |            | NOTIFY     |
 |            |            | (pending)  |
 |            |            |<***********|
 |            | (F7) SIP   |            |
 |            | NOTIFY     |            |
 |            |<***********|            |
 |            | (F8) SIP   |            |
 |            | 200 OK     |            |
 |            |***********>|            |
 |            |            | (F9) SIP   |
 |            |            | 200 OK     |
 |            |            |***********>|
 |            |            | (F10) SIP  |
 |            |            | NOTIFY     |
 |            |            | (active)   |
 |            |            |<***********|
 |            | (F11) SIP  |            |
 |            | NOTIFY     |            |
 |            |<***********|            |
 |            | (F12) SIP  |            |
 |            | 200 OK     |            |
 |            |***********>|            |
 |            |            | (F13) SIP  |
 |            |            | 200 OK     |
 |            |            |***********>|
 | (F14) XMPP |            |            |
 | subscribed |            |            |
 |<...........|            |            |
 | (F15) XMPP |            |            |
 | presence   |            |            |
 |<...........|            |            |
 |            |            |            |

So an XMPP user (like juliet@example.com ๐Ÿ’•) asks for a presence authorization by sending a request to a SIP contact (like romeo@example.net), and the contact either accepts or declines. If the SIP contact accepts, the XMPP user keeps a long-lived authorization to receive the SIP contact's presence information until either (1) the XMPP user unsubscribes or (2) the SIP contact cancels the authorization ๐Ÿ”. The request gets wrapped in a <presence/> stanza of type "subscribe":

Example 1: XMPP User Subscribes to SIP Contact (F1)

<presence from='juliet@example.com'
          to='romeo@example.net'
          type='subscribe'/>

When that <presence/> stanza arrives, the XMPP server Juliet connected to needs to figure out what the domainpart in the 'to' address is. It does this by following the procedures explained in Section 5 of [RFC7247] ๐Ÿ”. If the domain is a SIP domain, the XMPP server hands the <presence/> stanza off to an associated XMPP-to-SIP gateway or connection manager, which natively talks to presence-aware SIP proxies ๐Ÿš€.

Next, the XMPP-to-SIP gateway translates the XMPP request into a SIP SUBSCRIBE request, addressed from the XMPP user to the SIP contact:

Example 2: SIP Transformation of XMPP Presence Authorization Request (F2)

SUBSCRIBE sip:romeo@example.net SIP/2.0
Via: SIP/2.0/TCP x2s.example.com;branch=z9hG4bKna998sk
From: <sip:juliet@example.com>;tag=j89d
Call-ID: 5BCF940D-793D-43F8-8972-218F7F4EAA8C
Event: presence
Max-Forwards: 70
CSeq: 1 SUBSCRIBE
Contact: <sip:juliet@example.com>;gr=yn0cl4bnw0yr3vym
Accept: application/pidf+xml
Expires: 3600
Content-Length: 0

Once the SIP proxy has delivered the SIP SUBSCRIBE to the SIP User Agent or Presence Server (that's F3, and no example is shown for it ๐Ÿ™ˆ), the SIP User Agent sends back a response that says yes, accepted โœ…:

Example 3: SIP User Accepts Presence Authorization Request (F4)

SIP/2.0 200 OK
Via: SIP/2.0/TCP s2x.example.net;branch=z9hG4bKna998sk
From: <sip:juliet@example.com>;tag=j89d
To: <sip:romeo@example.net>;tag=ffd2
Call-ID: 5BCF940D-793D-43F8-8972-218F7F4EAA8C
CSeq: 1 SUBSCRIBE
Contact: <sip:romeo@example.net>;gr=dr4hcr0st3lup4c
Expires: 3600
Content-Length: 0

Per Section 6.7 of [RFC3856], the XMPP-to-SIP gateway has to treat the state as "neutral" until it gets a NOTIFY message with a Subscription-State header [RFC6665] whose value is "active" ๐ŸŒˆ. So the SIP User Agent or Presence Server SHOULD immediately send that NOTIFY message (see Section 6 below) ๐Ÿ’จ. If the XMPP-to-SIP gateway first receives one or more NOTIFY messages whose Subscription-State header value is "pending" (F6), then it MUST respond to them on the SIP side, but it should hold back and NOT send any presence stanzas from the SIP contact to the XMPP user ๐Ÿ›‘.

Example 4: SIP User Agent or Presence Server Sends Presence Notification (F10)

NOTIFY sip:juliet@example.com SIP/2.0
Via: SIP/2.0/TCP simple.example.net;branch=z9hG4bKna998sk
From: <sip:juliet@example.com>;tag=j89d
To: <sip:romeo@example.net>;tag=ffd2
Call-ID: 5BCF940D-793D-43F8-8972-218F7F4EAA8C
Event: presence
Subscription-State: active;expires=499
Max-Forwards: 70
CSeq: 2 NOTIFY
Content-Type: application/pidf+xml
Content-Length: 193

<?xml version='1.0' encoding='UTF-8'?>
<presence xmlns='urn:ietf:params:xml:ns:pidf'
          entity='pres:romeo@example.net'>
  <tuple id='ID-dr4hcr0st3lup4c'>
    <status>
      <basic>open</basic>
      <show xmlns='jabber:client'>away</show>
    </status>
  </tuple>
</presence>

When the first NOTIFY with an active state comes in, the XMPP-to-SIP gateway sends a 200 OK back to the SIP User Agent or Presence Server (that's F12, no example ๐ŸŽ€).

The XMPP-to-SIP gateway also generates a <presence/> stanza of type "subscribed" ๐Ÿฅณ:

Example 5: XMPP User Receives Acknowledgement from SIP Contact (F14)

<presence from='romeo@example.net'
          to='juliet@example.com'
          type='subscribed'/>

As Section 6 explains, if this first NOTIFY in the notification session has a body, then the XMPP-to-SIP gateway also generates a presence notification addressed to the XMPP user. (And if the NOTIFY doesn't have a body, the gateway interprets it as "unknown" or "closed" ๐Ÿซฅ.)

Example 6: XMPP User Receives Presence Notification from SIP Contact (F15)

<presence from='romeo@example.net/dr4hcr0st3lup4c'
          to='juliet@example.com'/>

5.2.2. Refreshing a Notification Dialog

The XMPP-to-SIP gateway is responsible for setting the Expires header value and periodically renewing the notification dialog on the SIMPLE side of the gateway ๐Ÿ”„. For example, the XMPP-to-SIP gateway SHOULD send a new SUBSCRIBE request to the SIP contact whenever the XMPP user starts a presence session with the XMPP server by sending initial presence to it (this is functionally the same as sending an XMPP presence probe ๐Ÿ”Ž). The XMPP-to-SIP gateway SHOULD ALSO send a new SUBSCRIBE request to the SIP contact sufficiently before the SIP notification dialog is due to expire, while the XMPP user's presence session is still active โณ.

The rules for SIP SUBSCRIBE requests that establish and refresh a notification dialog are in [RFC6665]. Those rules apply to XMPP-to-SIP gateways too ๐Ÿ’–. Also, an XMPP-to-SIP gateway MUST consider the XMPP presence authorization permanently cancelled (and tell the XMPP user so) if it receives a SIP response of 403, 489, or 603 โŒ. On the other hand, it's fine to treat a SIP response of 423 or 481 as a transient error and honor the long-lived XMPP presence authorization ๐Ÿซถ. [RFC6665] goes into more detailed considerations about handling SIP responses for notification dialogs and refreshes ๐Ÿ“š.

And finally, check out the Privacy and Security Considerations section (Section 8) for important information and requirements about the security implications of notification refreshes ๐Ÿ”๐Ÿšจ.

5.2.3. Cancelling a Presence Authorization ๐Ÿ’…

Okay bestie, this flow is how an XMPP user cancels her outbound presence authorization to a SIP contact ๐Ÿ™…โ€โ™€๏ธ (aka she's done watching that SIP contact's presence, periodt). SIMPLE doesn't have a built-in "cancel my outbound authorization" move ๐Ÿ˜ญ. Lots of SIP/SIMPLE implementations let her use something like XCAP [RFC4825] to remove the contact from her address list, but that's not the flow here. Instead, this just cancels the user's notification dialog, which means on the XMPP side she won't ask for a new one later. More details come after the diagram ๐Ÿฆ‹.

XMPP         XMPP         SIP        SIP UA or
Client      Server       Proxy    Presence Server
 |        + X2S GW         |            |
 |            |            |            |
 | (F16) XMPP |            |            |
 |unsubscribe |            |            |
 |...........>|            |            |
 |            | (F17) SIP  |            |
 |            | SUBSCRIBE  |            |
 |            | Expires: 0 |            |
 |            |***********>|            |
 |            |            | (F18) SIP  |
 |            |            | SUBSCRIBE  |
 |            |            | Expires: 0 |
 |            |            |***********>|
 |            |            | (F19) SIP  |
 |            |            | 200 OK     |
 |            |            |<***********|
 |            | (F20) SIP  |            |
 |            | 200 OK     |            |
 |            |<***********|            |
 | (F21) XMPP |            |            |
 |unsubscribed|            |            |
 |<...........|            |            |
 |            | (F22) SIP  |            |
 |            | NOTIFY     |            |
 |            | terminated |            |
 |            |***********>|            |
 |            |            | (F23) SIP  |
 |            |            | NOTIFY     |
 |            |            | terminated |
 |            |            |***********>|
 |            |            | (F24) SIP  |
 |            |            | 200 OK     |
 |            |            |<***********|
 |            | (F25) SIP  |            |
 |            | 200 OK     |            |
 |            |<***********|            |
 |            |            |            |

At any point after subscribing, the XMPP user can say "I'm out" ๐Ÿ™‹โ€โ™€๏ธ. She does that by sending a <presence/> stanza of type "unsubscribe", and it looks like this:

Example 7: XMPP User Unsubscribes from SIP Contact (F16) โœจ

|  <presence from='juliet@example.com'
|            to='romeo@example.net'
|            type='unsubscribe'/>

The XMPP-to-SIP gateway is responsible for turning that XMPP unsubscribe into a SIP SUBSCRIBE request with the Expires header set to a value of zero ("0") ๐Ÿงš:

Example 8: SIP Transformation of XMPP Unsubscribe (F17) ๐ŸŽ€

|  SUBSCRIBE sip:romeo@example.net SIP/2.0
|  Via: SIP/2.0/TCP s2x.example.net;branch=z9hG4bKna998sk
|  From: <sip:juliet@example.com>;tag=j89d
|  To: <sip:romeo@example.com>;tag=ffd2
|  Call-ID: 5BCF940D-793D-43F8-8972-218F7F4EAA8C
|  Event: presence
|  Max-Forwards: 70
|  CSeq: 42 SUBSCRIBE
|  Contact: <sip:juliet@example.com>;gr=yn0cl4bnw0yr3vym
|  Accept: application/pidf+xml
|  Expires: 0
|  Content-Length: 0

Once the gateway gets the SIP 200 OK that acknowledges the cancellation, it SHOULD send a <presence/> stanza of type "unsubscribed" back to the XMPP user ๐ŸŒธ. This is the confirmation moment, bestie ๐Ÿฅน:

Example 9: XMPP User Receives Unsubscribed Notification (F21) ๐Ÿ’–

|  <presence from='romeo@example.net'
|            to='juliet@example.com'
|            type='unsubscribed'/>

Following Section 4.4.1 of [RFC6665], the XMPP-to-SIP gateway is then responsible for sending a NOTIFY message with a Subscription-State header of "terminated". That formally ends the XMPP user's outbound presence authorization and the SIP dialog tied to it ๐Ÿ”š๐Ÿฆ‹.

Example 10: XMPP-to-SIP Gateway Sends Presence Notification to Terminate Authorization (F25) ๐Ÿ“

|  NOTIFY sip:juliet@example.com SIP/2.0
|  Via: SIP/2.0/TCP simple.example.net;branch=z9hG4bKna998sk
|  From: <sip:juliet@example.com>;tag=j89d
|  To: <sip:romeo@example.net>;tag=ffd2
|  Call-ID: 5BCF940D-793D-43F8-8972-218F7F4EAA8C
|  Event: presence
|  Subscription-State: terminated
|  Max-Forwards: 70
|  CSeq: 43 NOTIFY
|  Content-Length: 0
Note: When the XMPP user cancels her outbound presence authorization to the SIP user, any inbound authorization she approved earlier (the one that lets the SIP user see her presence) stays exactly as it is ๐Ÿซถ. Only the outbound side gets cancelled, not the inbound side!

5.3. SIP to XMPP ๐ŸŒˆ

5.3.1. Requesting a Presence Authorization ๐Ÿ’Œ

Now we flip it! This flow sets up an authorization for a SIP user to receive presence notifications from an XMPP contact ๐Ÿงšโ€โ™€๏ธ. Check the diagram first, then the examples after it:

SIP         SIP         XMPP         XMPP
UA         Proxy       Server        Client
 |       + S2X GW         |           |
 |           |            |           |
 | (F26) SIP |            |           |
 | SUBSCRIBE |            |           |
 |**********>|            |           |
 | (F27) SIP |            |           |
 | 200 OK    |            |           |
 |<**********|            |           |
 |           | (F28) XMPP |           |
 |           | subscribe  |           |
 |           |...........>|           |
 |           |            | (F29) XMPP|
 |           |            | subscribe |
 |           |            |..........>|
 |           |            | (F30) XMPP|
 |           |            | subscribed|
 |           |            |<..........|
 |           | (F31) XMPP |           |
 |           | subscribed |           |
 |           |<...........|           |
 | (F32) SIP |            |           |
 | NOTIFY    |            |           |
 | (active)  |            |           |
 |<**********|            |           |
 | (F33) SIP |            |           |
 | 200 OK    |            |           |
 |**********>|            |           |
 |           |            |           |

A SIP User Agent starts a presence authorization to an XMPP contact's presence info by sending a SIP SUBSCRIBE request to that contact. Here's what that looks like ๐Ÿ“ž:

Example 11: SIP User Subscribes to XMPP Contact (F26) ๐ŸŽ€

|  SUBSCRIBE sip:juliet@example.com SIP/2.0
|  Via: SIP/2.0/TCP s2x.example.net;branch=z9hG4bKna998sk
|  From: <sip:romeo@example.net>;tag=xfg9
|  To: <sip:juliet@example.net>
|  Call-ID: AA5A8BE5-CBB7-42B9-8181-6230012B1E11
|  Event: presence
|  Max-Forwards: 70
|  CSeq: 1 SUBSCRIBE
|  Contact: <sip:romeo@example.net>;gr=dr4hcr0st3lup4c
|  Accept: application/pidf+xml
|  Content-Length: 0

Notice that there's no Expires header in that SUBSCRIBE ๐Ÿ‘€. That means the default value of 3600 applies (3600 seconds, which is 1 hour, lol) โฐ.

When the SUBSCRIBE arrives, the SIP proxy has to figure out the identity of the domain portion of the Request-URI. It does that by following the procedures in Section 5 of [RFC7247] ๐Ÿ”. If the domain is an XMPP domain, the SIP proxy hands the SUBSCRIBE off to an associated SIP-to-XMPP gateway or connection manager that talks XMPP natively ๐Ÿค.

The SIP-to-XMPP gateway is then responsible for translating that SUBSCRIBE into an XMPP authorization request, addressed from the SIP user to the XMPP contact:

Example 12: XMPP Transformation of SIP SUBSCRIBE (F28) ๐Ÿ’…

|  <presence from='romeo@example.net'
|            to='juliet@example.com'
|            type='subscribe'/>

Per [RFC6121], the XMPP user's server delivers the presence authorization request to the XMPP user. Or, if the XMPP user's roster already has an authorization in place, the XMPP server SHOULD auto-reply with a <presence/> stanza of type 'subscribed' ๐Ÿ™Œ.

The "happy path" is when the XMPP user approves the request by generating a <presence/> stanza of type "subscribed" (F30) ๐Ÿฅฐ. The XMPP server then stamps that stanza with the 'from' address of the XMPP contact and sends it to the SIP user (F31). When the SIP-to-XMPP gateway gets that stanza, it generates an empty SIP NOTIFY message with a Subscription-State header [RFC6665] of "active". That tells the SIP user their request was approved (F32) ๐ŸŽ‰.

Example 13: XMPP User Approves Presence Authorization Request (F31) ๐ŸŒธ

|  <presence from='juliet@example.com'
|            to='romeo@example.net'
|            type='subscribed'/>

Example 14: Presence Authorization Request Approved (F32) ๐Ÿ“

|  NOTIFY sip:romeo@example.net SIP/2.0
|  Via: SIP/2.0/TCP s2x.example.net;branch=z9hG4bKna998sk
|  From: <sip:romeo@example.net>;tag=xfg9
|  To: <sip:juliet@example.com>;tag=ur93
|  Call-ID: AA5A8BE5-CBB7-42B9-8181-6230012B1E11
|  Event: presence
|  Subscription-State: active
|  Max-Forwards: 70
|  CSeq: 2 NOTIFY
|  Content-Length: 0

Plot twist ๐Ÿ™€: the XMPP user can totally decline instead, by generating a <presence/> stanza of type "unsubscribed". The XMPP server stamps it with the contact's 'from' address and sends it to the SIP user. The SIP-to-XMPP gateway then turns that stanza into an empty SIP NOTIFY with a Subscription-State header [RFC6665] of "terminated" and a reason of "rejected" ๐Ÿšซ.

Example 15: XMPP User Rejects Presence Authorization Request ๐Ÿ’€

|  <presence from='juliet@example.com'
|            to='romeo@example.net'
|            type='unsubscribed'/>

Example 16: Presence Authorization Request Rejected ๐Ÿ™ˆ

|  NOTIFY sip:romeo@example.net SIP/2.0
|  Via: SIP/2.0/TCP s2x.example.net;branch=z9hG4bKna998sk
|  From: <sip:romeo@example.net>;tag=xfg9
|  To: <sip:juliet@example.com>;tag=ur93
|  Call-ID: AA5A8BE5-CBB7-42B9-8181-6230012B1E11
|  Event: presence
|  Subscription-State: terminated;reason=rejected
|  Max-Forwards: 70
|  CSeq: 2 NOTIFY
|  Content-Length: 0

5.3.2. Refreshing a Notification Dialog ๐Ÿ”„

As long as the SIP user is online and wants to keep their notification session going (aka keep receiving presence notifications from the XMPP contact), their SIP User Agent is responsible for periodically refreshing the notification dialog. It does this by sending an updated SUBSCRIBE request with a suitable value for the Expires header ๐Ÿ’–. In response, the presence-aware SIP-to-XMPP gateway sends a SIP NOTIFY message to the SIP User Agent (per [RFC6665]) ๐Ÿ“จ.

Here's the tea โ˜•: if the gateway has meaningful info about the XMPP user's availability (say, from the core presence session on the XMPP server, or from a presence probe as described under Section 7), then the NOTIFY shares that info, such as with a PIDF body [RFC3863] holding the relevant data ๐Ÿงพ. But if the gateway doesn't have meaningful availability info, then the NOTIFY MUST be empty, as allowed by [RFC6665] ๐Ÿซง.

5.3.3. Cancelling a Presence Authorization โœจ

okay so SIP doesn't have a built-in "bye, I'm out" button for cancelling an outbound presence authorization ๐Ÿฅบ instead, the SIP user ends their outbound notification dialog by sending a SUBSCRIBE with Expires set to zero ("0") and then just never renewing it ๐Ÿ’…

SUBSCRIBE sip:juliet@example.com SIP/2.0
Via: SIP/2.0/TCP simple.example.net;branch=z9hG4bKna998sk
From: <sip:romeo@example.net>;tag=xfg9
To: <sip:juliet@example.com>;tag=ur93
Call-ID: AA5A8BE5-CBB7-42B9-8181-6230012B1E11
Event: presence
Max-Forwards: 70
CSeq: 66 SUBSCRIBE
Contact: <sip:romeo@example.net>;gr=dr4hcr0st3lup4c
Expires: 0
Content-Length: 0

Once that lands, the presence-aware SIP-to-XMPP gateway has two jobs to handle ๐Ÿงš

  1. Sending a SIP NOTIFY request to the SIP User Agent containing a PIDF document saying the XMPP contact now has a basic status of "closed", including a Subscription-State header [RFC6665] of terminated with a reason of timeout ๐Ÿ™ˆ
  2. Sending an XMPP <presence/> stanza of type "unavailable" to the XMPP contact ๐ŸŒธ
Note: When the SIP user cancels his outbound presence authorization to the XMPP user, any inbound authorization that he might have approved (enabling the XMPP user to see his presence) remains unchanged. ๐Ÿซถ

6. Notifications of Presence Information ๐Ÿฆ‹

6.1. Overview

Okay so both XMPP and presence-aware SIP systems let entities (often, but not necessarily, human users) send presence notifications to other entities ๐Ÿ’– At its most basic, "presence" is just info about an entity's "on/off" availability for communication on a network. Usually that gets a glow-up with extra context about the entity's status while it's available, and these availability states commonly include "away" and "do not disturb" โœจ Some systems and protocols go even further and call any relatively ephemeral info about an entity a kind of presence ๐ŸŒˆ Categories of this "extended presence" include geographical location (e.g., GPS coordinates), user mood (e.g., grumpy), user activity (e.g., walking), and ambient environment (e.g., noisy). This document focuses on the "least common denominator" of network availability only ๐ŸŽ€ Future documents might address broader notions of presence, including availability states and extended presence or so-called "rich presence" as defined in specifications such as [RFC4480], [XEP-0107], and [XEP-0108] ๐Ÿงš

The XMPP instant messaging and presence specification [RFC6121] defines how XMPP <presence/> stanzas can indicate availability (via the absence of a type attribute) or lack of availability (via a type attribute with a value of "unavailable") ๐Ÿ’… SIP presence using a SIP event package for presence is specified in [RFC3856] ๐Ÿซถ

As described in [RFC6121], XMPP presence information about an entity is communicated by means of an XML <presence/> stanza sent over an XML stream ๐Ÿ˜ญ This document assumes that such a <presence/> stanza is sent from an XMPP client to an XMPP server over an XML stream negotiated between the client and the server, and that the client is controlled by a human user. In general, XMPP presence is sent by the user's client to the user's server and then broadcast to all entities who are subscribed to the user's presence information ๐Ÿ”ฅ

As described in [RFC3856], presence information about an entity is communicated by means of a SIP NOTIFY event sent from a SIP User Agent to an intended recipient who is most generally referenced by a Presence URI of the form <pres:user@domain>, but who might be referenced by a SIP or SIPS URI of the form <sip:user@domain> or <sips:user@domain> ๐Ÿ‘‘

6.2. XMPP to SIP โœจ

okay so when Juliet messes with her XMPP client to change her presence (or her client just does it automatically, like with an "auto-away" feature ๐Ÿ’ค), her client whips up an XMPP <presence/> stanza ๐Ÿ’… The syntax for that stanza, including what's required and what's optional, lives in [RFC6121]. Here's one:

Example 18: XMPP User Sends Presence Notification

<presence from='juliet@example.com/yn0cl4bnw0yr3vym'/>

Once the XMPP server Juliet connected to gets it, it blasts the stanza out to everyone who's allowed to get Juliet's presence and who's currently interested in hearing about it (kinda like a SIP NOTIFY ๐Ÿฆ‹). For each subscriber, the server adds the subscriber's 'to' address. Then it either delivers the notification locally (if the hostname in that address is one the server serves) or tries to route it to the foreign domain that handles that hostname. If the notification is headed to an address at a foreign domain, the server has to figure out the domainpart in the 'to' address, and it does that by following the procedures in [RFC7247]. If that domain is a SIP domain, the server hands the <presence/> stanza off to an associated XMPP-to-SIP gateway or connection manager that natively talks to a presence-aware SIP proxy ๐ŸŽ€

The XMPP-to-SIP gateway then takes over and translates the XMPP <presence/> stanza into a SIP NOTIFY request (including the PIDF document) from the XMPP user to the SIP contact ๐ŸŒธ

Example 19: SIP Transformation of XMPP Presence Notification

NOTIFY sip:juliet@example.com SIP/2.0
Via: SIP/2.0/TCP x2s.example.com;branch=z9hG4bKna998sk
From: <sip:juliet@example.com>;tag=gh19
To: <sip:romeo@example.net>
Contact: <sip:juliet@example.com>;gr=yn0cl4bnw0yr3vym
Call-ID: 2B44E147-3B53-45E4-9D48-C051F3216D14
Event: presence
Subscription-State: active;expires=599
Max-Forwards: 70
CSeq: 2 NOTIFY
Content-Type: application/pidf+xml
Content-Length: 192

<?xml version='1.0' encoding='UTF-8'?>
<presence xmlns='urn:ietf:params:xml:ns:pidf'
          entity='pres:juliet@example.com'>
  <tuple id='ID-yn0cl4bnw0yr3vym'>
    <status>
      <basic>open</basic>
      <show xmlns='jabber:client'>away</show>
    </status>
  </tuple>
</presence>

The mapping of XMPP syntax elements to SIP syntax elements MUST be as shown in the following table. (Mappings for elements not mentioned are undefined and therefore are a matter of implementation.) ๐Ÿงš

+-----------------------------+---------------------------+
|  XMPP Element or Attribute  |  SIP Header or PIDF Data  |
+-----------------------------+---------------------------+
|  <presence/> stanza         |  "Event: presence" (1)    |
+-----------------------------+---------------------------+
|  XMPP resource identifier   |  tuple 'id' attribute (2) |
+-----------------------------+---------------------------+
|  from                       |  From                     |
+-----------------------------+---------------------------+
|  id                         |  no mapping (3)           |
+-----------------------------+---------------------------+
|  to                         |  To                       |
+-----------------------------+---------------------------+
|  type                       |  basic status (4) (5)     |
+-----------------------------+---------------------------+
|  xml:lang                   |  Content-Language         |
+-----------------------------+---------------------------+
|  <priority/>                |  priority for tuple (6)   |
+-----------------------------+---------------------------+
|  <show/>                    |  no mapping (7)           |
+-----------------------------+---------------------------+
|  <status/>                  |  <note/>                  |
+-----------------------------+---------------------------+

Table 1: Presence Syntax Mapping from XMPP to SIP

Note the following regarding these mappings:

  1. Only an XMPP <presence/> stanza that lacks a 'type' attribute, or whose 'type' attribute has a value of "unavailable", gets mapped by an XMPP-to-SIP gateway to a SIP NOTIFY request. Those are the only <presence/> stanzas that represent notifications, so that's the only thing that gets the glow-up ๐Ÿ’–
  2. The PIDF schema defines the tuple 'id' attribute as having a datatype of "xs:ID". That datatype is more restrictive than the "xs:string" datatype for XMPP resourceparts (in particular, a number is not allowed as the first character of an ID), so it is RECOMMENDED to prepend the resourcepart with "ID-" or some other alphabetic string when mapping from XMPP to SIP ๐Ÿ”ฅ
  3. In practice, XMPP <presence/> stanzas often do not include the 'id' attribute ๐Ÿ™ˆ
  4. Because the lack of a 'type' attribute indicates that an XMPP entity is available for communication, the XMPP-to-SIP gateway MUST map that information to a PIDF basic status of "open". Because a 'type' attribute with a value of "unavailable" indicates that an XMPP entity is not available for communication, the XMPP-to-SIP gateway MUST map that information to a PIDF <basic/> status of "closed". No vibes lost in translation ๐Ÿ‘‘
  5. When the XMPP-to-SIP gateway receives an XMPP presence of type "unavailable" from the XMPP contact, it sends a SIP NOTIFY request from the XMPP contact to the SIP User Agent. That request contains a PIDF document specifying that the XMPP contact now has a basic status of "closed" ๐ŸŒ™
  6. The value of the XMPP <priority/> element is an integer between -128 and +127. The value of the PIDF <contact/> element's 'priority' attribute, on the other hand, is a decimal number from zero to one inclusive, with a maximum of three decimal places. If the value of the XMPP <priority/> element is negative, an XMPP-to-SIP gateway MUST NOT map the value. If an XMPP-to-SIP gateway maps positive values, it SHOULD treat XMPP priority 0 as PIDF priority 0 and XMPP priority 127 as PIDF priority 1, mapping intermediate values appropriately so that they are unique (e.g., XMPP priority 1 to PIDF priority 0.007, XMPP priority 2 to PIDF priority 0.015, and so on up through mapping XMPP priority 126 to PIDF priority 0.992; note that this is an example only and that the exact mapping is up to the implementation) ๐Ÿ“Š
  7. Some implementations support custom extensions to encapsulate detailed information about availability. There's no need to standardize a PIDF extension for this, because PIDF is already extensible, so the XMPP <show/> element (qualified by the 'jabber:client' namespace) can be included directly in the PIDF XML. The examples in this document illustrate this usage, which is RECOMMENDED. The most useful values are likely "away" and "dnd" (both defined in [RFC6121]). Just note that in XMPP, a value of "dnd" (short for "do not disturb") merely means "busy" and does not imply that a server or client ought to block incoming traffic while the user is in that state ๐Ÿฅบ Naturally, an XMPP-to-SIP gateway can choose to translate a custom extension into an established value of the XMPP <show/> element (as defined in [RFC6121]), or translate a <show/> element into a custom extension that the gateway knows is supported by the SIP User Agent of the intended recipient. Unfortunately, this behavior does not guarantee that information will not be lost. To help prevent information loss, an XMPP-to-SIP gateway ought to include both the <show/> element and the custom extension if it cannot suitably translate the custom value into a <show/> value. Even so, there is no guarantee that the SIP receiver will render a standard XMPP <show/> value or custom extension ๐Ÿ˜ญ

In XMPP, a user can connect with multiple clients at the same time [RFC6120]. For presence notification purposes [RFC6121], each client is associated with a distinct resourcepart [RFC7622], and a contact's SIP User Agent will receive a separate presence notification from each of the XMPP user's clients. Multiple devices, multiple vibes ๐ŸŒˆ Although the interpretation of multiple presence notifications from a single user is a matter of implementation by the contact's SIP User Agent, typically the SIP User Agent will show the "most available" status for the contact. For example, if the user is online with three devices, one of which is "away", one of which is in "do not disturb" mode, and one of which is "available" with no qualifications, then the status shown will simply be "available" โœจ In SIP, it is reasonable for a SIP User Agent to model multiple presence notifications from an XMPP user in the same way that it would handle multiple tuples from a SIP user ๐Ÿ’œ

6.3. SIP to XMPP ๐Ÿฆ‹

okay so when Romeo changes his presence, his SIP User Agent sends a SIP NOTIFY request to every contact that has presence authorizations and notification sessions ๐Ÿ’Œ The NOTIFY syntax is defined in [RFC3856]. Here's what that looks like:

Example 20: SIP User Sends Presence Notification

NOTIFY sip:romeo@example.net SIP/2.0
Via: SIP/2.0/TCP simple.example.net;branch=z9hG4bKna998sk
From: <sip:romeo@example.net>;tag=yt66
To: <sip:juliet@example.com>;tag=bi54
Contact: <sip:romeo@example.net>;gr=dr4hcr0st3lup4c
Call-ID: C33C6C9D-0F4A-42F9-B95C-7CE86B526B5B
Event: presence
Subscription-State: active;expires=499
Max-Forwards: 70
CSeq: 8 NOTIFY
Content-Type: application/pidf+xml
Content-Length: 193

<?xml version='1.0' encoding='UTF-8'?>
<presence xmlns='urn:ietf:params:xml:ns:pidf'
          entity='pres:romeo@example.net'>
  <tuple id='ID-dr4hcr0st3lup4c'>
    <status>
      <basic>closed</basic>
    </status>
  </tuple>
</presence>

When the NOTIFY hits the SIP proxy, it needs to figure out the identity of the domain portion of the Request-URI ๐Ÿง It does that by following the procedures in [RFC7247]. If the domain is an XMPP domain, the proxy hands the NOTIFY off to an associated SIP-to-XMPP gateway or connection manager that natively talks to XMPP servers โœจ

The SIP-to-XMPP gateway then handles the translation, turning the NOTIFY into an XMPP <presence/> stanza that goes from the SIP user to the XMPP contact ๐Ÿ’…

Example 21: XMPP Transformation of SIP Presence Notification

<presence from='romeo@example.net'
          to='juliet@example.com/yn0cl4bnw0yr3vym'
          type='unavailable'/>

The mapping of SIP syntax elements to XMPP syntax elements MUST be as shown in the following table ๐Ÿ“‹ Anything not mentioned in the table is undefined, so it's up to the implementation ๐Ÿคทโ€โ™€๏ธ

Table 2: Presence Syntax Mapping from SIP to XMPP

+---------------------------+-----------------------------+
|  SIP Header or PIDF Data  |  XMPP Element or Attribute  |
+---------------------------+-----------------------------+
|  basic status             |  type (1)                   |
+---------------------------+-----------------------------+
|  Content-Language         |  xml:lang                   |
+---------------------------+-----------------------------+
|  From                     |  from                       |
+---------------------------+-----------------------------+
|  priority for tuple       |  <priority/> (2)            |
+---------------------------+-----------------------------+
|  To                       |  to                         |
+---------------------------+-----------------------------+
|  <note/>                  |  <status/>                  |
+---------------------------+-----------------------------+
|  <show/>                  |  <show/> (3)                |
+---------------------------+-----------------------------+

A few notes to keep in mind about these mappings ๐Ÿ‘€

  1. A PIDF basic status of "open" MUST be mapped to a <presence/> stanza with no 'type' attribute, and a PIDF basic status of "closed" MUST be mapped to a <presence/> stanza whose 'type' attribute has a value of "unavailable" ๐Ÿซถ
  2. See the notes following Table 1 of this document regarding mapping of presence priority ๐Ÿ’œ
  3. If a SIP implementation supports the XMPP <show/> element (qualified by the 'jabber:client' namespace) as a PIDF extension for availability status, as described in the notes following Table 1 of this document, the SIP-to-XMPP gateway is responsible for including that element in the XMPP presence notification ๐ŸŒˆ

7. Polling for Presence Information ๐Ÿงš

Both SIP and XMPP have ways to explicitly ask for one-time info about another entity's current presence status ๐Ÿ” These are "polling" methods, which is different from the publish-subscribe methods covered in the rest of this document ๐ŸŒธ

7.1. XMPP to SIP ๐ŸŽ€

In XMPP, you ask for current presence status by sending a <presence/> stanza of type "probe" ๐Ÿ’–

Example 22: XMPP Server Sends Presence Probe on Behalf of XMPP User

<presence from='juliet@example.com/chamber'
          to='romeo@example.net'
          type='probe'/>

Note: As described in [RFC6121], XMPP servers use presence probes to request presence on behalf of XMPP users. XMPP clients are discouraged from sending presence probes, because retrieving presence is a service that XMPP servers provide automatically ๐Ÿ™ˆ

A SIP-to-XMPP gateway would transform the presence probe into its SIP equivalent, which is a SUBSCRIBE request with an Expires header value of zero ("0") in a new dialog ๐Ÿฆ‹

Example 23: SIP Transformation of XMPP Presence Probe

SUBSCRIBE sip:romeo@example.net SIP/2.0
Via: SIP/2.0/TCP x2s.example.com;branch=z9hG4bKna998sk
From: <sip:juliet@example.com>;tag=j89d
Call-ID: 2398B737-566F-4CBB-A21A-1F8EEF7AF423
Event: presence
Max-Forwards: 70
CSeq: 1 SUBSCRIBE
Contact: <sip:juliet@example.com>;gr=yn0cl4bnw0yr3vym
Accept: application/pidf+xml
Expires: 0
Content-Length: 0

As described in [RFC3856], this causes a NOTIFY to be sent to the subscriber, just like a presence probe does. The transformation rules for presence notifications were already covered in Section 6.2 of this document ๐Ÿง 

7.2. SIP to XMPP ๐ŸŒท

In SIP, you effectively ask for current presence status by sending a SUBSCRIBE with an Expires header value of zero ("0") ๐Ÿ’…

Example 24: SIP User Sends Presence Request

SUBSCRIBE sip:juliet@example.com SIP/2.0
Via: SIP/2.0/TCP simple.example.net;branch=z9hG4bKna998sk
From: <sip:romeo@example.net>;tag=yt66
Call-ID: 717B1B84-F080-4F12-9F44-0EC1ADE767B9
Event: presence
Max-Forwards: 70
CSeq: 1 SUBSCRIBE
Contact: <sip:romeo@example.net>;gr=dr4hcr0st3lup4c
Expires: 0
Content-Length: 0

A presence-aware SIP-to-XMPP gateway translates that SIP request into a <presence/> stanza of type "probe" if it doesn't already have presence information about the contact โœจ

Example 25: XMPP Transformation of SIP Presence Request

<presence from='romeo@example.net'
          to='juliet@example.com'
          type='probe'/>

8. Privacy and Security Considerations ๐Ÿ”

Detailed privacy and security considerations are covered for presence protocols in [RFC2779], for SIP-based presence in [RFC3856] (see also [RFC3261]), and for XMPP-based presence in [RFC6121] (see also [RFC6120]) ๐Ÿซง

8.1. Amplification Attacks ๐Ÿšจ

This one is seriously important, bestie ๐Ÿ˜ญ

There's a real possibility of an amplification attack launched from the XMPP network against a SIP Presence Server ๐Ÿ’€ Why? Because each long-lived XMPP presence authorization would typically cause multiple notification dialog refreshes on the SIP side of an XMPP-to-SIP gateway. So access to an XMPP-to-SIP gateway SHOULD be restricted in a few ways, for example:

  • Only an XMPP service that carefully controls account provisioning, and that provides effective methods for administrators to control the behavior of registered users, ought to host an XMPP-to-SIP gateway (e.g., not a service that offers open account registration) ๐Ÿ”’
  • An XMPP-to-SIP gateway ought to be associated with only a single domain or trust realm. For example, an XMPP-to-SIP gateway hosted at simple.example.com ought to allow only users within the example.com domain to access it, not users within example.org, example.net, or any other domain (unless they're part of the same multi-tenanted environment as example.com). This helps prevent the gateway equivalent of open relays that are shared across XMPP domains from different trust realms ๐Ÿงฑ

If a SIP Presence Server receives communications through an XMPP-to-SIP gateway from users who aren't associated with a domain that is so related to the hostname of the gateway, it SHOULD (based on local service provisioning) refuse to service those users or refuse to receive traffic from the gateway ๐Ÿ™…โ€โ™€๏ธ As an extra check, whenever an XMPP-to-SIP gateway wants to refresh an XMPP user's long-lived authorization to a SIP user's presence, it first sends an XMPP <presence/> stanza of type "probe" from the gateway's address to the "bare Jabber Identifier (JID)" (user@domain.tld) of the XMPP user. The user's XMPP server then responds in accordance with [RFC6121]. This puts an equal burden on the XMPP server and the SIP proxy โš–๏ธ

8.2. Presence Leaks ๐Ÿซฃ

Presence notifications can contain sensitive information (e.g., about network availability) ๐ŸŒซ๏ธ Also, both SIP and XMPP let an entity send different presence notifications to different subscribers. So a gateway MUST NOT route or deliver a presence notification to any entity other than the intended recipient (as represented by the 'to' address for XMPP and by the Request-URI for SIP) ๐Ÿ›‘ That's because the gateway doesn't have information about whether an entity is authorized to receive presence notifications for such recipients. That information lives at the user's home service, not at the receiving gateway ๐Ÿ 


9. References ๐Ÿ“š

9.1. Normative References


9.2. Informative References


Appendix A. Changes from RFC 7248 ๐ŸŽ€

okay so RFC 7248 was already published ๐Ÿ’… when the STOX working group realized that a related doc (now [RFC7702]) had problems that ALSO applied to RFC 7248. ๐Ÿ˜ญ the diagrams and protocol flows in RFC 7248 had errors. They showed an incorrect architecture with gateways on both sides of the exchange. In theory and in practice, presence traffic from an XMPP system gets translated by an XMPP-to-SIMPLE gateway on the XMPP side, and then a normal SIP/SIMPLE system receives it directly, with no receiving gateway on the SIP/SIMPLE side. Traffic from a SIP system goes through a SIMPLE-to-XMPP gateway on the SIP side, and a normal XMPP system receives it directly, with no receiving gateway on the XMPP side. the vibe was off, bestie ๐Ÿ™ˆ

So this document makes the following substantive changes from RFC 7248:

  • Corrects the architectural assumptions, diagrams, and protocol flows so there's a single-gateway model in each direction โœจ
  • Swaps the term "SIP Server" for "SIP Proxy" or "SIP Presence Server" (whichever fits). It also uses "notification dialog" for a SIP subscription and "presence authorization" for an XMPP subscription, instead of the generic word "subscription" in both places. ๐Ÿฆ‹
  • Clarifies that SIP notification dialogs are used to handle presence authorizations in SIP. There's no dedicated way to signal outbound cancellation of an authorization like there is in XMPP, so it's a whole different vibe ๐Ÿ’€
  • Clarifies the use of the 'presence.winfo' event package, the SIP Subscription-State headers (specifically with the values "pending", "active", "closed", or "terminated"), and SIP NOTIFY messages with no body. ๐Ÿงš
  • Clarifies the durations of notification dialogs and presence authorizations, and how they get extended in SIP and handled in XMPP. โณ
  • Removes the mapping of the XMPP 'id' attribute to the SIP "CSeq" header. Not it ๐Ÿ™…โ€โ™€๏ธ
  • Describes the handling of multiple connected resources in XMPP. ๐Ÿ’œ
  • Provides information about mitigations for leaks of presence information. ๐Ÿซถ

Acknowledgements ๐ŸŒธ

Thanks to the authors, contributors, and other individuals acknowledged in RFC 7248. the whole squad ๐Ÿซถ

Thanks to Saul Ibarra Corretge and Markus Isomaki for their reviews during working group consideration. ๐Ÿ”ฅ

Special thanks to Ben Campbell for identifying the underlying discrepancy that resulted in the need to obsolete RFC 7248. literally iconic behavior ๐Ÿ‘‘

Thanks also to Markus Isomaki and Yana Stamcheva as the working group chairs, and to Alissa Cooper as the sponsoring Area Director. ๐Ÿ’–


Author's Address ๐Ÿฆ‹

Peter Saint-Andre Filament

Email: peter@filament.com URI: https://filament.com/

๐Ÿ“ฆ where this page comes from