Session Initiation Protocol (SIP)-Specific Event Notification
obsoleted by
- rfc-6665 — SIP-Specific Event Notification
obsoletes
- rfc-2543 — SIP: Session Initiation Protocol
updated by
- rfc-5367 — Subscriptions to Request-Contained Resource Lists in the Session Initiation Protocol (SIP)
- rfc-5727 — Change Process for the Session Initiation Protocol (SIP) and the Real-time Applications and Infrastructure Area
- rfc-6446 — Session Initiation Protocol (SIP) Event Notification Extension for Notification Rate Control
updates
- rfc-3261 — SIP: Session Initiation Protocol
Extracted elements (30)
A 481 response to NOTIFY is given special meaning — it unconditionally requires the notifier to remove the corresponding subscription — to prevent subscribers from being used as amplifiers in denial-of-service attacks. Without this, subscribers receiving NOTIFY for unknown subscriptions would need to both send an error and separately send a SUBSCRIBE to cancel.
The event notification framework is explicitly NOT intended as a general-purpose infrastructure for all event subscription and notification. It is scoped to SIP-specific use cases; high-frequency events (more than ~once per second) and unrelated domains (e.g., network management) are out of scope.
Due to forking, a SUBSCRIBE may be accepted by multiple nodes; subscribers MUST be prepared to receive NOTIFY requests with 'From' tags differing from the 'To' tag in the SUBSCRIBE 200-class response. Each dialog resulting from a fork represents a different destination and is handled independently.
For PINT compatibility, servers MAY interpret a SUBSCRIBE with no 'Event' header as a request for PINT events. Servers that do not support PINT SHOULD return '489 Bad Event' for any SUBSCRIBE without an 'Event' header.
200-class responses to SUBSCRIBE requests MUST contain an 'Expires' header. The period in the response MAY be shorter but MUST NOT be longer than specified in the request; the response value defines the actual subscription duration.
'Allow-Events' headers MUST NOT be inserted by proxies. Any node implementing one or more event packages SHOULD include an 'Allow-Events' header in dialog-initiating methods and OPTIONS responses.
Any event package that supports delta state changes MUST include a version number in the NOTIFY body that increases by exactly one per NOTIFY transaction in a subscription. If a NOTIFY arrives with a version incremented by more than one, the subscriber ignores the delta and re-sends SUBSCRIBE to force a full state snapshot.
Each event package MUST specify whether forked SUBSCRIBE requests are allowed to install multiple subscriptions, and if so, whether merging of notifications is required and how such merging is performed.
If a NOTIFY request fails due to an error response and the subscription was installed via a soft-state mechanism, the notifier MUST remove the corresponding subscription. A 481 response to NOTIFY MUST cause subscription removal even for non-SUBSCRIBE-installed subscriptions.
Notifiers MUST NOT wait for a user response before returning a final response to a SUBSCRIBE request; the transaction must complete in the time necessary for automated processing only, to prevent timer F from firing.
NOTIFY requests MUST contain a 'Subscription-State' header with a value of 'active', 'pending', or 'terminated'. If the value is 'active' or 'pending', the notifier SHOULD also include an 'expires' parameter; this mechanism MUST NOT be used to lengthen a subscription.
Subscribers MUST be prepared to receive NOTIFY messages before the SUBSCRIBE transaction has completed, due to the potential for both out-of-order messages and forking.
Subscribers MUST include exactly one 'Event' header in SUBSCRIBE requests, indicating the event package or class of events being subscribed. The event token MUST be registered with IANA.
Upon receiving a NOTIFY request that does not match any outstanding subscription, the subscriber MUST return a '481 Subscription does not exist' response unless another 400- or 500-class response is more appropriate.
Upon successfully accepting or refreshing a subscription, notifiers MUST send a NOTIFY message immediately to communicate current resource state. This applies regardless of whether authorization has already been granted.
Returning specific 4xx/6xx responses to SUBSCRIBE may reveal authorization policy. When privacy is required, notifiers SHOULD always return 202 and send a NOTIFY that appears to contain a plausible piece of state, indistinguishable from a valid response, without revealing actual authorization decisions.
NOTIFY is a SIP method sent by notifiers to inform subscribers of changes in subscribed state. A single SUBSCRIBE may trigger multiple NOTIFY requests; NOTIFY does not terminate the corresponding subscription.
SUBSCRIBE is a dialog-creating SIP method used to request current state and state updates from a remote node. Subscriptions expire and must be refreshed via subsequent SUBSCRIBE messages on the same dialog; a SUBSCRIBE with Expires of 0 constitutes an unsubscribe and also triggers a state fetch.
The '202 Accepted' response to SUBSCRIBE indicates the request was understood but authorization may not yet be granted, allowing notifiers to mask authorization policy. The '489 Bad Event' response indicates the event package in the 'Event' header is not understood.
The 'Allow-Events' header lists the event packages supported by a node. Its presence in a message is sufficient to indicate support for SUBSCRIBE and NOTIFY; it uses compact form 'u'.
The 'Event' header carries a single event package name token and an optional 'id' parameter that identifies a specific subscription within a dialog. The event-type portion is compared byte-by-byte; an 'id' parameter never matches an 'Event' header without one.
The 'Subscription-State' header in NOTIFY requests carries values 'active', 'pending', or 'terminated', plus optional 'expires', 'reason', and 'retry-after' parameters. Reason values include: deactivated, probation, rejected, timeout, giveup, noresource.
This document establishes the IANA SIP Event Types registry for event packages and event template-packages. Normal event packages are allocated First Come First Served; template-packages require IETF Consensus. Registrations must include the token, type (package or template), contact, and/or published specification. Tokens MUST NOT contain '.'.
Implementations SHOULD require authentication with anti-replay protection. Replaying SUBSCRIBE can install arbitrary past subscriptions; replaying NOTIFY can spoof stale state. The prohibition on sending NOTIFY to non-subscribed nodes also mitigates replay effects.
Notifiers SHOULD require authentication to reduce denial-of-service risk. The SUBSCRIBE/NOTIFY pattern (one SUBSCRIBE triggers multiple NOTIFYs) is a classic amplification setup; creation of subscription state on SUBSCRIBE receipt can also be exploited to exhaust resources.
NOTIFY bodies may contain sensitive state information; implementations MAY encrypt SUBSCRIBE and NOTIFY to ensure confidentiality. All implementations SHOULD be able to handle encrypted SUBSCRIBE and NOTIFY messages to allow remote parties to protect sensitive information.
To prevent man-in-the-middle attacks, implementations SHOULD provide integrity protection across 'Contact', 'Route', 'Expires', 'Event', and 'To' headers of SUBSCRIBE messages, and across 'Call-ID', 'CSeq', 'Subscription-State' headers and bodies of NOTIFY messages.
A subscription exists in states: pending (received, authorization not yet determined), active (accepted and authorized), or terminated (no longer active). Transitions are driven by Subscription-State values in NOTIFY messages; reason codes (deactivated, probation, rejected, timeout, giveup, noresource) govern re-subscription behavior upon termination.
Event header ABNF: 'Event' (or compact 'o') followed by event-type (event-package optionally followed by '.' event-template), plus zero or more event-param (generic-param or 'id' EQUAL token). Token-nodot excludes '.', used to separate template from package name.
Subscription-State header ABNF: 'Subscription-State' HCOLON substate-value ('active'/'pending'/'terminated'/extension-substate) followed by zero or more subexp-params: reason=event-reason-value, expires=delta-seconds, retry-after=delta-seconds, or generic-param.