RFC 4662
A Session Initiation Protocol (SIP) Event Notification Extension for Resource Lists
A Session Initiation Protocol (SIP) Event Notification Extension for Resource Lists โจ
RFC 4662 ๐ is from the Network Working Group and it's a Standards Track doc, which means it's a real protocol spec. It was written by A. B. Roach and B. Campbell (both at Estacado Systems) and J. Rosenberg (at Cisco Systems) in August 2006. The title block doesn't list any RFCs that it obsoletes or updates, so it stands on its own ๐ .
Status of This Memo ๐
okay so this doc is an Internet standards track protocol for the Internet community. It's inviting discussion and suggestions for improvements ๐ซถ. If you want to know where this protocol stands in terms of standardization, check the current edition of the "Internet Official Protocol Standards" (STD 1). And the distribution of this memo is unlimited, so share it with everyone ๐.
Copyright Notice ๐
Copyright (C) The Internet Society (2006). That's the legal bit, bestie ๐.
Abstract ๐ธ
this doc extends the SIP-Specific Event Notification mechanism so you can subscribe to a whole homogeneous list of resources at once ๐ง. Instead of sending a SUBSCRIBE for every single resource one by one (ugh, so much work), you subscribe to the entire list. Then you get notifications whenever the state of any resource in that list changes. It's giving efficiency ๐ฅ.
Table of Contents ๐
1. Introduction ....................................................3
2. Terminology .....................................................4
3. Overview of Operation ...........................................4
4. Operation of List Subscriptions .................................5
4.1. Negotiation of Support for Resource Lists ..................6
4.2. Subscription Duration ......................................7
4.3. NOTIFY Bodies ..............................................7
4.4. RLS Processing of SUBSCRIBE Requests .......................7
4.5. RLS Generation of NOTIFY Requests ..........................7
4.6. Subscriber Processing of NOTIFY Requests ...................9
4.7. Handling of Forked Requests ...............................10
4.8. Rate of Notifications .....................................10
5. Using multipart/related to Convey Aggregate State ..............10
5.1. XML Syntax ................................................11
5.2. List Attributes ...........................................13
5.3. Resource Attributes .......................................14
5.4. Name Attributes ...........................................14
5.5. Instance Attributes .......................................14
5.6. Constructing Coherent Resource State ......................16
5.6.1. Processing Full State Notifications ................17
5.6.2. Processing Partial State Notifications .............17
6. Example ........................................................18
7. Security Considerations ........................................31
7.1. Authentication ............................................31
7.1.1. RLS and Subscriber in the Same Domain ..............31
7.1.2. RLS and Subscriber in Different Domains ............32
7.2. Risks of Improper Aggregation .............................33
7.3. Signing and Sealing .......................................33
7.4. Infinite Loops ............................................34
8. IANA Considerations ............................................34
8.1. New SIP Option Tag: eventlist .............................34
8.2. New MIME type for Resource List Meta-Information ..........34
8.3. URN Sub-Namespace .........................................35
9. Acknowledgements ...............................................36
10. References ....................................................36
10.1. Normative References .....................................36
10.2. Informative References ...................................37
1. Introduction โจ
so the SIP-specific event notification mechanism [2] lets a user (the subscriber) ask to be told when a particular resource changes state ๐. The subscriber sends a SUBSCRIBE request for that resource, and a notifier representing the resource handles it.
But here's the thing: subscribers often care about a whole list of resources ๐. Without some way to aggregate them, the subscriber has to send a SUBSCRIBE for every resource they want info on. That's a big problem when bandwidth is tight, like on wireless networks ๐ถ. Some specific issues:
- Doing this creates a ton of message traffic ๐. You get the initial
SUBSCRIBErequests for each resource, plus the refreshes for every individual subscription. - The notifier might insist on short refresh intervals so it doesn't keep long-lived subscription state around ๐ฉ. That means the subscriber may have to refresh
SUBSCRIBEfaster than it wants to, or faster than it has the capacity for. - The notifier might send
NOTIFYrequests more often than the subscriber wants, so theNOTIFYtraffic gets way louder than the subscriber is happy with ๐.
To fix all of this, the doc defines an extension to RFC 3265 [2] that lets you request and convey notifications for lists of resources ๐. A resource list is identified by a URI, and it represents a list of zero or more URIs. Each of those URIs identifies one resource the subscriber wants info about. A lot of the time, the URI for the resource list will be a SIP URI [1], but other schemes like pres: [10] are also expected to work ๐.
The notifier for the list is called a "resource list server", or RLS ๐งโโ๏ธ. To figure out the state of the entire list, the RLS acts as if it has subscribed to each resource in the list.
Also, the resource list doesn't have to live inside the subscriber's domain, and the resources on the list don't have to live inside the RLS's domain either. Anything goes, lowkey iconic ๐ฆ.
2. Terminology ๐
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 RFC 2119 [5]. (Those are the official BCP 14 key words, so they carry real weight here ๐.)
These terms get used all the way through the rest of the doc, so let's get them straight:
- Back-End Subscription: any subscription (SIP or otherwise) that an RLS creates to learn the state of a resource ๐. An RLS creates back-end subscriptions for resources it isn't the authority on. For back-end subscriptions, RLSes act as a subscriber.
- List Subscription: a subscription to a resource list ๐. In list subscriptions, RLSes act as the notifier.
- Resource: any logical entity that has a state (or states) that can be subscribed to ๐. Resources are identified by URIs.
- Resource List: a list of zero or more resources whose individual states can be subscribed to with a single subscription ๐งบ.
- RLMI: Resource List Meta-Information ๐๏ธ. RLMI is a document that describes the state of the virtual subscriptions tied to a list subscription.
- RLS: Resource List Server ๐. RLSes accept subscriptions to resource lists and send notifications to update subscribers on the state of the resources in a resource list.
- Virtual Subscription: a logical construct inside an RLS that represents subscriptions to the resources in a resource list ๐ช. For each list subscription it services, an RLS creates at least one virtual subscription for every resource in the list being subscribed to. Sometimes, like when the RLS isn't the authority for a resource's state, that virtual subscription is linked to a back-end subscription. Other times, like when the RLS is the authority for the state, the virtual subscription has no corresponding back-end subscription ๐ธ.
3. Overview of Operation ๐ฆ
This section is an overview of the typical way this extension works, so it's not normative ๐. The actual rules are in the rest of the doc.
when users want to subscribe to a list of resources, they can use the mechanisms in this spec ๐ซถ. Step one is creating a resource list, which is represented by a SIP URI. The list holds a set of URIs, and each one represents a resource the subscriber wants info about. The resource list can live in any domain. You could manage the list through a web page, a voice response system, or some other protocol ๐ฑ. How the list gets created and maintained is outside the scope of this spec, so no need to stress about it ๐ .
To find out the state of everything on the list, the user sends a single SUBSCRIBE request aimed at the list's URI โจ. That request gets routed to an RLS for that URI. The RLS acts as the notifier, authenticates the subscriber, and accepts the subscription ๐.
The RLS might already have direct info about some or all of the resources on the list. If it doesn't, it can subscribe to any non-local resources specified by the list resource ๐ญ.
Heads up that subscriptions to non-local resources might or might not be SIP subscriptions. Any mechanism for figuring out that info can be used ๐งฉ. This doc uses the term "back-end subscription" for these, no matter whether SIP is used to set them up and keep them going.
As the state of the resources on the list changes, the RLS generates notifications for the list subscribers ๐. The RLS can, if it wants, buffer the resource-change notifications and send the resource info to the subscriber in batches instead of one at a time ๐ฆ. That lets the RLS do rate limiting for the subscriber, which is honestly such a mood ๐ญ.
The list notifications contain a body of type multipart/related ๐. The root section of that multipart/related content is an XML document that provides meta-information about each resource in the list. The remaining sections hold the actual state info for each resource ๐.
4. Operation of List Subscriptions โจ
okay so the event list extension is lowkey giving event template package energy ๐. The big rule is that any single list subscription has to be homogeneous with respect to the underlying event package. Translation: one list subscription can only apply ONE event package to every resource on the list ๐
Also, it is totally fine for an RLS to let multiple subscriptions to the same list use different event packages ๐ฆ
The real main character difference between list subscriptions and templates in general is that supporting list subscriptions means you support arbitrary nesting of list subscriptions ๐ Elements inside a list can be atomic elements, or they can be lists themselves. Lists all the way down, bestie ๐ง
So when you subscribe to a URI that represents a list, you actually end up with a bunch of virtual subscriptions to a whole tree of resources ๐ธ The leaf nodes of that tree are virtual subscriptions of the event type given in the Event header field. Every other node in the tree is a list subscription, and those get handled the way this section and its subsections describe ๐
Keep in mind that these virtual subscriptions are not literal SIP subscriptions ๐ They might result in SIP subscriptions, depending on how the RLS is implemented, so don't mix them up!
4.1. Negotiation of Support for Resource Lists
This spec uses the SIP option tag mechanism to negotiate support for the extension ๐ซถ For the normative stuff on how the Supported and Require header fields get processed, and what the 421 (Extension Required) response code means, go check RFC 3261 [1]. That's the source of truth, periodt ๐
A non-normative description of what option tags imply is coming up next. It's not the official rulebook, just the vibe check ๐ท
Any client that supports the event list extension will put an option tag of eventlist in a Supported header field of every SUBSCRIBE message for a subscription it's willing to process a list for โจ If the subscription goes to a URI that represents a list, the RLS will put eventlist in a Require header field of the response to that SUBSCRIBE, and in every NOTIFY message within that subscription ๐
Now, why would the notifier put Require: eventlist in NOTIFY messages? Because of the RFC 3261 rule that a UAC MUST insert a Require header field into a request if it wants to insist that the UAS understands an extension in order to process that request ๐ฅ The NOTIFY is literally not usable without the eventlist option, so the notifier is obligated to include it. No choice, bestie ๐ญ
Putting eventlist in a Require header field of a SUBSCRIBE request serves no purpose except to break interoperability in certain cases ๐ So it is NOT RECOMMENDED. Don't do it!!
Sending Supported: eventlist in a NOTIFY message is meaningless and silly ๐ Implementations SHOULD NOT include Supported: eventlist in any requests except for SUBSCRIBE ๐
Here's the tea โ A SIP URI has nothing in it that tells you whether it represents a list of resources or a single resource. So if a subscriber sends a request to a list URI without a Supported header field listing the eventlist token, the notifier will typically return a 421 (Extension Required) response code ๐ RFC 3261 [1] advises servers to avoid returning a 421 and to just try processing the request without the extension. But in this case the URI fundamentally represents a list resource, so the subscription genuinely cannot proceed without this extension. No cap ๐งข
4.2. Subscription Duration
Since the whole point of the resource list server is to cut down the overall messaging volume to a subscriber ๐ it is RECOMMENDED that the subscription duration to a list be reasonably long โณ If no duration is specified, the default comes from the underlying event package. The standard techniques [2] can be used to make that amount longer or shorter, if you need it ๐ฆ
4.3. NOTIFY Bodies
Any implementation compliant with this spec MUST support the multipart/related and application/rlmi+xml MIME types ๐ These types MUST be included in an Accept header sent in a SUBSCRIBE message, on top of any other types the client supports (including any types the event package being used requires) ๐ซถ
4.4. RLS Processing of SUBSCRIBE Requests
Once the subscriber is authenticated, the RLS does authorization according to its local policy ๐ A lot of the time, each resource list belongs to one particular user (the one who created it and manages the elements in it), and only that user gets to subscribe ๐ That's not something baked into resource lists, though. An RLS can use whatever authorization policy it wants โจ
4.5. RLS Generation of NOTIFY Requests
This spec leaves it up to the implementor how and when NOTIFY requests get generated ๐ Honestly, this is where RLS implementations flex on each other: how they aggregate, rate-limit, or optimize notifications is the big differentiator ๐ As a baseline, the RLS MAY generate a NOTIFY to the RLS subscriber whenever the state of any resource on the list changes ๐ง
Okay, pay attention, this part is important ๐ Any given subscription is either a subscription to a single resource or a subscription to a list of resources. That nature (single resource versus list of resources) can NOT change during the life of one subscription ๐ โโ๏ธ So RLSes MUST NOT send NOTIFY messages that don't contain RLMI for a subscription if they've already sent NOTIFY messages containing RLMI in that subscription. And the flip side: RLSes MUST NOT send NOTIFY messages that DO contain RLMI for a subscription if they've previously sent NOTIFY messages in it that didn't. Consistency is everything ๐
Quick lore drop: list representations always contain RLMI documents, and there are two reasons why ๐ก First, they identify the resource that the event state corresponds to. This matters because a lot of state syntaxes don't fully identify the resource they apply to, or they identify it differently than the list does. PIDF documents, for example, can have resource URIs that aren't identical to the URI used to fetch them ๐ Second, RLMI documents disambiguate multiple instances of a single resource ๐ซถ
Check out Section 5 for the detailed syntax used to convey the state of resource lists ๐ For what's coming next, the key thing to know is that the overall list holds zero or more resources, and each resource holds zero or more instances. Every instance has a state attached to it (pending, active, or terminating), which represents the state of the virtual subscription ๐ฆ
Notifications contain a multipart document. The first part ALWAYS has meta-information about the list (like membership and the state of the virtual subscription to each resource) ๐ The remaining parts carry the actual state of the resources listed in that meta-information ๐ธ
The state attribute of each instance of a resource in the meta-information is set according to the state of the virtual subscription ๐ What those state attribute values mean is described in RFC 3265 [2] ๐
Now, if an instance of a resource was reported to the subscriber earlier but is no longer available (meaning the virtual subscription to that instance has been terminated), the resource list server SHOULD include that resource instance in the meta-information in the first NOTIFY message sent to the subscriber after the instance went unavailable ๐ซ The RLS MAY keep doing that in future notifications too ๐
When sending info about a terminated resource instance, the RLS sets a state of terminated and an appropriate reason value ๐ Valid reason values and what they mean are in RFC 3265 [2]. If the RLS is going to try to recover that resource state again later (for example, when the reason in the meta-information is probation), then the instance SHOULD stay in the meta-information until its state is available, or until the RLS gives up on making that state available ๐
When the very first SUBSCRIBE message for a particular subscription hits an RLS, the RLS often won't know the state of every resource in the resource list yet ๐ฅบ For any resource whose state isn't known, the corresponding uri attribute gets set appropriately, and there are NO <instance> elements present for that resource โจ
For an initial notification, sections for resources the RLS does have state for get filled in with the appropriate data (subject, of course, to local policy decisions) ๐ This often happens when the resource list server is co-located with the server for one or more of the resources on the list ๐ง
Immediate notifications triggered by later SUBSCRIBE messages SHOULD include an RLMI document that shows the full state ๐ The RLS SHOULD also include state info for every resource in the list that it has state for, subject to policy restrictions ๐ธ This lets the subscriber refresh their state and recover from lost notifications, which is honestly so iconic of it ๐ซถ
4.6. Subscriber Processing of NOTIFY Requests
Notifications for a resource list can carry info about just a subset of the list elements ๐งฉ So there needs to be an explicit algorithm for building coherent, consistent state on the subscriber's side ๐ฅ
The XML document in the root of the multipart/related document has a <resource> element for some or all of the resources in the list ๐ Each <resource> element contains a URI that uniquely identifies the resource that section corresponds to ๐ฆ When a NOTIFY arrives, it can contain full or partial state, which is indicated by the fullState attribute on the top-level <list> element ๐ If full state is indicated, the recipient replaces ALL state associated with the list with the entities in the NOTIFY body ๐
If full state is NOT indicated, the recipient updates the information for each identified resource ๐ Info for any resource that isn't identified in the NOTIFY stays unchanged, even if it showed up in earlier NOTIFY messages ๐ See Section 5.6 for more info โจ
Full state only applies to the RLMI document it appears in!! One of the <resource> elements in that document might point to another list of resources. Any sub-lists get detailed in their own RLMI documents, which may or may not have full state indicated ๐ง
Also, the underlying event package might have its own rules for compositing partial state notifications ๐ When you're processing data for those packages, their rules apply. Being reported as part of a list doesn't change their partial notification semantics ๐ซถ
Last but not least: because of how resource list subscriptions work, polling resource state may not be super useful ๐ Polls will retrieve the resource list, but they won't necessarily include state for some or all of the resources on it ๐
4.7. Handling of Forked Requests ๐ด
okay so forking is kinda weird for list subscriptions ๐ because the whole point of a list is that it's ONE central place sending out notifications. so a subscriber to a list MUST NOT install multiple subscriptions when the initial request gets forked ๐ โโ๏ธ and if multiple responses come back, they get handled with the techniques in Section 4.4.9 of RFC 3265 [2] โจ
4.8. Rate of Notifications โฑ๏ธ
the RLS can totally act as a bouncer for the subscriber and do rate limiting for them ๐ง but this spec doesn't force any particular rate limit. it just leaves that up to the implementation, so do you bestie ๐
5. Using multipart/related to Convey Aggregate State ๐
to show the state of a bunch of resources at once, the list extension uses the "multipart/related" mime type ๐ฆ the syntax for that lives in "The MIME Multipart/Related Content-type" [4], so go check that out if you want the full tea ๐ซ
5.1. XML Syntax ๐งฉ
the root document of the multipart/related body MUST be a Resource List Meta-Information (RLMI) document ๐ it's of the type "application/rlmi+xml" and it holds the meta-information for all the resources in the notification. here's the schema, bestie ๐
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema targetNamespace="urn:ietf:params:xml:ns:rlmi"
elementFormDefault="qualified"
xmlns="urn:ietf:params:xml:ns:rlmi"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element ref="name" minOccurs="0"
maxOccurs="unbounded" />
<xs:element ref="resource" minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="uri" type="xs:anyURI" use="required" />
<xs:attribute name="version" type="xs:unsignedInt"
use="required" />
<xs:attribute name="fullState" type="xs:boolean"
use="required" />
<xs:attribute name="cid" type="xs:string" use="optional" />
<xs:anyAttribute processContents="lax" />
</xs:complexType>
</xs:element>
<xs:element name="resource">
<xs:complexType>
<xs:sequence>
<xs:element ref="name" minOccurs="0"
maxOccurs="unbounded" />
<xs:element ref="instance" minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="uri" type="xs:anyURI" use="required" />
<xs:anyAttribute processContents="lax" />
</xs:complexType>
</xs:element>
<xs:element name="instance">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded"
processContents="lax" />
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required" />
<xs:attribute name="state" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="active" />
<xs:enumeration value="pending" />
<xs:enumeration value="terminated" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="reason" type="xs:string"
use="optional" />
<xs:attribute name="cid" type="xs:string" use="optional" />
<xs:anyAttribute processContents="lax" />
</xs:complexType>
</xs:element>
<xs:element name="name">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute ref="xml:lang" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
and here's an example of a document that follows that schema ๐ธ
<?xml version="1.0"?>
<list xmlns="urn:ietf:params:xml:ns:rlmi"
uri="sip:adam-friends@lists.vancouver.example.com"
version="7" fullState="true">
<name xml:lang="en">Buddy List</name>
<name xml:lang="fr">Liste d'amis</name>
<resource uri="sip:bob@vancouver.example.com">
<name>Bob Smith</name>
<instance id="juwigmtboe" state="active"
cid="12345.aaa@vancouver.example.com"/>
</resource>
<resource uri="sip:dave@vancouver.example.com">
<name>Dave Jones</name>
<instance id="hqzsuxtfyq" state="active"
cid="12345.aab@vancouver.example.com"/>
</resource>
<resource uri="sip:jim@vancouver.example.com">
<name>Jim</name>
<instance id="oflzxqzuvg" state="terminated"
reason="rejected" />
</resource>
<resource uri="sip:ed@vancouver.example.com">
<name>Ed</name>
<instance id="grqhzsppxb" state="pending"/>
</resource>
</list>
5.2. List Attributes ๐
the <list> element in a list notification MUST contain three attributes, no cap ๐งพ
the first mandatory one is "uri" ๐ it holds the uri for the list, and usually that's the URI the SUBSCRIBE request was sent to.
the second mandatory one is "version" ๐ข it's a number from 0 to 2^32-1. the version MUST be 0 for the first NOTIFY sent in a subscription, and it MUST increase by exactly one for every NOTIFY after that. very orderly, very iconic ๐
the third mandatory one is "fullState" ๐ it tells you whether the NOTIFY has info for every single resource in the list. if it does, the value is true (or 1); if not, it's false (or 0). the first NOTIFY in a subscription MUST contain full state, and so must the first NOTIFY sent after a SUBSCRIBE request for the subscription is received ๐ซถ
finally, <list> elements MAY contain a "cid" attribute ๐ฆ if it's there, it points at a section inside the multipart/related body that has the aggregate state for the resources in the list. what that aggregate info actually looks like is outside the scope of this doc and will be defined per package, as needed. the cid is the Content-ID of that matching section in the multipart body.
the cid attribute MUST refer only to top-level parts of the multipart/related document that the RLMI document it's in is the root of. Section 5.5 has an example if you wanna see it in action ๐
5.3. Resource Attributes ๐ง
the resource list has one <resource> element for each resource being reported in the notification. these elements carry attributes that hold the meta-data for each resource โจ
the "uri" attribute says which resource that <resource> element is about. usually it's a SIP URI that, if you subscribed to it, would give you back that resource's state ๐ก this attribute MUST be present, no exceptions bestie ๐
โโ๏ธ
5.4. Name Attributes ๐ท๏ธ
each list and resource element can have zero or more name elements. these hold human-readable names or descriptions for the list or resource, kinda like the "Display Name" in a SIP name-addr element ๐
name elements can optionally carry the standard XML "xml:lang" attribute ๐ if it's there, it says what language the human-readable name is in. when it's present, it MUST contain a valid language tag. language tags are defined in RFC 3066 [6], and they help apps figure out which of several name elements to show the user ๐
5.5. Instance Attributes ๐ฆ
Okay so each resource element can hold zero or more instance elements โจ Each instance element represents a single notifier for the resource. For event packages that allow forking, there can be multiple virtual subscriptions for one resource, and each one shows up as its own instance element inside that resource element. For subscriptions where forking doesn't happen, there's at most one instance per resource.
The "id" attribute is an opaque string that uniquely identifies the instance of the resource. It only has to be unique within its resource, not globally. How you build that string is totally an implementation decision ๐ Any mechanism works, as long as uniqueness within the resource is assured.
The "state" attribute holds the subscription state for that instance. It's one of "active", "pending", or "terminated", and the meanings match the "Subscription-State" header field from RFC 3265 [2] ๐ธ
If the "state" attribute says "terminated", then a "reason" attribute MUST also be present. It has the same values and meanings as the "reason" parameter on the "Subscription-State" header field in RFC 3265 [2]. Just so you know, the "reason" attribute is only there for informational purposes. The list subscriber is not expected to take any automated actions based on the reason value ๐
Finally, the "cid" attribute MUST be present if the "state" attribute is "active" ๐ It identifies the section within the multipart/related body that contains the actual resource state. That state is expressed in the content type the event package defines for conveying state. The "cid" attribute is the Content-ID for the corresponding section in the multipart body.
The "cid" attribute MUST refer only to top-level parts of the multipart/related document for which the RLMI document in which it appears is the root.
Here's an example to make it click ๐ง Picture a multipart/related document with three parts: A, B, and C. Part A is type application/rlmi+xml, part B is type multipart/related, and part C is type application/pidf+xml. Part B is its own document with three parts: D, E, and F. Part D is type application/rlmi+xml, and parts E and F are both type application/pidf+xml.
+-------------------------------------------+
| Top Level Document: multipart/related |
| |
| +---------------------------------------+ |
| | Part A: application/rlmi+xml | |
| +---------------------------------------+ |
| | Part B: multipart/related | |
| | | |
| | +-----------------------------------+ | |
| | | Part D: application/rlmi+xml | | |
| | +-----------------------------------+ | |
| | | Part E: application/pidf+xml | | |
| | +-----------------------------------+ | |
| | | Part F: application/pidf+xml | | |
| | +-----------------------------------+ | |
| | | |
| +---------------------------------------+ |
| | Part C: application/pidf+xml | |
| +---------------------------------------+ |
| |
+-------------------------------------------+
So any "cid" attributes in document A must refer only to parts B or C. Referring to parts D, E, or F would be illegal. Similarly, any "cid" attributes in document D must refer only to parts E or F, and referring to any other parts would be illegal.
Also note that the subscription durations of any back-end subscriptions are not propagated into the meta-information state in any way. Those timers stay behind the scenes ๐คซ
5.6. Constructing Coherent Resource State ๐
The resource list subscriber keeps a table for each resource list. That table has a row for each resource in the list, and each row is indexed by the URI for that resource. The URI comes from the "uri" attribute on each <resource> element. The contents of each row hold the state of that resource as conveyed in the resource document.
For resources that provide versioning information (which is mandated by [2] for any formats that allow partial notification), each row also holds a resource state version number. The version number for the row gets initialized with the version specified in the first document received, as defined by the corresponding event package. That value is used when comparing versions of partial notifications for a resource ๐ฅ
How the resource list notification gets processed depends on whether it contains full or partial state.
5.6.1. Processing Full State Notifications ๐
If a notification contains full state, which is indicated by the <list> attribute "fullState" set to "true", the notification is used to update the table. First, a check is made to make sure that the "version" attribute of the <list> attribute in the received message is greater than the local version number. If it isn't, the received document is discarded without any further processing. Otherwise, the contents of the resource-list table get flushed and repopulated from the contents of the document. A new row gets created in the table for each "resource" element โจ
5.6.2. Processing Partial State Notifications ๐
If a notification contains partial state, which is indicated by the <list> attribute "fullState" set to "false", a check is made to make sure no list notifications have been lost. The value of the local version number (the "version" attribute of the <list> element) is compared to the version number of the new document.
- If the value in the new document is exactly one higher than the local version number, the local version number goes up by one, and the document is processed as described below.
- If the version in the document is more than one higher than the local version number, the local version number is set to the value in the new document, and the document is processed as described below. The list subscriber SHOULD also generate a refresh request to trigger a full state notification ๐ซถ
- If the version in the document is less than or equal to the local version, the document is discarded without any further processing.
For each resource listed in the document, the subscriber checks whether a row exists for that resource. This check is done by comparing the Resource-URI value with the URI associated with the row. If the resource doesn't exist in the table, a row is added, and its state is set to the information from that "resource" element. If the resource does exist, its state is updated to be the information from that "resource" element, as described in the definition of the event package. If a row is updated or created so that its state is now "terminated," that entry MAY be removed from the table at any time ๐ฆ
6. Example ๐ง
This section gives an example call flow. It is not normative. If a conflict arises between this call flow and the normative behavior described in this or any other document, the normative descriptions are to be followed.
In this particular example, we request a subscription to a nested presence list. The subscriber's address-of-record is "sip:adam@vancouver.example.com", and the name of the nested list resource we're subscribing to is "sip:adam-buddies@pres.vancouver.example.com". The underlying event package is "presence", described by [8].
In this example, the RLS has information to service some of the resources on the list, but it has to consult other servers to get information for others. The implementation of the RLS in this example uses the SIP SUBSCRIBE/NOTIFY mechanism to retrieve that information ๐
Terminal pres.vancouver.example.com pres.stockholm.example.org
| | pres.dallas.example.net |
1 |---SUBSCRIBE--->| | |
2 |<-----200-------| | |
3 |<----NOTIFY-----| | |
4 |------200------>| | |
5 | |---SUBSCRIBE--->| |
6 | |<-----200-------| |
7 | |<----NOTIFY-----| |
8 | |------200------>| |
9 | |------------SUBSCRIBE----------->|
10| |<--------------200---------------|
11| |<-------------NOTIFY-------------|
12| |---------------200-------------->|
13|<----NOTIFY-----| | |
14|------200------>| | |
- We start the subscription by sending a SUBSCRIBE message to our local RLS. (There's no reason the RLS we contact has to be in our domain, of course ๐ธ) Note that we must advertise support for application/rlmi+xml and multipart/related because we support the eventlist extension, and that we must advertise application/pidf+xml because we are requesting a subscription to presence ๐
Terminal -> Local RLS
SUBSCRIBE sip:adam-buddies@pres.vancouver.example.com SIP/2.0
Via: SIP/2.0/TCP terminal.vancouver.example.com;
branch=z9hG4bKwYb6QREiCL
Max-Forwards: 70
To: <sip:adam-buddies@pres.vancouver.example.com>
From: <sip:adam@vancouver.example.com>;tag=ie4hbb8t
Call-ID: cdB34qLToC@terminal.vancouver.example.com
CSeq: 322723822 SUBSCRIBE
Contact: <sip:terminal.vancouver.example.com>
Event: presence
Expires: 7200
Supported: eventlist
Accept: application/pidf+xml
Accept: application/rlmi+xml
Accept: multipart/related
Accept: multipart/signed
Accept: application/pkcs7-mime
Content-Length: 0
- The Local RLS completes the SUBSCRIBE transaction ๐ Authentication and authorization would normally happen at this point in the call flow, but those steps are omitted for brevity.
Local RLS -> Terminal
SIP/2.0 200 OK
Via: SIP/2.0/TCP terminal.vancouver.example.com;
branch=z9hG4bKwYb6QREiCL
To: <sip:adam-buddies@pres.vancouver.example.com>;tag=zpNctbZq
From: <sip:adam@vancouver.example.com>;tag=ie4hbb8t
Call-ID: cdB34qLToC@terminal.vancouver.example.com
CSeq: 322723822 SUBSCRIBE
Contact: <sip:pres.vancouver.example.com>
Expires: 7200
Require: eventlist
Content-Length: 0
- As RFC 3265 [2] requires, the RLS sends a NOTIFY immediately upon accepting the subscription โญ In this example, we're assuming the local RLS is also an authority for presence information for the users in the "vancouver.example.com" domain. The NOTIFY contains an RLMI document describing the entire buddy list (initial notifies require full state), as well as presence information for the users the RLS already knows about. Since the RLS hasn't retrieved information yet for some of the entries on the list, those <resource> elements contain no <instance> elements ๐ฆ
Local RLS -> Terminal
Okay so the NOTIFY is literally the main event ๐ญ๐ฆ The terminal gets a multipart body that has the list (RLMI) and two presence docs, and it's giving organized. ๐
NOTIFY sip:terminal.vancouver.example.com SIP/2.0
Via: SIP/2.0/TCP pres.vancouver.example.com;
branch=z9hG4bKMgRenTETmm
Max-Forwards: 70
From: <sip:adam-buddies@pres.vancouver.example.com>;tag=zpNctbZq
To: <sip:adam@vancouver.example.com>;tag=ie4hbb8t
Call-ID: cdB34qLToC@terminal.vancouver.example.com
CSeq: 997935768 NOTIFY
Contact: <sip:pres.vancouver.example.com>
Event: presence
Subscription-State: active;expires=7200
Require: eventlist
Content-Type: multipart/related;type="application/rlmi+xml";
start="<nXYxAE@pres.vancouver.example.com>";
boundary="50UBfW7LSCVLtggUPe5z"
Content-Length: 1560
--50UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <nXYxAE@pres.vancouver.example.com>
Content-Type: application/rlmi+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns="urn:ietf:params:xml:ns:rlmi"
uri="sip:adam-friends@pres.vancouver.example.com"
version="1" fullState="true">
<name xml:lang="en">Buddy List at COM</name>
<name xml:lang="de">Liste der Freunde an COM</name>
<resource uri="sip:bob@vancouver.example.com"">
<name>Bob Smith</name>
<instance id="juwigmtboe" state="active"
cid="bUZBsM@pres.vancouver.example.com"/>
</resource>
<resource uri="sip:dave@vancouver.example.com">
<name>Dave Jones</name>
<instance id="hqzsuxtfyq" state="active"
cid="ZvSvkz@pres.vancouver.example.com"/>
</resource>
<resource uri="sip:ed@dallas.example.net">
<name>Ed at NET</name>
</resource>
<resource uri="sip:adam-friends@stockholm.example.org">
<name xml:lang="en">My Friends at ORG</name>
<name xml:lang="de">Meine Freunde an ORG</name>
</resource>
</list>
--50UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <bUZBsM@pres.vancouver.example.com>
Content-Type: application/pidf+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:bob@vancouver.example.com">
<tuple id="sg89ae">
<status>
<basic>open</basic>
</status>
<contact priority="1.0">sip:bob@vancouver.example.com</contact>
</tuple>
</presence>
--50UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <ZvSvkz@pres.vancouver.example.com>
Content-Type: application/pidf+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:dave@vancouver.example.com">
<tuple id="slie74">
<status>
<basic>closed</basic>
</status>
</tuple>
</presence>
--50UBfW7LSCVLtggUPe5z--
4. The terminal wraps up the transaction. ๐ Bestie, it's giving "send the 200 and move on" โจ
Terminal -> Local RLS
SIP/2.0 200 OK
Via: SIP/2.0/TCP pres.vancouver.example.com;
branch=z9hG4bKMgRenTETmm
From: <sip:adam-buddies@pres.vancouver.example.com>;tag=zpNctbZq
To: <sip:adam@vancouver.example.com>;tag=ie4hbb8t
Call-ID: cdB34qLToC@terminal.vancouver.example.com
CSeq: 997935768 NOTIFY
Contact: <sip:terminal.vancouver.example.com>
Content-Length: 0
5. Now the local RLS goes shopping for info ๐๏ธ๐ It needs to subscribe to the state of the resources so it can actually service the subscription. In this step it tries to subscribe to the presence state of sip:ed@dallas.example.net. Since the local RLS knows how to receive notifications for list subscriptions, it puts Supported: eventlist in its request. Ngl, the link between this subscription and the one the terminal sent is left up to the application, but this message is lowkey iconic because it lists Accept header fields for every body type it knows the subscriber (Terminal) supports. And it's safe to do, bestie, because the local RLS only passes these formats through to the subscriber and doesn't need to actually understand them ๐ซถ
Local RLS -> Presence Server in dallas.example.net
SUBSCRIBE sip:ed@dallas.example.net SIP/2.0
Via: SIP/2.0/TCP pres.vancouver.example.com;
branch=z9hG4bKMEyGjdG1LH
Max-Forwards: 70
To: <sip:ed@dallas.example.net>
From: <sip:adam@vancouver.example.com>;tag=aM5icQu9
Call-ID: Ugwz5ARxNw@pres.vancouver.example.com
CSeq: 870936068 SUBSCRIBE
Contact: <sip:pres.vancouver.example.com>
Identity: Tm8sIHRoaXMgaXNuJ3QgYSByZWFsIGNlcnQuIFlvdSBvn
Zpb3VzbHkgaGF2ZSB0aW1lIHRvIGtpbGwuIEkKc3VnZ2V
zdCBodHRwOi8vd3d3LmhvbWVzdGFycnVubmVyLmNvbS8K
Identity-Info: https://vancouver.example.com/cert
Event: presence
Expires: 3600
Supported: eventlist
Accept: application/pidf+xml
Accept: application/rlmi+xml
Accept: multipart/related
Accept: multipart/signed
Accept: application/pkcs7-mime
Content-Length: 0
6. The Presence Server in dallas.example.net finishes the SUBSCRIBE transaction. ๐ Authentication would normally happen right about here, but we're skipping it for brevity, so no drama.
Presence Server in dallas.example.net -> Local RLS
SIP/2.0 200 OK
Via: SIP/2.0/TCP pres.vancouver.example.com;
branch=z9hG4bKMEyGjdG1LH
To: <sip:ed@dallas.example.net>;tag=e45TmHTh
From: <sip:adam@vancouver.example.com>;tag=aM5icQu9
Call-ID: Ugwz5ARxNw@pres.vancouver.example.com
CSeq: 870936068 SUBSCRIBE
Contact: <sip:dallas.example.net>
Expires: 3600
Content-Length: 0
7. Plot twist ๐ In this example, the server at dallas.example.net doesn't have enough authorization info to say yes or no to our subscription. So the initial NOTIFY carries a Subscription-State of "pending" ๐ Presumably whoever decides on authorization for the resource gets notified of this change, but those steps are skipped in this call flow for brevity. Not me being dramatic about it being pending... well, a little ๐
Presence Server in dallas.example.net -> Local RLS
NOTIFY sip:pres.vancouver.example.com SIP/2.0
Via: SIP/2.0/TCP pres.dallas.example.net;
branch=z9hG4bKfwpklPxmrW
Max-Forwards: 70
From: <sip:ed@dallas.example.net>;tag=e45TmHTh
To: <sip:adam@vancouver.example.com>;tag=aM5icQu9
Call-ID: Ugwz5ARxNw@pres.vancouver.example.com
CSeq: 1002640632 NOTIFY
Contact: <sip:dallas.example.net>
Subscription-State: pending;expires=3600
Event: presence
Require: eventlist
Content-Length: 0
8. The local RLS finishes the NOTIFY transaction โจ At this point the Local RLS has new info to tell the subscriber, and whether it reports right away or saves it up for later is totally up to the application. For this example, we pretend the RLS waits a little bit before sending, so the subscriptions it sent out have time to actually bring back useful data ๐ฆ
Local RLS -> Presence Server in dallas.example.net
SIP/2.0 200 OK
Via: SIP/2.0/TCP pres.dallas.example.net;
branch=z9hG4bKfwpklPxmrW
From: <sip:ed@dallas.example.net>;tag=e45TmHTh
To: <sip:adam@vancouver.example.com>;tag=aM5icQu9
Call-ID: Ugwz5ARxNw@pres.vancouver.example.com
CSeq: 1002640632 NOTIFY
Contact: <sip:pres.vancouver.example.com>
Content-Length: 0
9. The Local RLS subscribes to the state of the other non-local resource ๐ธ
Local RLS -> RLS in stockholm.example.org
SUBSCRIBE sip:adam-friends@stockholm.example.org SIP/2.0
Via: SIP/2.0/TCP pres.vancouver.example.com;
branch=z9hG4bKFSrAF8CZFL
Max-Forwards: 70
To: <sip:adam-friends@stockholm.example.org>
From: <sip:adam@vancouver.example.com>;tag=a12eztNf
Call-ID: kBq5XhtZLN@pres.vancouver.example.com
CSeq: 980774491 SUBSCRIBE
Contact: <sip:pres.vancouver.example.com>
Identity: Tm90IGEgcmVhbCBzaWduYXR1cmUsIGVpdGhlci4gQ2VydGFp
bmx5IHlvdSBoYXZlIGJldHRlcgp0aGluZ3MgdG8gYmUgZG9p
bmcuIEhhdmUgeW91IGZpbmlzaGVkIHlvdXIgUkxTIHlldD8K
Identity-Info: https://vancouver.example.com/cert
Event: presence
Expires: 3600
Supported: eventlist
Accept: application/pidf+xml
Accept: application/rlmi+xml
Accept: multipart/related
Accept: multipart/signed
Accept: application/pkcs7-mime
Content-Length: 0
10. The RLS in stockholm.example.org finishes the SUBSCRIBE transaction ๐ Again, authentication would normally happen at this point, but it's omitted here for brevity.
RLS in stockholm.example.org -> Local RLS
SIP/2.0 200 OK
Via: SIP/2.0/TCP pres.vancouver.example.com;
branch=z9hG4bKFSrAF8CZFL
To: <sip:adam-friends@stockholm.example.org>;tag=JenZ40P3
From: <sip:adam@vancouver.example.com>;tag=a12eztNf
Call-ID: kBq5XhtZLN@pres.vancouver.example.com
CSeq: 980774491 SUBSCRIBE
Contact: <sip:stockholm.example.org>
Expires: 3600
Content-Length: 0
11. Okay, the RLS in stockholm.example.org is also an authority for presence info for users in the "stockholm.example.org" domain ๐ So its NOTIFY has an RLMI document describing the buddy list, plus presence info for those users. Here the RLS has chosen to sign [14] the body of the NOTIFY. As described in RFC 3851, signing creates a multipart/signed document with two parts. The first part is the thing being signed (in this example, the multipart/related document describing the list resource states), and the second part is the actual signature. It's giving security glow-up ๐ฅ
RLS in stockholm.example.org -> Local RLS
NOTIFY sip:pres.vancouver.example.com SIP/2.0
Via: SIP/2.0/TCP pres.stockholm.example.org;
branch=z9hG4bKmGL1nyZfQI
Max-Forwards: 70
From: <sip:adam-friends@stockholm.example.org>;tag=JenZ40P3
To: <sip:adam@vancouver.example.com>;tag=a12eztNf
Call-ID: kBq5XhtZLN@pres.vancouver.example.com
CSeq: 294444656 NOTIFY
Contact: <sip:stockholm.example.org>
Event: presence
Subscription-State: active;expires=3600
Require: eventlist
Content-Type: multipart/signed;
protocol="application/pkcs7-signature";
micalg=sha1;boundary="l3WMZaaL8NpQWGnQ4mlU"
Content-Length: 2038
--l3WMZaaL8NpQWGnQ4mlU
Content-Transfer-Encoding: binary
Content-ID: <ZPvJHL@stockholm.example.org>
Content-Type: multipart/related;type="application/rlmi+xml";
start="<Cvjpeo@stockholm.example.org>";
boundary="tuLLl3lDyPZX0GMr2YOo"
--tuLLl3lDyPZX0GMr2YOo
Content-Transfer-Encoding: binary
Content-ID: <Cvjpeo@stockholm.example.org>
Content-Type: application/rlmi+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns="urn:ietf:params:xml:ns:rlmi"
uri="sip:adam-friends@stockholm.example.org" version="1"
fullState="true">
<name xml:lang="en">Buddy List at COM</name>
<name xml:lang="de">Liste der Freunde an COM</name>
<resource uri="sip:joe@stockholm.example.org">
<name>Joe Thomas</name>
<instance id="1" state="active"
cid="mrEakg@stockholm.example.org"/>
</resource>
<resource uri="sip:mark@stockholm.example.org">
<name>Mark Edwards</name>
<instance id="1" state="active"
cid="KKMDmv@stockholm.example.org"/>
</resource>
</list>
--tuLLl3lDyPZX0GMr2YOo
Content-Transfer-Encoding: binary
Content-ID: <mrEakg@stockholm.example.org>
Content-Type: application/pidf+xml;charset="UTF-8"
12. Okay, the Local RLS wraps up the NOTIFY transaction with a 200 OK, and it's giving tidy handshake vibes ๐ง
Local RLS -> RLS in stockholm.example.org
SIP/2.0 200 OK
Via: SIP/2.0/TCP pres.stockholm.example.org;
branch=z9hG4bKmGL1nyZfQI
From: <sip:adam-friends@stockholm.example.org>;tag=JenZ40P3
To: <sip:adam@vancouver.example.com>;tag=a12eztNf
Call-ID: kBq5XhtZLN@pres.vancouver.example.com
CSeq: 294444656 NOTIFY
Contact: <sip:pres.vancouver.example.com>
Content-Length: 0
13. Now the Local RLS has collected enough extra info to justify sending a new notification to the user ๐
A full notification would also be totally fine, but this RLS picks a partial notification instead. The RLMI document only has info for the resources that changed, which is why fullState is set to "false". Here's the cute part: to avoid messing up the S/MIME signature on the data from the RLS in stockholm.example.org, the local RLS copies the entire multipart/signed body exactly as-is into the notification it sends. No edits, no drama ๐ซถ
Local RLS -> Terminal
NOTIFY sip:terminal.vancouver.example.com SIP/2.0
Via: SIP/2.0/TCP pres.vancouver.example.com;
branch=z9hG4bK4EPlfSFQK1
Max-Forwards: 70
From: <sip:adam-buddies@pres.vancouver.example.com>;tag=zpNctbZq
To: <sip:adam@vancouver.example.com>;tag=ie4hbb8t
Call-ID: cdB34qLToC@terminal.vancouver.example.com
CSeq: 997935769 NOTIFY
Contact: <sip:pres.vancouver.example.com>
Event: presence
Subscription-State: active;expires=7200
Require: eventlist
Content-Type: multipart/related;type="application/rlmi+xml";
start="<2BEI83@pres.vancouver.example.com>";
boundary="TfZxoxgAvLqgj4wRWPDL"
Content-Length: 2862
--TfZxoxgAvLqgj4wRWPDL
Content-Transfer-Encoding: binary
Content-ID: <2BEI83@pres.vancouver.example.com>
Content-Type: application/rlmi+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns="urn:ietf:params:xml:ns:rlmi"
uri="sip:adam-friends@pres.vancouver.example.com" version="2"
fullState="false">
<name xml:lang="en">Buddy List at COM</name>
<name xml:lang="de">Liste der Freunde an COM</name>
<resource uri="sip:ed@dallas.example.net">
<name>Ed at NET</name>
<instance id="sdlkmeopdf" state="pending"/>
</resource>
<resource uri="sip:adam-friends@stockholm.example.org">
<name xml:lang="en">My Friends at ORG</name>
<name xml:lang="de">Meine Freunde an ORG</name>
<instance id="cmpqweitlp" state="active"
cid="1KQhyE@pres.vancouver.example.com"/>
</resource>
</list>
--TfZxoxgAvLqgj4wRWPDL
Content-Transfer-Encoding: binary
Content-ID: <1KQhyE@pres.vancouver.example.com>
Content-Type: multipart/signed;
protocol="application/pkcs7-signature";
micalg=sha1;boundary="l3WMZaaL8NpQWGnQ4mlU"
--l3WMZaaL8NpQWGnQ4mlU
Content-Transfer-Encoding: binary
Content-ID: <ZPvJHL@stockholm.example.org>
Content-Type: multipart/related;type="application/rlmi+xml";
start="<Cvjpeo@stockholm.example.org>";
boundary="tuLLl3lDyPZX0GMr2YOo"
--tuLLl3lDyPZX0GMr2YOo
Content-Transfer-Encoding: binary
Content-ID: <Cvjpeo@stockholm.example.org>
Content-Type: application/rlmi+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns="urn:ietf:params:xml:ns:rlmi"
uri="sip:adam-friends@stockholm.example.org" version="1"
fullState="true">
<name xml:lang="en">Buddy List at ORG</name>
<name xml:lang="de">Liste der Freunde an ORG</name>
<resource uri="sip:joe@stockholm.example.org">
<name>Joe Thomas</name>
<instance id="1" state="active"
cid="mrEakg@stockholm.example.org"/>
</resource>
<resource uri="sip:mark@stockholm.example.org">
<name>Mark Edwards</name>
<instance id="1" state="active"
cid="KKMDmv@stockholm.example.org"/>
</resource>
</list>
--tuLLl3lDyPZX0GMr2YOo
Content-Transfer-Encoding: binary
Content-ID: <mrEakg@stockholm.example.org>
Content-Type: application/pidf+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:joe@stockholm.example.org">
<tuple id="x823a4">
<status>
<basic>open</basic>
</status>
<contact priority="1.0">sip:joe@stockholm.example.org</contact>
</tuple>
</presence>
--tuLLl3lDyPZX0GMr2YOo
Content-Transfer-Encoding: binary
Content-ID: <KKMDmv@stockholm.example.org>
Content-Type: application/pidf+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:mark@stockholm.example.org">
<tuple id="z98075">
<status>
<basic>closed</basic>
</status>
</tuple>
</presence>
--tuLLl3lDyPZX0GMr2YOo--
--l3WMZaaL8NpQWGnQ4mlU
Content-Transfer-Encoding: binary
Content-ID: <K9LB7k@stockholm.example.org>
Content-Type: application/pkcs7-signature
[PKCS #7 signature here]
--l3WMZaaL8NpQWGnQ4mlU--
--TfZxoxgAvLqgj4wRWPDL--
14. Last step, and it's so satisfying โจ The terminal finishes the NOTIFY transaction by sending back a 200 OK ๐
Terminal -> Local RLS
SIP/2.0 200 OK
Via: SIP/2.0/TCP pres.vancouver.example.com;
branch=z9hG4bK4EPlfSFQK1
From: <sip:adam-buddies@pres.vancouver.example.com>;tag=zpNctbZq
To: <sip:adam@vancouver.example.com>;tag=ie4hbb8t
Call-ID: cdB34qLToC@terminal.vancouver.example.com
CSeq: 997935769 NOTIFY
Contact: <sip:terminal.vancouver.example.com>
Content-Length: 0
7. Security Considerations ๐
Okay bestie, this part is serious, so let's get into it ๐ฅบ The way RLS state gets collected is mostly up to whoever builds the RLS. Some of the security issues below only show up when a SIP back-end subscription is being used for that. Non-SIP ways of getting resource state will usually come with their own security issues too ๐ฌ Listing every possible access method isn't something this document can do, so if you're using one of those, you must analyze your chosen access method for security issues yourself.
7.1. Authentication ๐
If back-end subscriptions are needed to get resource state, the end user is no longer the one directly subscribing to the resource state. So direct authentication of the user is no longer possible ๐
7.1.1. RLS and Subscriber in the Same Domain ๐
The most common setup is going to be the RLS and its subscribers living in the same domain ๐ When that's the case, the RLS can act as an authentication service. That role is defined in "Enhancements for Authenticated Identity Management in the Session Initiation Protocol (SIP)" [7].
Here's the high-level version. The RLS authenticates the subscriber, then puts an Identity header field into every back-end subscription it makes on that user's behalf. That Identity header field cryptographically asserts that the request was authorized to be made for the user named in the From header field ๐โจ
Authenticating requests is super central to the network working properly, so any RLS that uses SIP back-end subscriptions to get information about the resources in a resource list MUST be able to act as an authentication service as defined in [7], provided that local administrative policy allows it to do so.
In other words, every RLS implementation that supports SIP back-end subscriptions also has to include the ability to be configured as an authentication service. Whether an admin actually turns that on is totally up to them ๐ And if an RLS can't act as an identity server, then it's going to behave like the next section describes, because it's basically acting like it's in a different domain from the user.
7.1.2. RLS and Subscriber in Different Domains ๐
In the general case, the SIP Authenticated Identity extensions don't give the RLS a way to securely say that subscriptions are being made on the end user's behalf ๐ญ So when the subscriber and the RLS are in different domains, the RLS has no way to vouch for the user's identity. How back-end subscriptions get authenticated in that situation is left for future study ๐ฎ
Until general solutions show up, RLSes in a different domain from the subscriber they're making back-end subscriptions for SHOULD subscribe to the resources using their own identity. Doing that means the RLS will generally only get the resource information that's publicly available ๐ซ
Until those general solutions exist, implementations of subscriber user agents MAY try direct subscriptions to the resources in the resource list when they're subscribing to an RLS outside their domain (either directly or through another resource list subscription). The resources to subscribe to are the ones in the uri attribute of the <resource> elements in the RLMI document the RLS returns. Subscribing directly lets the user get properly authenticated, which generally means they'll be authorized to get more complete state information ๐ Implementations that choose to do direct subscriptions SHOULD use the data they retrieve instead of any information about the resource they got through the list subscription ๐ธ
7.2. Risks of Improper Aggregation ๐
Okay bestie, so a resource list server (RLS) usually serves info to a bunch of subscribers at the same time ๐ธ. Resources can show up in several lists, and it's super possible that two users subscribe to the same list.
In these cases, misguided RLS implementations might try to save network load by keeping just one back-end subscription to a resource in a list and handing that one result to more than one user ๐. But that totally works around whatever authorization policy the notifier keeps for the resource ๐. Authorization is so much more than "allowed/not allowed" ๐ญ. A resource can show totally different (even conflicting!) states depending on who's asking ๐ซถ.
To make sure event info only goes to the intended recipient, implementations MUST NOT present the result of one back-end subscription to more than one user, unless:
a. The RLS has adequate access to the complete authorization policy associated with the resource to which the back-end subscription has been made, AND
b. The RLS can and has determined that presenting the information to more than one user does not violate such policy.
Note that this is a very difficult problem to solve correctly ๐. Even in the cases where such access is believed possible, this mode of operation is NOT RECOMMENDED. ๐ซ
7.3. Signing and Sealing ๐
Implementors should keep in mind that any section of the MIME body may be signed and/or encrypted as necessary โจ. Resource List Servers should take care not to modify any MIME bodies they receive from any back-end subscriptions, and should not generally rely on being able to read them ๐.
In order to facilitate security, resource list servers SHOULD pass along indication for support of multipart/signed and application/pkcs7-mime content types to any SIP back-end subscriptions, if the subscriber includes them in the initial SUBSCRIBE message ๐ฆ. Not doing so may actually result in resources refusing to divulge state (if notifier policy requires encryption, but the RLS fails to convey support), or subscribers discarding valid state (if subscriber policy requires a signature, but the RLS fails to convey support). Yikes, that's a mess ๐ฌ.
Note that actual implementation of encryption and signing by the RLS is not necessary to be able to pass through signed and/or encrypted bodies ๐.
7.4. Infinite Loops ๐
One risk introduced by the ability to nest resource lists is the possibility of creating lists that ultimately contain themselves as a sub-list ๐. Detection and handling of such a case is trivial when the RLS services all the virtual subscriptions internally. When back-end subscriptions are created to service virtual subscriptions, however, detection of such situations becomes a more difficult problem ๐ตโ๐ซ.
Implementors of RLSes that create back-end subscriptions MUST implement safeguards to prevent such nestings from creating an infinite loop of subscriptions. Typically, such mechanisms will require support in the back-end subscription protocol. In particular, applying filters to the back-end subscriptions can be an effective way to preclude such problems ๐.
8. IANA Considerations ๐ฆ
8.1. New SIP Option Tag: eventlist
This section defines a new option tag for the registry established by Section 27.1 of RFC 3261[1] ๐ง.
Option Tag Name: eventlist
Description: Extension to allow subscriptions to lists of resources.
Published specification: RFC 4662
8.2. New MIME type for Resource List Meta-Information ๐
MIME Media Type Name: application
MIME subtype name: rlmi+xml
Required parameters: None
Optional parameters: charset
See RFC 3023 [12] for a discussion of the charset parameter on
XML-derived MIME types. Since this MIME type is used exclusively
in SIP, the use of UTF-8 encoding is strongly encouraged.
Encoding considerations: 8-bit text
Security considerations: Security considerations specific to uses of
this MIME type are discussed in RFC 4662. RFC 1874 [11] and RFC
3023 [12] discuss security issues common to all uses of XML.
Interoperability considerations: The use of this MIME body is
intended to be generally interoperable. No unique considerations
have been identified.
Published specification: RFC 4662
Applications that use this media type: This media type is used to
convey meta-information for the state of lists of resources within
a Session Initiation Protocol (SIP) subscription.
Additional information:
Magic Number(s): None.
File Extension(s): None.
Macintosh File Type Code(s): None.
Object Identifier(s) or OID(s): None.
Intended usage: Limited Use
Other Information/General Comment: None.
Person to contact for further information:
Name: Adam Roach
E-Mail: adam@estacado.net
Author/Change Controller: The specification of this MIME type is
a work product of the SIMPLE working group and was authored by
Adam Roach, Jonathan Rosenberg, and Ben Campbell. The IETF has
change control over its specification.
8.3. URN Sub-Namespace ๐ธ
URI: urn:ietf:params:xml:ns:rlmi
Description: This is the XML namespace URI for XML elements defined
by RFC 4662 to describe information about subscriptions when such
subscriptions are aggregated within a single SIP subscription. It
is used in the application/rlmi+xml body type.
Registrant Contact:
Name: Adam Roach
E-Mail: adam@estacado.net
Author/Change Controller: The specification of this MIME type is
a work product of the SIMPLE working group and was authored by
Adam Roach, Jonathan Rosenberg, and Ben Campbell. The IETF has
change control over its specification.
XML:
BEGIN
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN"
"http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html;charset=utf-8"/>
<title>Namespace for SIP Event Resource List
Meta-Information</title>
</head>
<body>
<h1>Namespace for SIP Event Resource List
Meta-Information</h1>
<h2>application/rlmi+xml</h2>
<p>See <a href="[http://www.rfc-editor.org/rfc/rfc4662.txt]">
RFC4662</a>.</p>
</body>
</html>
END
9. Acknowledgements ๐ซถ
Huge thanks to Sean Olson for reviewing and correcting how XML is used in this protocol ๐.
Thanks also to Hisham Khartabil, Paul Kyzivat, Keith Drage, and Robert Sparks for their careful reviews of and comments on this document ๐.
10. References ๐
10.1. Normative References
- [1] 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.
- [2] Roach, A. B., "Session Initiation Protocol (SIP)-Specific Event Notification", RFC 3265, June 2002.
- [3] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, November 1996.
- [4] Levinson, E., "The MIME Multipart/Related Content-type", RFC 2387, August 1998.
- [5] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
- [6] Alvestrand, H., "Tags for the Identification of Languages", BCP 47, RFC 3066, January 2001.
- [7] Peterson, J. and C. Jennings, "Enhancements for Authenticated Identity Management in the Session Initiation Protocol (SIP)", RFC 4474, August 2006.
10.2. Informative References
- [8] Rosenberg, J., "A Presence Event Package for the Session Initiation Protocol (SIP)", RFC 3856, August 2004.
- [9] Burger, E., "A Mechanism for Content Indirection in Session Initiation Protocol (SIP) Messages", RFC 4483, May 2006.
- [10] Peterson, J., "Common Profile for Presence (CPP)", RFC 3859, August 2004.
- [11] Levinson, E., "SGML Media Types", RFC 1874, December 1995.
- [12] Murata, M., St. Laurent, S., and D. Kohn, "XML Media Types", RFC 3023, January 2001.
- [13] Ramsdell, B., "Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.1 Message Specification", RFC 3851, July 2004.
- [14] Galvin, J., Murphy, S., Crocker, S., and N. Freed, "Security Multiparts for MIME: Multipart/Signed and Multipart/Encrypted", RFC 1847, October 1995.
- [15] Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000.
Authors' Addresses ๐
Adam Roach
Estacado Systems
US
EMail: adam@estacado.net
Ben Campbell
Estacado Systems
US
EMail: ben@estacado.net
Jonathan Rosenberg
Cisco Systems
600 Lanidex Plaza
Parsippany, NJ 07054-2711
US
EMail: jdrosen@cisco.com
Full Copyright Statement โ๏ธ
Copyright (C) The Internet Society (2006).
This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.
This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Intellectual Property ๐ง
The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.
Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.
The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.
Acknowledgement ๐ท
Funding for the RFC Editor function is provided by the IETF Administrative Support Activity (IASA). ๐
๐ฆ where this page comes from
- ietf: rfc4662 2006-08
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms