RFC 5057
Multiple Dialog Usages in the Session Initiation Protocol
RFC 5057: Multiple Dialog Usages in the Session Initiation Protocol π
okay bestie, title block time π This one is RFC 5057, written by R. Sparks from Estacado Systems and published in November 2007 under the Network Working Group π. It's Informational, so it's just here to share info, not to set a standard π . It doesn't obsolete or update any other RFCs, because none are listed.
Status of This Memo β¨
Okay so this memo is here to give info to the Internet community π«Ά. It does not specify an Internet standard of any kind, and it can be shared as widely as you want, since distribution is unlimited π¦.
Abstract πΈ
So a bunch of SIP methods can create a dialog, which is basically an association between two endpoints π. Some of those methods can also make a second, related association inside an existing dialog. These extra associations are called dialog usages, and they're kinda tricky π. Each one has its own life-cycle but they all share the same dialog state, so they need really careful handling. Honestly, nobody fully understands how to process multiple usages correctly yet, and the parts we do understand are hard to implement π.
This memo's whole argument is that multiple dialog usages should be avoided π. It talks about alternatives, and it clarifies the essential behavior for the elements that can't avoid them right now π.
This is an informative document and makes no normative statements of any kind β¨.
Table of Contents π
1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
3. Examples of Multiple Usages . . . . . . . . . . . . . . . . . 4
3.1. Transfer . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.2. Reciprocal Subscription . . . . . . . . . . . . . . . . . 6
4. Usage Creation and Destruction . . . . . . . . . . . . . . . . 9
4.1. Invite Usages . . . . . . . . . . . . . . . . . . . . . . 9
4.2. Subscribe usages . . . . . . . . . . . . . . . . . . . . . 9
5. Proper Handling of Multiple Usages . . . . . . . . . . . . . . 9
5.1. A Survey of the Effect of Failure Responses on Usages
and Dialogs . . . . . . . . . . . . . . . . . . . . . . . 9
5.2. Transaction Timeouts . . . . . . . . . . . . . . . . . . . 15
5.3. Matching Requests to Usages . . . . . . . . . . . . . . . 16
5.4. Target Refresh Requests . . . . . . . . . . . . . . . . . 17
5.5. Refreshing and Terminating Usages . . . . . . . . . . . . 17
5.6. Refusing New Usages . . . . . . . . . . . . . . . . . . . 18
5.7. Replacing Usages . . . . . . . . . . . . . . . . . . . . . 18
6. Avoiding Multiple Usages . . . . . . . . . . . . . . . . . . . 18
7. Security Considerations . . . . . . . . . . . . . . . . . . . 23
8. Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . 24
9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 24
10. Informative References . . . . . . . . . . . . . . . . . . . . 24
1. Overview π§
This is an informative document, so it makes no normative statements of any kind π«. It refines the idea of a dialog usage in SIP [1], and it digs into where that idea came from. It also explores the ambiguity around processing multiple dialog usages that share one dialog. The big focus is how SIP failure responses affect the transaction, the dialog usage, and the dialog state π₯. The goal is to help implementers understand what it takes to process multiple dialog usages correctly, and to give background for future standards-track work that will clarify RFC 3261 and other related documents π. Last but not least, the document looks at single-usage dialog alternatives that use SIP extensions, as a replacement for multiple dialog usages π¦.
2. Introduction π
Several SIP methods can establish a dialog πΈ. When they do, they also set up an association between the endpoints in that dialog. The developer community has been calling this association a "dialog usage" for a while now π . A dialog started with an INVITE request has an invite usage. A dialog started with a SUBSCRIBE request has a subscribe usage. A dialog started with a REFER request also has a subscribe usage π§.
Dialogs end up with multiple usages when a usage-creating action happens inside a dialog that already exists π. Examples include accepting a REFER or SUBSCRIBE that gets issued inside a dialog set up with an INVITE request. Multiple REFERs inside one dialog create multiple subscriptions, and each one is a brand new dialog usage sharing the same dialog state π. (Heads up: any REFER sent using the subscription-suppression mechanism from [2] creates no new usage π.) Here's another one: an endpoint in an INVITE-created dialog might subscribe to its peer's Key Press Markup Language (KPML) [3], and then later send a REFER. That gives you three dialog usages all sharing the same dialog state π₯.
The common state shared by any usages in a dialog is exactly this:
- the Call-ID
- the local Tag
- the remote Tag
- the local CSeq
- the remote CSeq
- the Route-set
- the local contact
- the remote target
- the secure flag
Usages also have their own state that isn't shared across the dialog π. A subscription, for example, has a duration plus other usage-specific stuff. If you have multiple subscriptions in the same dialog, each one has its own duration β¨.
A dialog comes into existence when the first usage is created, and it keeps existing until the last usage is terminated. That's basically reference counting π. The tricky part is that a lot of SIP's usage management, like authentication, was originally designed on the assumption that each dialog would only have one usage π. So the mechanisms we ended up with have mixed effects: some of them touch the individual usage, and some of them touch the whole dialog π.
Right now the current specs define two usages, invite and subscribe. A dialog can have up to one invite usage and as many subscribe usages as it wants π.
Now here's a fun one. RFC 3261 [1] says user agents should reuse the Call-ID and increment the CSeq across a series of registration requests. It also shows to-tags in register responses in some examples. Because of that, some implementations started treating REGISTER as if it lived inside a dialog π. But RFC 3261 explicitly says REGISTER does not create a dialog. A series of REGISTER requests creates no usage and no dialog at all. PUBLISH [4] doesn't create any usage or dialog either β¨.
3. Examples of Multiple Usages π
3.1. Transfer π¦
Okay, so in Figure 1, Alice transfers a call she got from Bob over to Carol π. A dialog (plus an invite dialog usage) between Alice and Bob starts with the 200 OK labeled F1 π. A second usage shows up with the NOTIFY labeled F2. That's a subscription to event refer π₯. This second usage ends when the subscription gets terminated by the NOTIFY transaction labeled F3 π. The dialog still has one usage left, the invite usage, and that one lasts until the BYE transaction labeled F4 π. Once that happens, the dialog has zero usages left, so it stops existing π. You can see the details of each message in Figure 2 π.
Figure 1, the ladder diagram π§
Alice Bob Carol
| INVITE | |
|<----------------| |
Dialog 1 Usage 1 | 200 OK (F1) | |
-start- -start- ----------->|---------------->| |
| | | ACK | |
| | |<----------------| |
| | | reINVITE/200/ACK| |
| | | (hold) | |
| | |---------------->| |
| | | REFER | |
| | Dialog 1 |---------------->| |
| | Usage 2 | NOTIFY (F2) | |
| | -start- -->|<----------------| INVITE |
| | | | 200 NOTIFY |----------->|
| | | |---------------->| 200 OK |
| | | | 200 REFER |<-----------|
| | | |<----------------| ACK |
| | | | NOTIFY (F3) |----------->|
| | | |<----------------| |
| | | | 200 | . |
| | -end- -->|---------------->| . |
| | | BYE (F4) | Dialog 2 |
| | |<----------------| proceeds |
| | | 200 | . |
-end- -end- ------------>|---------------->| . |
Figure 1
Message Details (abridged to show only dialog or usage details) π
F1
SIP/2.0 200 OK
Call-ID: dialog1@bob.example.com
CSeq: 100 INVITE
To: <sip:Alice@alice.example.com>;tag=alicetag1
From: <sip:Bob@bob.example.com>;tag=bobtag1
Contact: <sip:aliceinstance@alice.example.com>
F2
NOTIFY sip:aliceinstance@alice.example.com SIP/2.0
Event: refer
Call-ID: dialog1@bob.example.com
CSeq: 101 NOTIFY
To: <sip:Alice@alice.example.com>;tag=alicetag1
From: <sip:Bob@bob.example.com>;tag=bobtag1
Contact: <sip:bobinstance@bob.example.com>
F3
NOTIFY sip:aliceinstance@alice.example.com SIP/2.0
Event: refer
Subscription-State: terminated;reason=noresource
Call-ID: dialog1@bob.example.com
CSeq: 102 NOTIFY
To: <sip:Alice@alice.example.com>;tag=alicetag1
From: <sip:Bob@bob.example.com>;tag=bobtag1
Contact: <sip:bobinstance@bob.example.com>
Content-Type: message/sipfrag
SIP/2.0 200 OK
F4
BYE sip:aliceinstance@alice.example.com SIP/2.0
Call-ID: dialog1@bob.example.com
CSeq: 103 BYE
To: <sip:Alice@alice.example.com>;tag=alicetag1
From: <sip:Bob@bob.example.com>;tag=bobtag1
Contact: <sip:bobinstance@bob.example.com>
Figure 2
3.2. Reciprocal Subscription π
Okay so in Figure 3, Alice subscribes to Bob's presence π. For simplicity, pretend Bob and Alice are both serving their presence straight from their endpoints instead of through a presence server. To keep the focus on the good stuff, the figure skips the rendezvous signaling that Alice uses to find Bob's endpoint.
Bob is interested in Alice's presence too, so he subscribes right back to her (in most deployed presence/IM systems, people watch each other, it's giving mutual π«Ά). He skips the rendezvous step because he's already in a dialog with Alice, so he sends his SUBSCRIBE inside that dialog. Some early SIMPLE clients actually did this, so it's not a made-up situation π§.
The dialog and its first usage come into being at F1, which sets up Alice's subscription to Bob. The second usage starts at F2, which sets up Bob's subscription to Alice. These two subscriptions are independent. They have distinct, different expirations, but they share all of the dialog state π .
The first usage ends when Alice decides to unsubscribe at F3. Bob's subscription to Alice is still going, so the dialog keeps existing. Alice's UA has to keep holding onto this dialog state even though the subscription that created it is over πΈ. The second usage ends when Alice decides to terminate Bob's subscription at F4. She's probably going to reject any attempt Bob makes to resubscribe until she's ready to subscribe to him again π. Since this was the last usage, the dialog also terminates. The details of these messages are in Figure 4.
Alice Bob
| |
| SUBSCRIBE |
|------------------->|
Dialog Usage 1 | NOTIFY (F1) |
-start- -start- --------->|<-------------------|
| | | 200 SUBSCRIBE |
| | |<-------------------|
| | | 200 NOTIFY |
| | |------------------->|
| | | SUBSCRIBE |
| | |<-------------------|
| | Usage 2 | NOTIFY (F2) |
| | -start- -->|------------------->|
| | | | 200 SUBSCRIBE
| | | |------------------->|
| | | | 200 NOTIFY |
| | | |<-------------------|
| | | | : |
| | | | : |
| | | | (un)SUBSCRIBE (F3) |
| | | |------------------->|
| | | | 200 |
| | | |<-------------------|
| | | | NOTIFY |
| | | |<-------------------|
| | | | 200 |
| -end- ----------->|------------------->|
| | | : |
| | | : |
| | | NOTIFY (F4) |
| | | (Terminated) |
| | |------------------->|
| | | 200 |
-end- -end- -->|<-------------------|
| |
Figure 3
Message details (trimmed down to just the dialog or usage bits) β¨
F1
NOTIFY sip:aliceinstance@alice.example.com SIP/2.0
Event: presence
Subscription-State: active;expires=600
Call-ID: alicecallid1@alice.example.com
From: <sip:Bob@bob.example.com>;tag=bobtag2
To: <sip:Alice@alice.example.com>;tag=alicetag2
CSeq: 100 NOTIFY
Contact: <sip:bobinstance@bob.example.com>
F2
NOTIFY sip:bobinstance@bob.example.com SIP/2.0
Event: presence
Subscription-State: active;expires=1200
Call-ID: alicecallid1@alice.example.com
To: <sip:Bob@bob.example.com>;tag=bobtag2
From: <sip:Alice@alice.example.com>;tag=alicetag2
CSeq: 500 NOTIFY
Contact: <sip:aliceinstance@alice.example.com>
F3
SUBSCRIBE sip:bobinstance@bob.example.com SIP/2.0
Event: presence
Expires: 0
Call-ID: alicecallid1@alice.example.com
To: <sip:Bob@bob.example.com>;tag=bobtag2
From: <sip:Alice@alice.example.com>;tag=alicetag2
CSeq: 501 SUBSCRIBE
Contact: <sip:aliceinstance@alice.example.com>
F4
NOTIFY sip:bobinstance@bob.example.com SIP/2.0
Event: presence
Subscription-State: terminated;reason=deactivated
Call-ID: alicecallid1@alice.example.com
To: <sip:Bob@bob.example.com>;tag=bobtag2
From: <sip:Alice@alice.example.com>;tag=alicetag2
CSeq: 502 NOTIFY
Contact: <sip:aliceinstance@alice.example.com>
Figure 4
4. Usage Creation and Destruction π
Dialogs come into existence along with their first usage, and they terminate once their last usage is destroyed π. The messages that create and destroy usages depend on the usage. This section gives a high-level sorting of those messages. It doesn't try to dig into the REGISTER pseudo-dialog, so that one's on its own π ββοΈ.
4.1. Invite Usages π
Created by:
non-100 provisional responses to INVITE200 response to INVITE
Destroyed by:
200 responses to BYEcertain failure responses to INVITE, UPDATE, PRACK, INFO, or BYEanything that destroys a dialog and all its usages
4.2. Subscribe usages π
Created by:
200 class responses to SUBSCRIBE200 class responses to REFERNOTIFY requests
Destroyed by:
200 class responses to NOTIFY-terminatedNOTIFY or refresh-SUBSCRIBE request timeoutcertain failure responses to NOTIFY or SUBSCRIBEexpiration without refresh if network issues prevent the terminal NOTIFY from arrivinganything that destroys a dialog and all its usages
5. Proper Handling of Multiple Usages π§©
The examples in Section 3 are the easy ones, where it's pretty obvious when the dialog starts and when it ends. Sadly, lots of scenarios aren't that clear π. For instance, in Figure 1, what would it mean if the response to the NOTIFY (F2) were a 481? Does that just terminate the refer subscription, or does it destroy the entire dialog? π This section digs into the problem areas with multiple usages that have been spotted so far.
5.1. A Survey of the Effect of Failure Responses on Usages and Dialogs π
For this survey, picture a subscribe usage living inside a dialog that was set up with an invite usage. Unless it says otherwise, we'll talk about what happens to each usage and to the dialog when a client sending a NOTIFY inside the subscribe usage gets a failure response (like a transferee sending a NOTIFY for event refer). Also, unless noted otherwise, the conclusions apply to any number of multiple usages π. This survey is written from the point of view of the client that receives the error response. The effect on dialogs and usages at the server that sends the response is the same.
3xx responses: Redirection in the middle of a dialog isn't well understood in SIP, but whatever effect it has hits the entire dialog and all of its usages equally π¦. In our example, both the subscription and the invite usage would get redirected by that one response.
For the failure responses with code 400 and greater, there are three common ways the failure can affect transaction, usage, and dialog state β¨.
Transaction Only: The error only affects the transaction, not the usage or dialog that the transaction happens in (apart from affecting the local CSeq). Any other usage of the dialog is unaffected. The error is a complaint about this transaction, not about the usage or dialog it lives in π.
Destroys Usage: The error destroys the usage, but not the dialog. Any other usages sharing this dialog are not affected π·.
Destroys Dialog: The error destroys the dialog and every usage sharing it π₯.
Table 1 and Table 2 show how the different codes affect transaction, usage, or dialog state. Any code-specific comments or exceptions come after the table π .
+----------------------+----------------+-----------------+
| Transaction Only | Destroys Usage | Destroys Dialog |
+----------------------+----------------+-----------------+
| 400 (or unknown 4xx) | 405, 480 | 404, 410, 416 |
| 401, 402, 403, 406 | 481, 489 | 482, 483 |
| 407, 408, 412-415 | 501 | 484, 485 |
| 417, 420, 421, 422 | | 502, 604 |
| 423, 428, 429 | | |
| 436-438, 486, 487 | | |
| 488, 491, 493, 494 | | |
| 500 (or unknown 5xx) | | |
| 503, 504, 505 | | |
| 513, 580 | | |
| 600 (or unknown 6xx) | | |
| 603, 606 | | |
+----------------------+----------------+-----------------+
Table 1
Okay bestie, here's the big cheat sheet of failure codes and what they actually do to your usages and dialogs π β¨
+---------+---------------------------------+-------------+-------+
| Code | Reason | Impact | Notes |
+---------+---------------------------------+-------------+-------+
| 400/4xx | Bad Request | Transaction | |
| 401 | Unauthorized | Transaction | |
| 402 | Payment Required | Transaction | (1) |
| 403 | Forbidden | Transaction | |
| 404 | Not Found | Dialog | (2) |
| 405 | Method Not Allowed | Usage | (3) |
| 406 | Not Acceptable | Transaction | |
| 407 | Proxy Authentication Required | Transaction | |
| 408 | Request Timeout | Transaction | (4) |
| 410 | Gone | Dialog | (2) |
| 412 | Conditional Request Failed | Transaction | |
| 413 | Request Entity Too Large | Transaction | |
| 414 | Request-URI Too Long | Transaction | |
| 415 | Unsupported Media Type | Transaction | |
| 416 | Unsupported URI Scheme | Dialog | (2) |
| 417 | Unknown Resource-Priority | Transaction | |
| 420 | Bad Extension | Transaction | |
| 421 | Extension Required | Transaction | |
| 422 | Session Interval Too Small | Transaction | (5) |
| 423 | Interval Too Brief | Transaction | |
| 428 | Use Identity Header | Transaction | |
| 429 | Provide Referrer Identity | Transaction | (6) |
| 436 | Bad Identity-Info | Transaction | |
| 437 | Unsupported Certificate | Transaction | |
| 438 | Invalid Identity Header | Transaction | |
| 480 | Temporarily Unavailable | Usage | (7) |
| 481 | Call/Transaction Does Not Exist | Usage | (8) |
| 482 | Loop Detected | Dialog | (9) |
| 483 | Too Many Hops | Dialog | (10) |
| 484 | Address Incomplete | Dialog | (2) |
| 485 | Ambiguous | Dialog | (2) |
| 486 | Busy Here | Transaction | (11) |
| 487 | Request Terminated | Transaction | |
| 488 | Not Acceptable Here | Transaction | |
| 489 | Bad Event | Usage | (12) |
| 491 | Request Pending | Transaction | |
| 493 | Undecipherable | Transaction | |
| 494 | Security Agreement Required | Transaction | |
| 500/5xx | Server Internal Error | Transaction | (13) |
| 501 | Not Implemented | Usage | (3) |
| 502 | Bad Gateway | Dialog | (14) |
| 503 | Service Unavailable | Transaction | (15) |
| 504 | Server Time-Out | Transaction | (16) |
| 505 | Version Not Supported | Transaction | |
| 513 | Message Too Large | Transaction | |
| 580 | Precondition Failure | Transaction | |
| 600/6xx | Busy Everywhere | Transaction | (17) |
| 603 | Decline | Transaction | |
| 604 | Does Not Exist Anywhere | Dialog | (2) |
| 606 | Not Acceptable | Transaction | |
+---------+---------------------------------+-------------+-------+
Table 2
Now for the notes, which is where the juicy details live π
(1) 402 Payment Required πΈ: this is a reserved response code. If you run into it, you should treat it as an unrecognized 4xx π«Ά
(2) This note covers a whole squad of codes that all behave the same way:
- 404 Not Found π
- 410 Gone π»
- 416 Unsupported URI Scheme π«
- 484 Address Incomplete π§©
- 485 Ambiguous π€·ββοΈ
- 604 Does Not Exist Anywhere π
The Request-URI being rejected is the remote target set by the Contact that the peer gave you. Getting one of these means something has gone fundamentally wrong with the dialog state ππ
(3) This one covers 405 Method Not Allowed and 501 Not Implemented π. Either of them would be aberrant in our example scenario, since support for the NOTIFY method is required by the usage. Here the UA knows the condition is unrecoverable, so it should stop sending NOTIFYs on the usage, and any refresh subscriptions should be rejected. In general these errors affect at most the usage. If the request wasn't integral to the usage (it used an unknown method, or was an INFO inside an INVITE usage, for example), then only the transaction is affected π―
(4) 408 Request Timeout β°: receiving a 408 has the same effect on usages and dialogs as a real transaction timeout, as described in Section 5.2 π¦
(5) 422 Session Interval Too Small π: this response doesn't make sense for any mid-usage request. If you get it, an element in the path of the request is violating protocol, and the recipient should treat it the way it would an unknown 4xx response π©
(6) 429 Provide Referrer Identity πͺͺ: this response won't be returned to a NOTIFY in our example scenario. When it comes back to a REFER, though, it's only objecting to the REFER request itself π
(7) 480 Temporarily Unavailable π°οΈ: RFC 3261 is unclear on what this response means for mid-usage requests. Future updates to that specification are expected to clarify that this response affects only the usage in which the request occurs, and no other usages are affected. If the response included a Retry-After header field, further requests in that usage should not be sent until the indicated time has passed. Requests in other usages may still be sent at any time π
(8) 481 Call/Transaction Does Not Exist π«₯: this response means the peer has lost its copy of the dialog usage state. The dialog itself should not be destroyed unless this was the last usage.
Honestly, the effects of a 481 on a dialog and its usages are the most ambiguous of any final response π© Some implementations follow the meaning recommended here, and others destroy the entire dialog without regard to the number of outstanding usages. Going with this clarification lets the deployed implementations that assumed only the usage was destroyed work with a wider range of implementations. Existing implementations that destroy all other usages in the dialog will keep working the way they do now. The catch is that peers following the recommendation will try to do things with the other usages, and this element will return 481s for each of them until they're all gone. The necessary clarification to RFC 3261 also needs to make it very clear that being able to terminate usages independently of the overall dialog using a 481 is not a reason to design new applications that count on multiple usages in a dialog π¨
The 481 response to a CANCEL request is treated differently, bestie π For CANCEL, a 481 means the UAS can't find a matching transaction. A 481 response to a CANCEL affects only the CANCEL transaction. The usage associated with the INVITE is not affected πΈ
(9) 482 Loop Detected π: this response is aberrant mid-dialog. It only occurs if the Record-Route header field was improperly constructed by the proxies involved in setting up the dialog's initial usage, or if a mid-dialog request forks and merges (which should never happen). Future requests using this dialog state will also fail π
There's also an edge condition during RFC 3263 failover at the element sending a request, where the request effectively forks to multiple destinations from the client. Some implementations make this more likely by trying the next potential location, as determined by RFC 3263, very rapidly if the first one doesn't respond right away. In any situation where a client sends the same request to more than one endpoint, it must be prepared to receive a response from each branch, and it should choose a "best" response to act on, following the same guidelines as a forking proxy. In this particular race condition, if multiple branches respond, all but one will most likely return a 482 Merged Request. The client should select the remaining non-482 response as the "best" response π§
(10) 483 Too Many Hops π¦: similar to 482, receiving this mid-dialog is aberrant. Unlike 482, recovery may be possible by increasing Max-Forwards, assuming the requester did something strange like using a smaller value for Max-Forwards in mid-dialog requests than it used for the initial request. If the request isn't tried again with an increased Max-Forwards, then the agent should follow the Destroy Dialog actions π
(11) 486 Busy Here π΅: this response is nonsensical in our example scenario, or in any scenario where it comes inside an established usage. If it shows up in that context, it should be treated as an unknown 4xx response π ββοΈ
(12) 489 Bad Event π: in our example scenario, [5] declares that the subscription usage in which the NOTIFY is sent is terminated. This response is only valid in the context of SUBSCRIBE and NOTIFY. UAC behaviour for receiving this response to other methods isn't specified, but treating it as an unknown 4xx is a reasonable practice π
(13) 500 and 5xx unrecognized responses π©οΈ: if the response contains a Retry-After header field value, the server thinks the condition is temporary, and the request can be retried after the indicated interval. If the response doesn't contain a Retry-After header field value, the UA may decide to retry after an interval of its own choosing, or it may attempt to gracefully terminate the usage. Whether or not to terminate other usages depends on the application. If the UA receives a 500 (or an unrecognized 5xx) in response to an attempt to gracefully terminate this usage, it can treat this usage as terminated. If this is the last usage sharing the dialog, the dialog is also terminated π
(14) 502 Bad Gateway π: this response is aberrant mid-dialog. It only occurs if the Record-Route header field was improperly constructed by the proxies involved in setting up the dialog's initial usage. Future requests using this dialog state will also fail π΅
(15) 503 Service Unavailable π§: as per [6], the logic that handles locating SIP servers for transactions may handle 503 responses. This effectively means sequentially forking at the endpoint based on DNS results. If that process doesn't yield a better response, a 503 may be returned to the transaction user. Like a 500 response, this error is a complaint about this transaction, not the usage. Because this response occurred in the context of an established usage (and therefore an existing dialog), the route-set has already been formed, and any opportunity to try alternate servers (as recommended in [1]) has been used up by the RFC3263 logic π₯²
(16) 504 Server Time-out: Okay, this one's a bit of a mystery π It's not obvious under what circumstances this response would come back for a request in an existing dialog.
(17) 600 and 6xx unrecognized responses: this one is so iconic π
Unlike 400 Bad Request, a 600 response code says something about the recipient user, not the request that was made. This end user is basically saying they're not up for communicating π
ββοΈ. If the response has a Retry-After header field value, the user is open to talking later, so the request can be retried after the indicated interval β°. This usage, and any other usages sharing the dialog, are unaffected β¨. If there's no Retry-After header field value, the UA may decide to retry after an interval of its choosing, or attempt to gracefully terminate the usage. Whether or not to terminate other usages depends on the application π€·ββοΈ. If the UA gets a 600 (or unrecognized 6xx) in response to an attempt to gracefully terminate this usage, it can treat this usage as terminated π«Ά. And if this is the last usage sharing the dialog, the dialog is also terminated π.
5.2. Transaction Timeouts π¦
[1] states that a UAC should terminate a dialog (by sending a BYE) if no response is received for a request sent within a dialog. Bestie, this recommendation should have been limited to the invite usage instead of the whole dialog π. [5] states that a timeout for a NOTIFY removes a subscription, but a SUBSCRIBE that fails with anything other than a 481 does not. So it's honestly confusing π€. Given these statements, it is unclear whether a refresh SUBSCRIBE issued in a dialog shared with an invite usage destroys either usage or the dialog if it times out.
Generally, a transaction timeout should affect only the usage in which the transaction occurred πΈ. Other usages sharing the dialog should not be affected. In the worst case of timeout due to total transport failure, it may require multiple failed messages to remove all usages from a dialog (at least one per usage) π.
There are some mid-dialog messages that never belong to any usage. If they time out, they will have no effect on the dialog or its usages π§.
5.3. Matching Requests to Usages π
For many mid-dialog requests, figuring out which usage they belong to is obvious. A dialog can have at most one invite usage, so any INVITE, UPDATE, PRACK, ACK, CANCEL, BYE, or INFO requests belong to it. The usage (i.e. the particular subscription) that SUBSCRIBE, NOTIFY, and REFER requests belong to can be determined from the Event header field of the request. REGISTER requests within a (pseudo)-dialog belong to the registration usage. (As mentioned before, implementations aren't mixing registration usages with other usages, so this document isn't exploring the consequences of that bad behavior π.)
According to [1], "an OPTIONS request received within a dialog generates a 200 OK response that is identical to one constructed outside a dialog and does not have any impact on that dialog". So OPTIONS does not belong to any usage β¨. Only those failures discussed in Section 5.1 and Section 5.2 that destroy entire dialogs will have any effect on the usages sharing the dialog with a failed OPTIONS request.
MESSAGE requests are discouraged inside a dialog π ββοΈ. Implementations are restricted from creating a usage for the purpose of carrying a sequence of MESSAGE requests (though some implementations use it that way, against the standard recommendation). A failed MESSAGE occurring inside an existing dialog will have similar effects on the dialog and its usages as a failed OPTIONS request.
Mid-dialog requests with unknown methods cannot be matched with a usage. Servers will return a failure response (likely a 501). The effect on the dialog and its usages at either the client or the server should be similar to that of a failed OPTIONS request.
These guidelines for matching messages to usages (or determining there is no usage) apply equally when acting as a UAS, a UAC, or any third party tracking usage and dialog state by inspecting all messages between two endpoints π.
5.4. Target Refresh Requests π
Target refresh requests update the remote target of a dialog when they are successfully processed. The currently defined target refresh requests are INVITE, UPDATE, SUBSCRIBE, NOTIFY, and REFER [7]).
The remote target is part of the dialog state. When a target refresh request affects it, it affects it for ALL usages sharing that dialog π±. If a subscription and invite usage are sharing a dialog, sending a refresh SUBSCRIBE with a different contact will cause reINVITEs from the peer to go to that different contact.
A UAS will only update the remote target if it sends a 200 class response to a target refresh request. A UAC will only update the remote target if it receives a 200 class response to a target refresh request. Again, any update to a dialog's remote target affects all usages of that dialog π.
There is known ambiguity around the effects of provisional responses on remote targets, and a future specification will attempt to clarify it. Furthermore, because the remote target is part of the dialog state, not any usage state, there is ambiguity in having target refresh requests in progress simultaneously on multiple usages in the same dialog. Implementation designers should consider these conditions with care π§.
5.5. Refreshing and Terminating Usages β
Subscription and registration usages expire over time and must be refreshed (with a refresh SUBSCRIBE, for example). This expiration is usage state, not dialog state. If several subscriptions share a dialog, refreshing one of them has no effect on the expiration of the others π.
Normal termination of a usage has no effect on other usages sharing the same dialog. For instance, terminating a subscription with a NOTIFY/Subscription-State: terminated will not terminate an invite usage sharing its dialog. Likewise, ending an invite usage with a BYE does not terminate any active Event: refer subscriptions established on that dialog π.
5.6. Refusing New Usages π ββοΈ
As the survey of the effect of failure responses shows, care must be taken when refusing a new usage inside an existing dialog. Choosing the wrong response code will terminate the dialog and all of its usages π. Generally, returning a 603 Decline is the safest way to refuse a new usage π‘οΈ.
5.7. Replacing Usages π₯
[8] defines a mechanism through which one usage can replace another. It can be used, for example, to associate the two dialogs in which a transfer target is involved during an attended transfer. It is written using the term "dialog", but its intent was only to affect the invite usage of the dialog it targets. Any other usages inside that dialog are unaffected. For some applications, the other usages may no longer make sense, and the application may terminate them as well π€·ββοΈ.
However, the interactions between Replaces and multiple dialog usages have not been well explored. More discussion of this topic is needed. Implementers should avoid this scenario completely π«.
6. Avoiding Multiple Usages π
Processing multiple usages correctly is not completely understood. What is understood is difficult to implement and is very likely to lead to interoperability problems. The best way to avoid the trouble that comes with such complexity is to avoid it altogether π«Ά.
When designing new applications or features that use SIP dialogs, do not require endpoints to construct multiple usages to participate in the application or use the feature. When designing endpoints, address the existing multiple usage scenarios as best as possible. Outside those scenarios, if a peer attempts to create a second usage inside a dialog, refuse it π ββοΈ.
Unfortunately, there are existing applications, like transfer, that currently entail multiple usages, so the simple solution of "don't do it" will require some transitional work. This section looks at the pressures that led to these existing multiple usages and suggests alternatives π§.
When executing a transfer, the transferor and transferee currently share an invite usage and a subscription usage within the dialog between them. This is a result of sending the REFER request within the dialog established by the invite usage. Implementations were led to this behavior by these primary problems:
- There was no way to ensure that a REFER on a new dialog would reach the particular endpoint involved in a transfer. Many factors, including details of implementations and changes in proxy routing between an INVITE and a REFER, could cause the REFER to be sent to the wrong place. Sending the REFER down the existing dialog ensured it got to the same endpoint with which the dialog was established.
- It was unclear how to associate an existing invite usage with a REFER arriving on a new dialog, where it was completely obvious what the association was when the REFER came on the invite usage's dialog.
- There were concerns with authorizing out-of-dialog REFERs. The authorization policy for REFER in most implementations piggybacks on the authorization policy for INVITE (which is, in most cases, based simply on "I placed or answered this call") π.
Globally Routable User Agent (UA) URIs (GRUUs) [9] have been defined specifically to address problem 1 by providing a URI that will reach one specific user-agent π―. The Target-Dialog header field [10] was created to address problems 2 and 3. This header field allows a request to indicate the dialog identifiers of some other dialog, providing association with the other dialog that can be used in an authorization decision β¨.
The Join [11] and Replaces [8] mechanisms can also be used to address problem 1. When using this technique, a new request is sent outside any dialog with the expectation that it will fork to possibly many endpoints, including the one we're interested in. This request contains a header field listing the dialog identifiers of a dialog in progress. Only the endpoint holding a dialog matching those identifiers will accept the request. The other endpoints the request may have forked to will respond with an error. This mechanism is reasonably robust, failing only when the routing logic for out-of-dialog requests changes such that the new request does not arrive at the endpoint holding the dialog of interest π¦.
The reachability aspects of using a GRUU to address problem 1 can be combined with the association-with-other-dialogs aspects of the Join/Replaces and Target-Dialog mechanisms. A REFER request sent out-of-dialog can be sent towards a GRUU, and identify an existing dialog as part of the context the receiver should use. The Target-Dialog header field can be included in the REFER listing the dialog this REFER is associated with. Figure 5 sketches how this could be used to achieve transfer without reusing a dialog πΈ. For simplicity, the diagram and message details do not show the server at example.com that will be involved in routing the GRUU. Refer to [9] for those details π.
Okay bestie, here's the whole transfer glow-up drawn out for you π¦ Peek at Figure 5 first, then we'll go through every message together π
Alice Bob Carol
| | |
| F1 INVITE (Bob's AOR) | |
| Call-ID: (call-id one) | |
| Contact: (Alice's-GRUU) | |
|------------------------------->| |
| F2 200 OK | |
| To: <>;tag=totag1 | |
| From: <>;tag=fromtag1 | |
| Call-ID: (call-id one) | |
| Contact: (Bob's-GRUU) | |
|<-------------------------------| |
| ACK | |
|------------------------------->| |
| : | |
| (Bob places Alice on hold) | |
| : | F3 INVITE (Carol's AOR) |
| | Call-ID: (call-id two) |
| | Contact: (Bob's-GRUU) |
| |----------------------------->|
| | F4 200 OK |
| | To: <>;tag=totag2 |
| | From: <>;tag=fromtag2 |
| | Call-ID: (call-id two) |
| | Contact: (Carol's-GRUU) |
| |<-----------------------------|
| | ACK |
| |----------------------------->|
| | : |
| | (Bob places Carol on hold) |
| F5 REFER (Alice's-GRUU) | : |
| Call-ID: (call-id three) | |
| Refer-To: (Carol's-GRUU) | |
| Target-Dialog: (call-id one,totag1,fromtag1) |
| Contact: (Bob's-GRUU) | |
|<-------------------------------| |
| 202 Accepted | |
|------------------------------->| |
| NOTIFY (Bob's-GRUU) | |
| Call-ID: (call-id three) | |
|------------------------------->| |
| 200 OK | |
|<-------------------------------| |
| | |
| F6 INVITE (Carol's-GRUU) |
| Call-ID: (call-id four) |
| Contact: (Alice's-GRUU) |
|-------------------------------------------------------------->|
| 200 OK |
| Contact: (Carol's-GRUU) |
|<--------------------------------------------------------------|
| ACK |
|-------------------------------------------------------------->|
| | |
| F7 NOTIFY (Bob's-GRUU) | |
| Call-ID: (call-id three) | |
|------------------------------->| |
| 200 OK | |
|<-------------------------------| |
| BYE (Alice's-GRUU) | |
| Call-ID: (call-id one) | |
|<-------------------------------| BYE (Carol's-GRUU) |
| | Call-ID: (call-id two) |
| 200 OK |----------------------------->|
|------------------------------->| 200 OK |
| |<-----------------------------|
| | |
That's Figure 5: Transfer without dialog reuse π
Okay so in message F1, Alice invites Bob and says she supports GRUUs, and she even offers a GRUU for herself π
Message F1 (abridged, detailing pertinent fields)
INVITE sip:bob@example.com SIP/2.0
Call-ID: 13jfdwer230jsdw@alice.example.com
Supported: gruu
Contact: <sip:alice@example.com;gr=urn:uuid:(Alice's UA's bits)>
Message F2 carries Bob's GRUU back to Alice πΈ
Message F2 (abridged, detailing pertinent fields)
SIP/2.0 200 OK
Supported: gruu
To: <sip:bob@example.com>;tag=totag1
From: <sip:alice@example.com>;tag=fromtag1
Contact: <sip:bob@example.com;gr=urn:uuid:(Bob's UA's bits)>
Bob decides he wants to transfer Alice over to Carol π So he puts Alice on hold and sends an INVITE to Carol. Carol and Bob negotiate GRUU support, just like what went down in F1 and F2 π«Ά
Message F3 (abridged, detailing pertinent fields)
INVITE sip:carol@example.com SIP/2.0
Supported: gruu
Call-ID: 23rasdnfoa39i4jnasdf@bob.example.com
Contact: <sip:bob@example.com;gr=urn:uuid:(Bob's UA's bits)>
Message F4 (abridged, detailing pertinent fields)
SIP/2.0 200 OK
Supported: gruu
To: <sip:carol@example.com>;tag=totag2
From: <sip:bob@example.com>;tag=fromtag2
Call-ID: 23rasdnfoa39i4jnasdf@bob.example.com
Contact: <sip:carol@example.com;gr=urn:uuid:(Carol's UA's bits)>
After consulting Carol, Bob places her on hold and refers Alice to her using message F5 π§ Notice that the Refer-To URI is Carol's GRUU, and that it's on a different Call-ID than message F1 π (The URI in the Refer-To header is line-broken for readability in this document; it would not be valid to break the URI this way in a real message.)
Message F5 (abridged, detailing pertinent fields)
REFER sip:aanewmr203raswdf@example.com SIP/2.0
Call-ID: 39fa99r0329493asdsf3n@bob.example.com
Refer-To: <sip:carol@example.com;g=urn:uid:(Carol's UA's bits)
?Replaces=23rasdnfoa39i4jnasdf@bob.example.com;
to-tag=totag2;from-tag=fromtag2>
Target-Dialog: 13jfdwer230jsdw@alice.example.com;
local-tag=fromtag1;remote-tag=totag1
Supported: gruu
Contact: <sip:bob@example.com;gr=urn:uuid:(Bob's UA's bits)>
Alice checks the Target-Dialog header field to figure out that this REFER belongs to the dialog she already has with Bob π Now she can use the same admission policy she used for in-dialog REFERs: "Do I have a call with this person?" She accepts the REFER, sends Bob the obligatory immediate NOTIFY π, and then INVITEs Carol with message F6.
Message F6 (abridged, detailing pertinent fields)
sip:carol@example.com;gr=urn:uuid:(Carol's UA's bits)
\ /
\ /
| |
v v
INVITE SIP/2.0
Call-ID: 4zsd9f234jasdfasn3jsad@alice.example.com
Replaces: 23rasdnfoa39i4jnasdf@bob.example.com;
to-tag=totag2;from-tag=fromtag2
Supported: gruu
Contact: <sip:alice@example.com;gr=urn:uuid:(Alice's UA's bits)>
Carol accepts Alice's invitation to replace her dialog (invite usage) with Bob, and tells him the REFERenced INVITE succeeded with message F7 π
Message F7 (abridged, detailing pertinent fields)
NOTIFY sip:boaiidfjjereis@example.com SIP/2.0
Subscription-State: terminated;reason=noresource
Call-ID: 39fa99r0329493asdsf3n@bob.example.com
Contact: <sip:alice@example.com;gr=urn:uuid:(Alice's UA's bits)>
Content-Type: message/sipfrag
SIP/2.0 200 OK
Then Bob ends his invite usages with both Alice and Carol using BYEs π
7. Security Considerations β¨
Okay, this part is serious, so listen up π₯Ί Handling multiple usages within a single dialog is complex and introduces scenarios where the right thing to do is not clear. The ambiguities described here can result in unexpected disruption of communication if response codes are chosen carelessly. Furthermore, these ambiguities could be exploited, particularly by third-parties injecting unauthenticated requests or inappropriate responses. Implementations choosing to create or accept multiple usages within a dialog should give extra attention to the security considerations in [1], especially those concerning the authenticity of requests and processing of responses.
Service implementations should carefully consider the effects on their service of peers making different choices in these areas of ambiguity. A service that requires multiple usages needs to pay particular attention to the effect on service and network utilization when a client fails to destroy a dialog the service believes should be destroyed. A service that disallows multiple usages should consider the effect on clients that, for instance, destroy the entire dialog when only a usage should be torn down. In the worst case of a service deployed into a network with a large number of misbehaving clients trying to create multiple usages in an automated fashion, a retry storm similar to an avalanche restart could be induced π±
8. Conclusion π
Handling multiple usages within a single dialog is complex and introduces scenarios where the right thing to do is not clear π Implementations should avoid entering into multiple usages whenever possible. New applications should be designed to never introduce multiple usages.
There are some accepted SIP practices, including transfer, that currently require multiple usages. Recent work, most notably GRUU, makes those practices unnecessary β¨ The standardization of those practices and the implementations should be revised as soon as possible to use only single-usage dialogs.
9. Acknowledgments π
The ideas in this document have been refined over several IETF meetings with many participants. Significant contribution was provided by Adam Roach, Alan Johnston, Ben Campbell, Cullen Jennings, Jonathan Rosenberg, Paul Kyzivat, and Rohan Mahy π«Ά Members of the reSIProcate project also shared their difficulties and discoveries while implementing multiple-usage dialog handlers π
10. Informative References β¨
okay bestie, these are the receipts π§Ύ every RFC that SIP leans on, with the full details so you can go find them yourself π
- [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] Levin, O., "Suppression of Session Initiation Protocol (SIP) REFER Method Implicit Subscription", RFC 4488, May 2006. π
- [3] Burger, E. and M. Dolly, "A Session Initiation Protocol (SIP) Event Package for Key Press Stimulus (KPML)", RFC 4730, November 2006. β¨οΈ
- [4] Niemi, A., "Session Initiation Protocol (SIP) Extension for Event State Publication", RFC 3903, October 2004. π£
- [5] Roach, A., "Session Initiation Protocol (SIP)-Specific Event Notification", RFC 3265, June 2002. π
- [6] Rosenberg, J. and H. Schulzrinne, "Session Initiation Protocol (SIP): Locating SIP Servers", RFC 3263, June 2002. πΊοΈ
- [7] Sparks, R., "The Session Initiation Protocol (SIP) Refer Method", RFC 3515, April 2003. π¦
- [8] Mahy, R., Biggs, B., and R. Dean, "The Session Initiation Protocol (SIP) "Replaces" Header", RFC 3891, September 2004. πΈ
- [9] Rosenberg, J., "Obtaining and Using Globally Routable User Agent (UA) URIs (GRUU) in the Session Initiation Protocol (SIP)", Work in Progress, June 2006. π§
- [10] Rosenberg, J., "Request Authorization through Dialog Identification in the Session Initiation Protocol (SIP)", RFC 4538, June 2006. π
- [11] Mahy, R. and D. Petrie, "The Session Initiation Protocol (SIP) "Join" Header", RFC 3911, October 2004. π€
Author's Address π
Robert J. Sparks π Estacado Systems
EMail: RjS@estacado.net π
Full Copyright Statement βοΈ
Copyright (C) The IETF Trust (2007). π
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, THE IETF TRUST 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. β¨
π¦ where this page comes from
- ietf: rfc5057 2007-11
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms