RFC 5839

An Extension to Session Initiation Protocol (SIP) Events for Conditional Event Notification

πŸ“… published May 2010, from ietf

RFC 5839: The Deets ✨

okay so this is An Extension to Session Initiation Protocol (SIP) Events for Conditional Event Notification πŸŽ€, RFC 5839, and it's giving practical efficiency energy πŸ’…

  • Authors: A. Niemi (Nokia) and D. Willis, Ed. (Softarmor Systems) 🫢
  • Category: Standards Track πŸ‘‘
  • ISSN: 2070-1721 🌸
  • Date: May 2010 πŸ“
  • Obsoletes / Updates: this title block doesn't list any RFCs it obsoletes or updates πŸ™ˆ

Abstract

okay so the SIP events framework lets you get async notifications about all kinds of events from other SIP user agents, and it's lowkey iconic ✨ It covers creating, refreshing, and terminating subscriptions, plus fetching and periodic polling of resource state πŸ’–

BUT here's the tea πŸ«–: none of those procedures give you a way to stop replaying event notifications your user agent already received. 😭

So this memo adds an extension that lets the subscriber put a condition on its subscription request, basically asking "has the state changed since the last notification I got?" 🧚 When that condition is true, the body of the resulting event notification gets suppressed, or the whole notification message does. Main character energy for efficiency πŸ’…πŸ”₯

Status of This Memo

This is an Internet Standards Track document. πŸ‘‘

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 5741. 🌈

Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc5839. πŸ¦‹

Copyright (c) 2010 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 (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License. πŸ’œ

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English. πŸ“œ

Table of Contents

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  4
  1.1.  Document Conventions . . . . . . . . . . . . . . . . . . .  5
  1.2.  Terminology  . . . . . . . . . . . . . . . . . . . . . . .  5
2.  Motivations and Background . . . . . . . . . . . . . . . . . .  5
  2.1.  Overview . . . . . . . . . . . . . . . . . . . . . . . . .  5
  2.2.  Problem Description  . . . . . . . . . . . . . . . . . . .  5
  2.3.  Requirements . . . . . . . . . . . . . . . . . . . . . . .  6
3.  Overview of Operation  . . . . . . . . . . . . . . . . . . . .  7
4.  Resource Model for Entity-Tags . . . . . . . . . . . . . . . . 10
5.  Subscriber Behavior  . . . . . . . . . . . . . . . . . . . . . 12
  5.1.  Detecting Support for Conditional Notification . . . . . . 13
  5.2.  Generating SUBSCRIBE Requests  . . . . . . . . . . . . . . 13
  5.3.  Receiving NOTIFY Requests  . . . . . . . . . . . . . . . . 14
  5.4.  Polling or Fetching Resource State . . . . . . . . . . . . 15
  5.5.  Resuming a Subscription  . . . . . . . . . . . . . . . . . 17
  5.6.  Refreshing a Subscription  . . . . . . . . . . . . . . . . 18
  5.7.  Terminating a Subscription . . . . . . . . . . . . . . . . 18
  5.8.  Handling Transient Errors  . . . . . . . . . . . . . . . . 19
6.  Notifier Behavior  . . . . . . . . . . . . . . . . . . . . . . 20
  6.1.  Generating Entity-tags . . . . . . . . . . . . . . . . . . 20
  6.2.  Suppressing NOTIFY Bodies  . . . . . . . . . . . . . . . . 20
  6.3.  Suppressing NOTIFY Requests  . . . . . . . . . . . . . . . 21
  6.4.  State Differentials  . . . . . . . . . . . . . . . . . . . 21
  6.5.  List Subscriptions . . . . . . . . . . . . . . . . . . . . 22
7.  Protocol Element Definitions . . . . . . . . . . . . . . . . . 22
  7.1.  204 (No Notification) Response Code  . . . . . . . . . . . 22
  7.2.  Suppress-If-Match Header Field . . . . . . . . . . . . . . 22
  7.3.  Grammar  . . . . . . . . . . . . . . . . . . . . . . . . . 22
8.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 23
  8.1.  204 (No Notification) Response Code  . . . . . . . . . . . 23
  8.2.  Suppress-If-Match Header Field . . . . . . . . . . . . . . 23
9.  Security Considerations  . . . . . . . . . . . . . . . . . . . 24
10. Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 24
11. References . . . . . . . . . . . . . . . . . . . . . . . . . . 24
  11.1. Normative References . . . . . . . . . . . . . . . . . . . 24
  11.2. Informative References . . . . . . . . . . . . . . . . . . 24

1. Introduction 🌸

okay so the SIP events framework gives you an extensible facility for requesting notification of certain events from other SIP user agents. πŸ¦‹ It includes procedures for creating, refreshing, and terminating subscriptions, plus the option to fetch or periodically poll the event resource. ✨

Several instantiations of this framework, called event packages, have been defined. Examples are presence [RFC3856], message waiting indications [RFC3842], and registrations [RFC3680]. πŸ’–

By default, every SUBSCRIBE request generates a NOTIFY request containing the latest event state. 🧚 Typically, the subscriber issues a SUBSCRIBE request whenever it needs a subscription to be installed, periodically refreshed, or terminated. Once the subscription is installed, most of the NOTIFYs generated by subscription refreshes are superfluous πŸ’€, because the subscriber usually already has the event state, except in the unlikely case where a state change exactly coincides with the periodic subscription refresh. In most cases, the final event state generated when terminating the subscription also contains resource state the subscriber already has. πŸ™„

Fetching or polling resource state is similarly suboptimal in cases where the state hasn't changed since the previous poll. In general, the problem is the inability to persist state across a SUBSCRIBE request. 😭

This memo defines an extension to optimize the SIP events framework. πŸ”₯ It lets a notifier tag notifications (called entity-tags hereafter), and lets the subscriber condition its later SUBSCRIBE requests on actual changes since a notification carrying that entity-tag was issued. The solution is similar to the conditional requests defined in the Hypertext Transfer Protocol (HTTP) [RFC2616], and it follows the mechanism already defined for the PUBLISH [RFC3903] method for issuing conditional event publications. πŸ‘‘

Here's how the memo is structured πŸ—ΊοΈ: Section 2 explains the background, motivations, and requirements. Section 3 gives a general overview of the mechanism. Section 4 explains the underlying model for resources and entities as they apply to conditional notification. Section 5 defines the subscriber behavior. Section 6 defines the notifier behavior. Section 7 includes the protocol element definitions. Section 8 includes the IANA considerations, and Section 9 includes the security considerations. πŸ’…

1.1. Document Conventions πŸŽ€

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14, RFC 2119 [RFC2119] and indicate requirement levels for compliant implementations. 🫢

1.2. Terminology πŸ“š

okay so in addition to the terminology introduced in [RFC3261], [RFC3265], and [RFC3903], this spec uses these extra terms to describe the objects of conditional notification πŸ¦‹

resource An object identified by a URI whose resource state can be accessed using the SIP Event Notification framework. There is a single authoritative notifier responsible for communicating the resource state. ✨

entity The representation of resource state. An entity consists of the state data carried in the body of a NOTIFY message, as well as related meta-data in the message header. There may be many versions of an entity, one current and the others stale. Each version of an entity is identified by an entity-tag, which is guaranteed to be unique across all versions of all entities for a resource and event package. πŸ’œ

2. Motivations and Background 🌈

2.1. Overview 🧚

A SUBSCRIBE request creates a subscription with a finite lifetime. ⏳ That lifetime is negotiated using the Expires header field. Unless the subscriber refreshes the subscription before the expiration is met, the subscription is terminated. The frequency of these refreshes depends on the event package, and typically ranges from minutes to hours. πŸ“

2.2. Problem Description πŸ’…

okay so the SIP events framework has a lowkey big gap πŸ₯Ί it doesn't have separate protocol methods for starting and ending subscriptions, refreshing them, or fetching state, whether that's inside or outside the SIP dialog. so SUBSCRIBE is doing everything 😭 it's giving overloaded. the only thing that makes a fetch different from a subscription that actually lasts is the Expires header value on the SUBSCRIBE. a zero-expiry SUBSCRIBE only gets you a single NOTIFY, and then the subscription immediately terminates πŸ’€ lasting subscriptions usually have pretty short expiry periods, so you keep sending fresh SUBSCRIBE requests to refresh them. periodt.

every new SUBSCRIBE sends a NOTIFY with the latest resource state, and that happens even when nothing has changed. so every poll or refresh resends the same info again πŸ™„ this is literally the same problem that HTTP [RFC2616] has with repeated GET operations on a resource. HTTP fixes it with conditional requests 🧚 the server gives each entity an entity-tag that identifies one specific instance of it. clients making GET requests can then include the entity-tag for the version they think is current in an If-None-Match header field. the server compares that entity-tag to the entity it believes is current, and if the server believes the client's version matches, it skips resending the entity in the response. in other words, the server doesn't resend stuff the client already has. iconic behaviour πŸ‘‘

the SIP PUBLISH [RFC3903] method uses a similar mechanism 🫢 refreshing a publication is done by referencing its assigned entity-tag, instead of retransmitting the event state every time the publication expiration gets extended ✨

2.3. Requirements πŸŽ€

okay here's the summary of the functionality we need to fix these issues:

  • REQ1: it must be possible to suppress the NOTIFY request (or at a minimum, the event body therein) if the subscriber is already in possession of (or has previously received and discarded) the latest event state of the resource.
  • REQ2: this mechanism must apply to initial subscriptions in which the subscriber is attempting to resume an earlier subscription that has been paused.
  • REQ3: this mechanism must apply to refreshing a subscription.
  • REQ4: this mechanism must apply to terminating a subscription (i.e., an unsubscribe).
  • REQ5: this mechanism must apply to fetching or polling of resource state.

3. Overview of Operation πŸ¦‹

whenever a subscriber starts a subscription, it sends a SUBSCRIBE request. that SUBSCRIBE gets sent, routed, and processed by the notifier totally normally, meaning it follows the Session Initiation Protocol [RFC3261] and SIP-Specific Event Notification [RFC3265] ✨

if the notifier that receives the SUBSCRIBE supports conditional subscriptions, it generates an entity-tag for the current entity and puts it in a SIP-ETag header field of the NOTIFY request 🌸 the entity-tag is unique across all versions of all entities for a resource and event package. see Section 4 for more on this.

entity-tags are independent of subscriptions πŸ’œ this means notifications sent for a fetch or a poll can have valid entity-tags even across later fetches or polls.

the subscriber stores the entity-tag it got in the notification along with the resource state. later, it can use that entity-tag to make a SUBSCRIBE that includes a condition in the form of a Suppress-If-Match header field. this is different from the If-Match condition in a PUBLISH [RFC3903] request, which decides whether the PUBLISH succeeds or returns an error. this condition applies to the stream of notifications that get sent after the SUBSCRIBE has been processed πŸ”₯

the Suppress-If-Match header field contains the last entity-tag the subscriber saw. if this condition is true, it tells the notifier to suppress either the body of a later notification or the entire notification πŸ™ˆ

the condition gets evaluated by matching the value of the header field against the entity-tag of the entity that would normally be sent in the associated NOTIFY message. there's also a wildcard entity-tag with the special value * that always matches πŸ¦‹

   Subscriber                               Notifier
   ----------                               --------

   (1) SUBSCRIBE       -------->
       Expires: 3600
                       <--------       (2) 200 (or 202)

                       <--------       (3) NOTIFY
                                           Subscription-State: active
                                           SIP-ETag: ffee2
   (4) 200             -------->

        ... time passes ...

   (5) SUBSCRIBE       -------->                \ if "ffee2"
       Suppress-If-Match: ffee2                 |   matches
       Expires: 3600                            |   local
                                                |   entity-tag
                                                |
                       <--------       (6) 204  / then

      ... time passes and resource state (entity) changes...


                       <--------       (7) NOTIFY
                                           Subscription-State: active
                                           SIP-ETag: ca89a
   (8) 200             -------->


      ... time passes ...


   (9) SUBSCRIBE       -------->                \ if "ca89"
       Suppress-If-Match: ca89a                 |   matches
       Expires: 0                               |   local
                                                |   entity-tag
                                                |
                       <--------      (10) 204  / then

                   Figure 1: Example Message Flow

Figure 1 shows a typical message flow for conditional notification, so let's walk through it 🧚

(1) the subscriber starts a subscription by sending a SUBSCRIBE request for a resource.

(2) after proper authentication and authorization, the notifier accepts the subscription.

(3) the notifier then immediately sends the initial event notification, including a unique entity-tag in a SIP-ETag header field.

(4) the subscriber accepts the notification and stores the entity-tag value along with the resource state.

(5) later, the subscriber refreshes the subscription and includes an entity-tag in a Suppress-If-Match header field.

(6) the notifier evaluates the condition by matching its local entity-tag value for the resource against the value of the Suppress-If-Match header field. if the condition evaluates to true, the notifier tells the subscriber that the notification will not be sent.

(7) at some point, the state of the resource changes, e.g., a user's presence status changes from online to busy. this triggers an event notification with a new value in the SIP-ETag header field.

(8) the subscriber accepts the notification and stores the new entity-tag along with the resource state.

(9) after a while, the subscriber decides to end the subscription. it adds a condition for Suppress-If-Match and includes the entity-tag it got in the previous NOTIFY.

(10) the notifier evaluates the condition by matching its entity-tag for the resource against the value of the Suppress-If-Match header field. if the condition evaluates to true, the notifier tells the subscriber that no notification will be sent. this wraps up the subscription πŸ’…

the benefit of conditional notification in this example is fewer NOTIFY requests for the subscriber to receive πŸ“ every event notification the subscriber has already seen gets suppressed by the notifier. this example only shows one use case for the mechanism, but the same principles can be used to optimize the flow of messages for other event notification use cases ✨

4. Resource Model for Entity-Tags ✨

okay bestie, the key to understanding how conditional notification works is understanding the resource model underneath event notification 🧠. it's kinda like HTTP's resource model but with some key differences πŸ’…. this section breaks it down for SIP events, and Figure 2 has the whole vibe:

                     +-----+
     ............    |     |
     .          .    | URI |
     . Represen .    |     |
     . tation   .    +-----+
     .          .       |*
     ............       |
          .             |
          .             V
          .        +----------+            +---------+
       composition |          |*           |  Event  |
          +------<>| Resource |----------->| Package |<----.
          |        |          |            |         |     |
          |        +----------+            +----.----+     |
          |                                    /_\         |
          |*                                    | classification
      +--------+                                |          |
      |        |        .----------------.------'          |
      | Entity |        |                |                 |
      |        |        |                |                 |*
      +--------+   +----------+    +------------+     +----------+
          ^        |          |    |            |     |          |
          |        | Presence |    | Conference |     | Template |
          |        |          |    |            |     |          |
          |1..*    +----------+    +------------+     +----.-----+
     +---------+                                          /_\
     |         |                                           |
     | Version |                                           |
     |         |                                      +---------+
     +---------+                                      | Watcher |
          |1                                          |  Info   |
          |                                           |         |
          V                                           +---------+
     +---------+
     | Entity- |
     |   Tag   |
     |         |
     +---------+

                     Figure 2: Resource Model Diagram

For a given event package, there is a single authoritative agent in charge of zero or more resources πŸ‘‘. Even for a distributed agent, the resource state is uniform across all instances 🫢. The resource itself can be a list of resources [RFC4662]. Conditional notification for list subscriptions is covered in Section 6.5 πŸ¦‹.

A resource is identified by zero or more URIs, which can be SIP URIs, pres URIs [RFC3859], or similar. Subscribers use this URI to subscribe to the resource for certain types of events, identified by the event package πŸ’–.

With a successful subscription, a subscriber gets event notifications that communicate the resource state and the changes to it πŸ“¬. Each event notification carries a representation of the current resource state. This representation is influenced by lots of things, e.g., authorization and filtering rules, and the event composition rules of the notifier ✨.

This representation is realized in an "entity" πŸŽ€. Each resource may be associated with zero or more entities. For example, there may be multiple subscribers to the presence info of a single user (a resource), and each subscriber may have a different filtered view of that resource, producing one entity per subscriber. However, each entity is associated with one and only one resource. There is no "compositing" of resources at the entity level πŸ™…β€β™€οΈ. Resources may themselves be made up of information from other resources (be "composite resources"), but this does not change the one-resource-per-entity rule.

An entity is the data carried in the body of a NOTIFY message plus the related meta-data in the message header 🌸. Whenever the data in the body or any of the meta-data changes, the notifier MUST produce a new entity-tag. This meta-data MUST include, but is not limited to, the following SIP header fields defined in the Session Initiation Protocol [RFC3261] and SIP Specific Event Notification [RFC3265]:

  1. Content-Disposition
  2. Content-Encoding
  3. Content-Language
  4. Content-Length
  5. Content-Type
  6. Event

Note that Subscription-State is explicitly NOT part of the entity πŸ™ˆ. In the future, event packages may define additional fields that implementations need to consider as part of the entity.

An entity has one or more versions, of which only one is current and all others are stale πŸ“. Each version has an entity-tag, which uniquely identifies it across all versions of all entities pertaining to a single resource and event package.

Two entity-tags for different resources being equal does NOT mean the entities are identical πŸ‘€. In other words, if an entity-tag received for a subscription to a first resource matches an entity-tag received for a subscription to a second resource, the subscriber cannot assume the two entity values are equal.

With partial event notification, the NOTIFY message only carries the delta state, or the set of changes to the previous version of the entity. In that case, implementations MUST consider the full event state as the version of the entity to which the entity-tag in the NOTIFY message applies 🧩.

The conditional notification mechanism is independent of the way subscriptions get installed πŸ¦‹. In other words, the mechanism supports implicit subscriptions, such as those associated with the REFER method [RFC3515].

It's possible that the same resource is accessible through another mechanism too, in some shape or form, e.g., HTTP or the SIP PUBLISH method 🌈. In general, implementations MUST NOT expect the entity-tags to be shared between the mechanisms, unless event packages or specific applications of SIP events explicitly define such dependencies.

5. Subscriber Behavior πŸ’œ

this section augments the subscriber behavior defined in RFC 3265 [RFC3265]. It first discusses general issues related to indicating support for the mechanism (Section 5.1) and creating conditions in SUBSCRIBE requests (Section 5.2). Next, it describes subscriber behavior for receiving NOTIFY requests (Section 5.3), and specific client workflows for polling resource state (Section 5.4), resuming a subscription (Section 5.5), refreshing a subscription (Section 5.6), and terminating a subscription (Section 5.7). Finally, handling of transient errors is discussed (Section 5.8) 🫢.

5.1. Detecting Support for Conditional Notification

The mechanism defined in this memo is backwards compatible with SIP events [RFC3265] in that a notifier supporting this mechanism will insert a SIP entity-tag in its NOTIFY requests, and a subscriber that understands this mechanism will know how to use it in creating a conditional request πŸ”₯.

Unaware subscribers will simply ignore the entity-tag, make requests without conditions, and receive the default treatment from the notifier 🌷. Unaware notifiers will simply ignore the conditional header fields and continue normal operation.

5.2. Generating SUBSCRIBE Requests

When creating a conditional SUBSCRIBE request, the subscriber MUST include a single conditional header field including an entity-tag in the request πŸ“. The condition is evaluated by comparing the entity-tag of the subscribed resource with the entity-tag carried in the conditional header field. If they match, the condition evaluates to true.

Unlike the condition introduced for the SIP PUBLISH [RFC3903] method, these conditions do NOT apply to the SUBSCRIBE request itself, but to the resulting NOTIFY requests πŸ™…β€β™€οΈ. When true, the condition drives the notifier to change its behavior with regard to sending the notifications after the SUBSCRIBE.

This specification defines a new header field called Suppress-If-Match πŸŽ€. This header field introduces a condition to the SUBSCRIBE request. If true, it instructs the notifier either to omit the body of the resulting NOTIFY message (if the SUBSCRIBE is not sent within an existing dialog) or to suppress (i.e., block) the NOTIFY request that would otherwise be triggered by the SUBSCRIBE (for an established dialog). In the latter case, the SUBSCRIBE message will be answered with a 204 (No Notification) response. As long as the condition remains true, it also instructs the notifier either to suppress any subsequent NOTIFY request or, if there are reportable changes in the NOTIFY header, e.g., the Subscription-State has changed, to suppress the body of any subsequent NOTIFY request 🀯.

If the condition is false, the notifier follows its default behavior πŸƒ.

If the subscriber receives a 204 (No Notification) response to an in-dialog SUBSCRIBE, the subscriber MUST consider the event state and the subscription state unchanged πŸ›‘.

The value of the Suppress-If-Match header field is an entity-tag, which is an opaque token that the subscriber simply copies (byte-wise) from a previously received NOTIFY request 🧾. Inclusion of an entity-tag in a Suppress-If-Match header field of a SUBSCRIBE request indicates that the client has a copy of, or is capable of recreating a copy of, the entity associated with that entity-tag.

Example:

Suppress-If-Match: b4cf7

The header field can also be wildcarded using the special "*" entity-tag value ⭐. Such a condition always evaluates to true, regardless of the value of the current entity-tag for the resource.

Example:

Suppress-If-Match: *

Such a wildcard condition effectively quenches a subscription πŸŒ™. The only notifications received are those reporting changes to the subscription state and those in response to a SUBSCRIBE message sent outside of an existing dialog. In both cases, the notifications will not contain a body.

A subscription with a wildcard Suppress-If-Match condition is useful in scenarios where the subscriber wants to temporarily put a subscription in dormant mode 😴. For example, a host may want to conserve bandwidth and power when it detects from screen or input device inactivity that the user isn't actively monitoring the presence statuses of contacts πŸ”‹.

5.3. Receiving NOTIFY Requests πŸ“¬

okay so when a subscriber gets a NOTIFY request with a SIP-ETag header field, it MUST store the entity-tag if it wants to use the conditional notification mechanism πŸ’…. And it MUST be ready for literally any entity-tag value to show up, even one that matches a value it has already seen 🫢.

The subscriber MUST NOT infer any meaning from the value of an entity-tag πŸ™ˆ. Specifically, it MUST NOT assume identical entities (aka identical event state) for NOTIFYs with identical entity-tag values when those NOTIFYs come from subscribing to different resources πŸ’€. This is the big trap, bestie!

Note that there are valid cases for which identical entity-tag values on different resources may occur. For example, it is possible to generate entity-tag values using a one-way hash function, which means two different resources having the same entity-value could also end up with the same entity-tag. Clients however MUST NOT assume that this is the case, because the algorithm for generating entity-tags is notifier-dependent and not negotiated with the subscriber. So the subscriber can't tell apart two entity-tags with the same value because they're similar hashes of identical entities, or because two notifiers happened to use the same sequential number as an entity-tag 🧚. Entity tags are only required to be unique for a given resource, not globally unique 🌸.

5.4. Polling or Fetching Resource State πŸ”

Polling with conditional notification lets a user agent efficiently poll resource state ✨. This works using the Suppress-If-Match condition, like this:

   Subscriber                               Notifier
   ----------                               --------

  (1) SUBSCRIBE       -------->
      Expires: 0
                      <--------       (2) 202

                      <--------       (3) NOTIFY
                                          Subscription-State: terminated
                                          SIP-ETag: f2e45
                                          Content-Length: 17539

  (4) 200             -------->


  ... poll interval elapses ...


  (5) SUBSCRIBE       -------->
      Suppress-If-Match: f2e45
      Expires: 0
                      <--------       (6) 202

                      <--------       (7) NOTIFY
                                          Subscription-State: terminated
                                          SIP-ETag: f2e45
                                          Content-Length: 0

  (8) 200             -------->

                     Figure 3: Polling Resource State
  1. The subscriber polls for resource state by sending a SUBSCRIBE with zero expiry, so it expires immediately πŸƒβ€β™€οΈ.
  2. The notifier accepts the SUBSCRIBE with a 202 (Accepted) response.
  3. The notifier then immediately sends a first (and last) NOTIFY request with the current resource state and the current entity-tag in the SIP-ETag header field πŸ“¦.
  4. The subscriber accepts the notification with a 200 (OK) response.
  5. After some arbitrary poll interval, the subscriber sends another SUBSCRIBE with a Suppress-If-Match header field that includes the entity-tag from the previous NOTIFY πŸ”.
  6. The notifier accepts the SUBSCRIBE with a 202 (Accepted) response. (202 is used to show the subscription request was understood without also showing that it was authorized, as per Section 3.1.6.1 of SIP-Specific Event Notification [RFC3265].)
  7. Since the resource state hasn't changed since the last poll, the notifier sends a NOTIFY with no body πŸ«™. It also mirrors the current entity-tag of the resource in the SIP-ETag header field.
  8. The subscriber accepts the notification with a 200 (OK) response πŸ’–.

5.5. Resuming a Subscription πŸ”

Resuming a subscription means picking up an earlier subscription that either closed abruptly or was explicitly terminated 🧩. When you resume, the subscription gets set up without sending the resource state again. This is done with conditional notification and the Suppress-If-Match header field:

       Subscriber                               Notifier
       ----------                               --------

   (1) SUBSCRIBE       -------->
       Suppress-If-Match: ega23
       Expires: 3600
                       <--------       (2) 202

                       <--------       (3) NOTIFY
                                           Subscription-State: active
                                           SIP-ETag: ega23
                                           Content-Length: 0
   (4) 200             -------->

                  Figure 4: Resuming a Subscription
  1. The subscriber tries to resume an earlier subscription by including a Suppress-If-Match header field with the entity-tag it last received 🫢.
  2. The notifier accepts the subscription after proper authentication and authorization, by sending a 202 (Accepted) response.
  3. Since the condition is true, the notifier immediately sends an initial NOTIFY request with no body. It also mirrors the current entity-tag of the resource in the SIP-ETag header field πŸŽ€.
  4. The subscriber accepts the NOTIFY and sends a 200 (OK) response.

Had the entity-tag not been valid any longer, the condition would have evaluated to false, and the NOTIFY would have had a body with the latest resource state 🌈.

5.6. Refreshing a Subscription πŸ”„

To refresh a subscription using conditional notification, the subscriber creates a subscription refresh before the subscription expires, and uses the Suppress-If-Match header field:

       Subscriber                               Notifier
       ----------                               --------

       (1) SUBSCRIBE       -------->
           Suppress-If-Match: aba91
           Expires: 3600

                           <--------       (2) 204
                                               Expires: 3600

                 Figure 5: Refreshing a Subscription
  1. Before the subscription expires, the subscriber sends a SUBSCRIBE request that includes the Suppress-If-Match header field with the latest entity-tag it has seen ⏰.
  2. If the condition evaluates to true, the notifier sends a 204 (No Notification) response and sends no NOTIFY request. The Expires header field of the 204 (No Notification) response shows the new expiry time πŸ¦‹.

5.7. Terminating a Subscription πŸ›‘

To terminate a subscription using conditional notification, the subscriber creates a SUBSCRIBE request with a Suppress-If-Match condition:

       Subscriber                               Notifier
       ----------                               --------

       (1) SUBSCRIBE       -------->
           Suppress-If-Match: ega23
           Expires: 0

                           <--------       (2) 204

                Figure 6: Terminating a Subscription
  1. The subscriber decides to end the subscription and sends a SUBSCRIBE request with the Suppress-If-Match condition, using the entity-tag it last saw πŸ‘‹.
  2. If the condition evaluates to true, the notifier sends a 204 (No Notification) response, which wraps up the subscription, and the subscriber can clear all state related to the subscription 🧹.

5.8. Handling Transient Errors 🩹

This section is non-normative.

In some deployments, there may be Back-to-Back User Agent (B2BUA) devices that track SIP dialogs, like subscription dialogs πŸ•΅οΈβ€β™€οΈ. These devices may not know about the conditional notification mechanism.

It's possible that some B2BUA devices treat a NOTIFY with a suppressed body as an error, or expect every SUBSCRIBE message to have an associated NOTIFY message 😭.

Honestly, there's very little an endpoint can do to recover from transient errors like these πŸ’€. The most it can do is try to detect them and define a fallback behavior.

If subscribers run into transient errors in conditional notification, they should disable the feature and fall back to normal subscription behavior 🫠.

6. Notifier Behavior πŸ‘‘

This section augments the notifier behavior as specified in RFC 3265 [RFC3265].

6.1. Generating Entity-tags 🏷️

An entity-tag is a token carried in the SIP-ETag header field, and it's opaque to the client πŸ”. The notifier is free to pick any means for generating the entity-tag. It can have any value, except for "*". For example, one option is to make the entity-tag a simple counter, incrementing it by one for each generated notification per resource πŸ”’.

A notifier MUST generate entity-tags for event notifications of all resources it's responsible for πŸ’…. The entity-tag MUST be unique across all versions of all entities for each state of a resource, as reported by a given event package. Otherwise said, for any subscription or sequence of subscriptions to a specific resource using a singular event package, each entity-tag produced MUST map to one and only one presentation of resource state (entity). Two identical entities for a specific resource might or might not have identical entity-tags; the notifier gets to decide that πŸ¦‹.

An entity-tag is considered valid for as long as the entity exists. An entity becomes stale when its version is no longer the current one πŸ•°οΈ. The notifier MUST remember (or be able to recalculate) the entity-tag of an entity as long as the version of the entity is current. The notifier MAY remember the entity-tag longer than this, e.g., for implementing journaled state differentials (Section 6.4) πŸ““.

The entity-tag values used in publications aren't necessarily shared with the entity-tag values used in subscriptions πŸ™ƒ. That's because there may not always be a one-to-one mapping between a publication and a notification of state change. There may be several sources to the event composition process, and a publication into a resource may not affect the resulting entity 🧩.

6.2. Suppressing NOTIFY Bodies 🀐

When a condition in a SUBSCRIBE request for suppressing notifications is true (i.e., the local entity-tag for the resource state and the entity-tag in a Suppress-If-Match header field are byte-wise identical) but there are reportable changes in the NOTIFY header (e.g., the Subscription-State has changed), the notifier MUST suppress the body of the NOTIFY request πŸ™Š. That means the resulting NOTIFY contains no Content-Type header field, the Content-Length is set to zero, and no payload is attached to the message.

Additionally, when a condition in a SUBSCRIBE request for suppressing notifications is true and the SUBSCRIBE message isn't sent within an established dialog, the notifier MUST send a NOTIFY request with a suppressed entity body πŸ’Œ.

Suppressing the entity body of a NOTIFY doesn't change the current entity-tag of the resource. So the NOTIFY MUST contain a SIP-ETag header field that contains the unchanged entity-tag of the resource state 🫢.

A Suppress-If-Match header field that includes an entity-tag with the value of "*" MUST always evaluate to true πŸ’―.

6.3. Suppressing NOTIFY Requests ✨

Okay bestie, this is the suppression move πŸ”‡πŸ’… When a condition in a SUBSCRIBE asking to suppress notifications is true (aka the resource's local entity-tag and the entity-tag in a Suppress-If-Match header field match), AND the SUBSCRIBE was sent within an established dialog, the notifier MUST suppress the resulting NOTIFY and generate a 204 (No Notification) response. πŸ™ˆ As long as that condition stays true and there are no reportable changes in the NOTIFY header, every later NOTIFY MUST also be suppressed. Iconic πŸ‘‘

Notifiers MUST NOT suppress a NOTIFY unless the SUBSCRIBE that asked for it was sent in an established dialog. No shortcuts, periodt πŸ’…

A successful conditional SUBSCRIBE MUST extend the subscription expiry time. ⏳✨

Suppressing the entire NOTIFY has no effect on the entity-tag of the resource. It stays exactly the same, unchanged πŸ¦‹

A Suppress-If-Match header field that includes an entity-tag with the value of "*" MUST always evaluate to true. That's the wildcard, and it's always a yes πŸ’–

6.4. State Differentials 🌈

Some event packages support a scheme where notifications carry state differentials (aka state deltas) [RFC3265] instead of the complete resource state. 🧚

Further extensions could let notifiers keep track of a resource's state changes, like storing them in a journal πŸ““ If a condition fails, the notifier would then send a state differential in the NOTIFY instead of the full state of the event resource. This only works if both the event package and the subscriber support a payload format with that capability, so it's not a free-for-all πŸ’…

When state differentials are sent, the SIP-ETag header field MUST contain an entity-tag that corresponds to the full resource state. Even when only the diff travels, the tag still points at the whole thing 🫢

6.5. List Subscriptions πŸŽ€

The Event Notification Extension for Resource Lists [RFC4662] defines a way to subscribe to a homogeneous list of resources using the SIP events framework. Lists, but make it iconic πŸ“‹βœ¨

A list subscription delivers event notifications that contain both Resource List Meta-Information (RLMI) documents AND the resource state of the individual resources on the list. Double the content, double the vibes πŸ”₯

Implementations MUST consider the full resource state of a resource list, including the RLMI and the entity-header, as the entity that the entity-tag applies to. The whole bundle counts as one thing πŸ«ΆπŸ’œ

7. Protocol Element Definitions πŸ’–

This section describes the protocol extensions required for conditional notification. Here's the new stuff you need to know πŸ‘€

7.1. 204 (No Notification) Response Code πŸ”‡

The 204 (No Notification) response code means the request was successful, but the notification tied to that request won't be sent. It's only valid in response to a SUBSCRIBE sent within an established dialog, so don't try it anywhere else πŸ™…β€β™€οΈ

The response code is added to the "Success" production rule in the SIP [RFC3261] message grammar. ✨

7.2. Suppress-If-Match Header Field πŸ¦‹

The Suppress-If-Match header field gets added to the definition of the "message-header" rule in the SIP [RFC3261] grammar. Its use is described in Sections 5, 6.3, and 6.2. Go check those πŸ“–

This header field is allowed to show up in any request, but its behavior is only defined for the SUBSCRIBE request. Only SUBSCRIBE gets the full experience πŸ’…

7.3. Grammar πŸ“œ

This section defines the formal syntax for the extensions in this memo, written in Augmented BNF (ABNF) [RFC5234]. The rules defined here augment and reference the syntax defined in RFC 3261 [RFC3261] and RFC 3903 [RFC3903]. Grammar is a lot, but it's giving precision πŸ€“

Success            =/ "204"  ;  No Notification

      ; Success is defined in RFC 3261.

message-header     =/ Suppress-If-Match

      ; message-header is defined in RFC 3261.

Suppress-If-Match  =  "Suppress-If-Match" HCOLON ( entity-tag / "*" )

      ; entity-tag is defined in RFC 3903.

8. IANA Considerations 🌸

This document registers a new response code and a new header field name. Two new things for the registries, let's gooo πŸŽ‰

8.1. 204 (No Notification) Response Code πŸ”‡

This document registers a new response code. It's defined by the following information, which has been added to the methods and response-codes sub-registry available from http://www.iana.org.

This information has been added under the "Successful 2xx" category. πŸ“

                 +---------------------+-----------+
                 | Response Code       | Reference |
                 +---------------------+-----------+
                 | 204 No Notification | [RFC5839] |
                 +---------------------+-----------+

8.2. Suppress-If-Match Header Field πŸ¦‹

This document registers a new SIP header field called Suppress-If-Match. It's defined by the following information, which has been added to the header fields sub-registry available from http://www.iana.org.

             +-------------------+---------+-----------+
             | Header Name       | Compact | Reference |
             +-------------------+---------+-----------+
             | Suppress-If-Match |         | [RFC5839] |
             +-------------------+---------+-----------+

9. Security Considerations πŸ”

The security considerations for SIP event notification are extensively discussed in RFC 3265 [RFC3265]. Go read that one, it's a whole saga πŸ“š

This specification introduces an optimization to SIP event notification. That optimization, on its own, does not alter the security properties of the protocol. Still, optimizations are where sneaky stuff hides, so keep your eyes open πŸ‘€πŸ’€

10. Acknowledgments 🫢

The following people contributed corrections and suggestions to this document: Adam Roach, Sean Olson, Johnny Vrancken, Pekka Pessi, Eva Leppanen, Krisztian Kiss, Peili Xu, Avshalom Houri, David Viamonte, Jonathan Rosenberg, Qian Sun, Dale Worley, Tolga Asveren, Brian Stucker, Eric Rescorla, Arun Arunachalam, and the SIP and SIMPLE working groups. Thank you, besties πŸ’œπŸ‘‘

11. References πŸ“š

11.1. Normative References

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC3261]  Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston,
           A., Peterson, J., Sparks, R., Handley, M., and E.
           Schooler, "SIP: Session Initiation Protocol", RFC 3261,
           June 2002.

[RFC3265]  Roach, A., "Session Initiation Protocol (SIP)-Specific
           Event Notification", RFC 3265, June 2002.

[RFC3903]  Niemi, A., "Session Initiation Protocol (SIP) Extension
           for Event State Publication", RFC 3903, October 2004.

[RFC5234]  Crocker, D. and P. Overell, "Augmented BNF for Syntax
           Specifications: ABNF", STD 68, RFC 5234, January 2008.

11.2. Informative References

[RFC2616]  Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
           Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
           Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.

[RFC3515]  Sparks, R., "The Session Initiation Protocol (SIP) Refer
           Method", RFC 3515, April 2003.

[RFC3680]  Rosenberg, J., "A Session Initiation Protocol (SIP) Event
           Package for Registrations", RFC 3680, March 2004.

[RFC3842]  Mahy, R., "A Message Summary and Message Waiting
           Indication Event Package for the Session Initiation
           Protocol (SIP)", RFC 3842, August 2004.

[RFC3856]  Rosenberg, J., "A Presence Event Package for the Session
           Initiation Protocol (SIP)", RFC 3856, August 2004.

[RFC3859]  Peterson, J., "Common Profile for Presence (CPP)",
           RFC 3859, August 2004.

[RFC4662]  Roach, A., Campbell, B., and J. Rosenberg, "A Session
           Initiation Protocol (SIP) Event Notification Extension for
           Resource Lists", RFC 4662, August 2006.

Authors' Addresses πŸ’Œ

Aki Niemi
Nokia
P.O. Box 407
NOKIA GROUP, FIN  00045
Finland

Phone: +358 50 389 1644
EMail: aki.niemi@nokia.com


Dean Willis (editor)
Softarmor Systems
3100 Independence Pkwy #311-164
Plano, TX  75075
USA

Phone: +1 214 504 1987
EMail: dean.willis@softarmor.com

That's the whole thing, bestie 🌈✨ RFC 5839 is a wrap, and you're officially cleared to go make conditional notifications slay πŸ’…πŸ¦‹

πŸ“¦ where this page comes from