RFC 3725
Best Current Practices for Third Party Call Control (3pcc) in the Session Initiation Protocol (SIP)
RFC 3725 Title Block π
okay bestie, this one is RFC 3725, and it's called Best Current Practices for Third Party Call Control (3pcc) in the Session Initiation Protocol (SIP). It's a Best Current Practice (BCP 85 π ), filed under Category: Best Current Practice, and it came out in April 2004 from the Network Working Group. The authors are J. Rosenberg (dynamicsoft), J. Peterson (Neustar), H. Schulzrinne (Columbia University), and G. Camarillo (Ericsson). The title block doesn't list anything it obsoletes or updates, so it stands on its own β¨
Status of This Memo π
This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements. Distribution of this memo is unlimited.
Copyright Notice Β©οΈ
Copyright (C) The Internet Society (2004). All Rights Reserved.
Abstract π
Third party call control is when one entity can create a call where the actual talking happens between other parties π«Ά SIP can do this with the mechanisms it already has, but there are a few possible approaches, and each one comes with its own pros and cons. This document talks through the best current practices for using SIP for third party call control.
Table of Contents π
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . 3
3. Definitions . . . . . . . . . . . . . . . . . . . . . . . . 3
4. 3pcc Call Establishment . . . . . . . . . . . . . . . . . . 3
4.1. Flow I . . . . . . . . . . . . . . . . . . . . . . . . 4
4.2. Flow II. . . . . . . . . . . . . . . . . . . . . . . . 5
4.3. Flow III . . . . . . . . . . . . . . . . . . . . . . . 7
4.4. Flow IV. . . . . . . . . . . . . . . . . . . . . . . . 8
5. Recommendations . . . . . . . . . . . . . . . . . . . . . . 9
6. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 10
7. Continued Processing . . . . . . . . . . . . . . . . . . . . 11
8. 3pcc and Early Media . . . . . . . . . . . . . . . . . . . . 13
9. Third Party Call Control and SDP Preconditions . . . . . . . 16
9.1. Controller Initiates . . . . . . . . . . . . . . . . . 16
9.2. Party A Initiates. . . . . . . . . . . . . . . . . . . 18
10. Example Call Flows . . . . . . . . . . . . . . . . . . . . . 21
10.1. Click-to-Dial. . . . . . . . . . . . . . . . . . . . . 21
10.2. Mid-Call Announcement Capability . . . . . . . . . . . 23
11. Implementation Recommendations . . . . . . . . . . . . . . . 25
12. Security Considerations. . . . . . . . . . . . . . . . . . . 26
12.1. Authorization and Authentication . . . . . . . . . . . 26
12.2. End-to-End Encryption and Integrity. . . . . . . . . . 27
13. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 28
14. References . . . . . . . . . . . . . . . . . . . . . . . . . 28
14.1. Normative References . . . . . . . . . . . . . . . . . 28
14.2. Informative References . . . . . . . . . . . . . . . . 29
15. Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 30
16. Full Copyright Statement . . . . . . . . . . . . . . . . . . 31
1. Introduction π¦
Okay so in the old-school phone world, third party call control lets one entity (we call it the controller) set up and manage a communication relationship between two or more other parties. It's super common for operator services (where an operator makes a call that connects two people) and for conferencing π
SIP has a ton of services that do this too. Some are the classic PSTN ones, but there are new ones as well, like click-to-dial πΈ With click-to-dial, a user clicks something on a web page when they want to talk to a customer service rep. The web server then sets up the call between the user and the rep. The call can be between two phones, a phone and an IP host, or two IP hosts. Iconic π
Third party call control is possible using only the mechanisms in RFC 3261 [1]. Honestly, lots of different call flows are possible, and each one works with SIP compliant user agents. But every flow has its own benefits and drawbacks β¨ It also gets more complicated when the call uses SIP extensions or optional SIP features. For example, using RFC 3312 [2] (which is for coupling signaling to resource reservation) with third party call control is non-trivial, and Section 9 covers that π Early media (where session data gets exchanged before the call is accepted) is also not trivial with third party call control. Both of these features define how user agents generate and respond to SDP, and it isn't clear how to do both at the same time. Section 8 digs into that π«Ά
This document is the best current practice for doing third party call control without using any extensions made specifically for it. Section 4 presents the known call flows you can use for third party call control, plus guidance on using them. Section 9 covers how RFC 3312 [2] interacts with third party call control. Section 8 covers how early media interacts with third party call control. Section 10 gives example applications that use the flows recommended here π
2. Terminology π
In this document, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in RFC 2119 [3] and indicate requirement levels for compliant implementations.
3. Definitions π
These are the terms we use all throughout this document:
- 3pcc: Third Party Call Control, which means the general ability to manipulate calls between other parties.
- Controller: A controller is a SIP User Agent that wants to create a session between two other user agents.
4. 3pcc Call Establishment π§
The main primitive operation of third party call control is setting up a session between participants A and B. A third party, called the controller, orchestrates that session setup π
This section documents three call flows the controller can use to give you this primitive operation. (Okay, it's actually four flows once you count the ones coming up in 4.2 through 4.4, but this section documents them all, so we're good π)
4.1. Flow I π
A Controller B
|(1) INVITE no SDP | |
|<------------------| |
|(2) 200 offer1 | |
|------------------>| |
| |(3) INVITE offer1 |
| |------------------>|
| |(4) 200 OK answer1 |
| |<------------------|
| |(5) ACK |
| |------------------>|
|(6) ACK answer1 | |
|<------------------| |
|(7) RTP | |
|.......................................|
Figure 1
Here's how Flow I goes, and Figure 1 has the whole picture π The controller starts by sending an INVITE to A (1). This INVITE has no session description in it. A's phone rings, and A picks up. That gets you a 200 OK (2) that contains an offer [4]. The controller has to send its answer in the ACK, as [1] requires π So it takes the offer it got from A (offer1) and sends it in an INVITE to B (3). B's phone rings. When B answers, the 200 OK (4) carries the answer to that offer, which is answer1. The controller sends an ACK to B (5), and then passes answer1 over to A in an ACK sent to A (6). Since A generated the offer and B generated the answer, the actual media session is between A and B. So media flows straight between them (7) π«Ά
Flow I is simple π₯° It doesn't need the controller to touch the SDP at all, and it works for any media types that both endpoints support. BUT (and this is a big but π) it has a serious timeout problem. User B might not answer the call right away. Then the controller can't send the ACK to A right away either. That makes A keep retransmitting the 200 OK periodically. As RFC 3261 Section 13.3.1.4 says, the 200 OK gets retransmitted for 64*T1 seconds. If the ACK doesn't show up by then, the call is considered failed. So this flow only really works when the controller knows B is going to answer the INVITE immediately π
4.2. Flow II β¨
A Controller B
|(1) INVITE bh sdp1 | |
|<------------------| |
|(2) 200 sdp2 | |
|------------------>| |
| |(3) INVITE sdp2 |
| |------------------>|
|(4) ACK | |
|<------------------| |
| |(5) 200 OK sdp3 |
| |<------------------|
| |(6) ACK |
| |------------------>|
|(7) INVITE sdp3 | |
|<------------------| |
|(8) 200 OK sdp2 | |
|------------------>| |
|(9) ACK | |
|<------------------| |
|(10) RTP | |
|.......................................|
Figure 2
Okay bestie, Flow II π¦ is where things get a little more chaotic. The controller first sends an INVITE to user A (1). It's a standard INVITE with an offer (sdp1) that has a single audio media line, one codec, a random port number (but not zero), and a connection address of 0.0.0.0. This creates an initial media stream that's basically "black holed", because no media (or RTCP packets [8]) will flow from A. And that INVITE makes A's phone ring π
Note that the usage of0.0.0.0, though recommended by RFC 3264, has numerous drawbacks. It is anticipated that a future specification will recommend usage of a domain within the.invalidDNS top level domain instead of the0.0.0.0IP address. As a result, implementors are encouraged to track such developments once they arise. π
When A answers (2), the 200 OK has an answer, sdp2, with a valid address in the connection line. The controller sends an ACK (4). Then it generates a second INVITE (3), addressed to user B, containing sdp2 as the offer to B. Heads up: the role of sdp2 just flipped! In the 200 OK (message 2) it was an answer, but in the INVITE it's an offer. Lucky for us, all valid answers are valid initial offers β¨ This INVITE makes B's phone ring. When B answers, it sends a 200 OK (5) with an answer, sdp3. The controller then generates an ACK (6). Next it sends a re-INVITE to A (7) containing sdp3 as the offer. Roles reversed again! sdp3 was an answer and is now an offer. An answer to an answer recast as an offer is, in turn, a valid offer, so we're still good π This re-INVITE generates a 200 OK (8) with sdp2, assuming A doesn't decide to change any aspects of the session because of it. That 200 OK gets ACKed (9), and then media can flow from A to B. Media from B to A could already start flowing once message 5 was sent π
This flow has the advantage that all final responses are immediately ACKed, so it doesn't suffer from the timeout and message inefficiency problems of flow 1 π
But it still has troubles, bestie. First off, it requires that the controller know the media types used for the call, since it has to generate a "blackhole" SDP, and that needs media lines. Secondly, the first INVITE to A (1) contains media with a 0.0.0.0 connection address. The controller expects the response to contain a valid, non-zero connection address for A. Here's the tea: experience has shown that many UAs respond to an offer of a 0.0.0.0 connection address with an answer that also has a 0.0.0.0 connection address. The offer-answer specification [4] explicitly tells implementors not to do this, but when this document was published, many implementations still did π If A responds with a 0.0.0.0 connection address in sdp2, the flow won't work.
But the most serious flaw π is the assumption that the 200 OK to the re-INVITE (message 8) contains the same SDP as in message 2. That might not be the case. If it isn't, the controller needs to re-INVITE B with that SDP (say, sdp4), which may get a different SDP, sdp5, in the 200 OK from B. Then the controller needs to re-INVITE A again, and so on. The result is an infinite loop of re-INVITEs. It's possible to break this cycle with very smart UAs that can return the same SDP whenever possible, or really smart controllers that can analyze the SDP to determine if a re-INVITE is really needed. However, we wish to keep this mechanism simple and avoid SDP awareness in the controller. So this flow is not really workable. It is therefore NOT RECOMMENDED π«
4.3. Flow III π§
A Controller B
|(1) INVITE no SDP | |
|<---------------------| |
|(2) 200 offer1 | |
|--------------------->| |
|(3) ACK answer1 (bh) | |
|<---------------------| |
| |(4) INVITE no SDP |
| |--------------------->|
| |(5) 200 OK offer2 |
| |<---------------------|
|(6) INVITE offer2' | |
|<---------------------| |
|(7) 200 answer2' | |
|--------------------->| |
| |(8) ACK answer2 |
| |--------------------->|
|(9) ACK | |
|<---------------------| |
|(10) RTP | |
|.............................................|
Figure 3
A third flow, Flow III πΈ, is shown in Figure 3. First, the controller sends an INVITE (1) to user A without any SDP at all. That's good, because it means the controller doesn't need to assume anything about the media composition of the session π A's phone rings. When A answers, a 200 OK gets generated (2) containing its offer, offer1. The controller generates an immediate ACK containing an answer (3). This answer is a "black hole" SDP with its connection address equal to 0.0.0.0.
The controller then sends an INVITE to B without SDP (4), which makes B's phone ring. When they answer, a 200 OK is sent containing their offer, offer2 (5). This SDP is used to create a re-INVITE back to A (6). That re-INVITE is based on offer2, but it may need to be reorganized to match up media lines, or to trim media lines. For example, if offer1 contained an audio and a video line, in that order, but offer2 contained just an audio line, the controller would need to add a video line to the offer (setting its port to zero) to create offer2'. Since this is a re-INVITE, it should complete quickly in the general case. That's good, since user B is retransmitting their 200 OK while waiting for an ACK β³ The SDP in the 200 OK (7) from A, answer2', may also need to be reorganized or trimmed before it's sent along to B in the ACK (8) as answer2. Finally, an ACK is sent to A (9), and then media can flow π
This flow has many benefits π First, it will usually operate without any spurious retransmissions or timeouts (although this may still happen if a re-INVITE is not responded to quickly). Secondly, it does not require the controller to guess the media that will be used by the participants.
There are some drawbacks, though π₯Ί The controller does need to perform SDP manipulations. Specifically, it must take some SDP and generate another SDP which has the same media composition but has connection addresses equal to 0.0.0.0. This is needed for message 3. Secondly, it may need to reorder and trim SDP X so that its media lines match up with those in some other SDP, Y. Thirdly, the offer from B (offer2) may have no codecs or media streams in common with the offer from A (offer1). The controller will need to detect this condition and terminate the call. Finally, the flow is far more complicated than the simple and elegant Flow I (Figure 1) π
4.4. Flow IV π
A Controller B
|(1) INVITE offer1 | |
|no media | |
|<---------------------| |
|(2) 200 answer1 | |
|no media | |
|--------------------->| |
|(3) ACK | |
|<---------------------| |
| |(4) INVITE no SDP |
| |--------------------->|
| |(5) 200 OK offer2 |
| |<---------------------|
|(6) INVITE offer2' | |
|<---------------------| |
|(7) 200 answer2' | |
|--------------------->| |
| |(8) ACK answer2 |
| |--------------------->|
|(9) ACK | |
|<---------------------| |
|(10) RTP | |
|.............................................|
Figure 4
Flow IV π shows a variation on Flow III that reduces its complexity. The actual message flow is identical, but the SDP placement and construction is different. The initial INVITE (1) contains SDP with no media at all, meaning there are no m lines. This is valid, and it implies that the media makeup of the session will be established later through a re-INVITE [4]. Once the INVITE is received, user A is alerted. When they answer, the 200 OK (2) has an answer with no media either. The controller acknowledges this (3). From this point onwards the flow is identical to Flow III. However, the manipulations needed to convert offer2 to offer2', and answer2' to answer2, are much simpler. Indeed, no media manipulations are needed at all. The only change needed is to modify the origin lines, so that the origin line in offer2' is valid based on the value in offer1 (validity requires that the version increments by one, and that the other parameters remain unchanged) β¨
There are some limitations, though π First, user A will be alerted without any media having been established yet. This means user A won't be able to reject or accept the call based on its media composition. Secondly, both A and B will end up answering the call (i.e., generating a 200 OK) before it is known whether there is compatible media. If there is no media in common, the call can be terminated later with a BYE. However, the users will already have been alerted, resulting in user annoyance and possibly resulting in billing events πΈ
5. Recommendations β¨
okay so bestie, Flow I (Figure 1) is the simplest and most efficient flow π¦ It is the one a controller SHOULD use when it knows with certainty that user B is actually an automata that will answer the call immediately π€ That is the case for things like media servers, conferencing servers, and messaging servers, for example π Since we expect a LOT of third party call control to go to automata, special casing for that scenario is totally reasonable π₯
For calls to unknown entities, or to entities known to represent people, it is RECOMMENDED that Flow IV (Figure 4) be used for third party call control π Flow III MAY be used instead, but it gives you no extra benefits over Flow IV, so why would you π However, Flow II SHOULD NOT be used, because of the potential for infinite ping-ponging of re-INVITEs π literally a nightmare loop, no thank you π
Several of these flows use a "black hole" connection address of 0.0.0.0 π³οΈ This is an IPv4 address with the property that packets sent to it will never leave the host which sent them; they are just discarded ποΈ So those flows are specific to IPv4 πΈ For other network or address types, an address with an equivalent property SHOULD be used β¨
In most cases, including the recommended flows, user A will hear silence while the call to B completes π€« This may not always be ideal, ngl π₯Ί It can be fixed by connecting the caller to a music-on-hold source while the call to B occurs πΆ main character energy for the caller, honestly π
6. Error Handling π¨
There are numerous error cases which merit discussion, so let's get into it π
With all of the call flows in Section 4, one call is established to A, and then the controller attempts to establish a call to B π However, this call attempt may fail for any number of reasons π¬ User B might be busy (resulting in a 486 response to the INVITE), there may not be any media in common, the request may time out, and so on π If the call attempt to B fails, it is RECOMMENDED that the controller send a BYE to A π This BYE SHOULD include a Reason header [5] which carries the status code from the error response π«Ά That way A knows the precise reason for the failure, which is super important from a user interface perspective β¨ For example, if A was calling from a black phone and B generated a 486, the BYE will contain a Reason code of 486, and this could be used to generate a local busy signal so that A knows B is busy π΅
A Controller B
|(1) INVITE offer1 | |
|no media | |
|<---------------------| |
|(2) 200 answer1 | |
|no media | |
|--------------------->| |
|(3) ACK | |
|<---------------------| |
| |(4) INVITE no SDP |
| |--------------------->|
| |(5) 180 |
| |<---------------------|
|(6) INVITE offer2 | |
|--------------------->| |
|(7) 491 | |
|<---------------------| |
|(8) ACK | |
|--------------------->| |
Figure 5
Another error condition worth discussing is shown in Figure 5 π After the controller establishes the dialog with A (messages 1-3), it attempts to contact B (message 4) π² Contacting B may take some time, and during that interval A could possibly attempt a re-INVITE, providing an updated offer π³ However, the controller cannot pass this offer on to B, since it has an INVITE transaction pending with it π« As a result, the controller needs to reject the request π ββοΈ It is RECOMMENDED that a 491 response be used π The situation is similar to the glare condition described in [1], so the same error handling is sensible π€ However, A is likely to retry its request (as a result of the 491), and this may happen before the exchange with B is completed π© In that case, the controller would respond with another 491 π
7. Continued Processing π¦
Once the calls are established, both participants believe they are in a single point-to-point call π«’ However, they are exchanging media directly with each other, rather than with the controller π‘ The controller is involved in two dialogs, yet it sees no media π
Since the controller is still a central point for signaling, it now has complete control over the call π If it receives a BYE from one of the participants, it can create a new BYE and hang up with the other participant π΄ This is shown in Figure 6 π
A Controller B
|(1) BYE | |
|------------------>| |
|(2) 200 OK | |
|<------------------| |
| |(3) BYE |
| |------------------>|
| |(4) 200 OK |
| |<------------------|
Figure 6
Similarly, if it receives a re-INVITE from one of the participants, it can forward it to the other participant π Depending on which flow was used, this may require some manipulation of the SDP before passing it on π οΈ
However, the controller does not need to "proxy" the SIP messages received from one of the parties π ββοΈ Since it is a Back-to-Back User Agent (B2BUA), it can invoke any signaling mechanism on each dialog, as it sees fit π§ For example, if the controller receives a BYE from A, it can generate a new INVITE to a third party, C, and connect B to that participant instead π A call flow for this is shown in Figure 7, assuming the case where C represents an end user, not an automata πββοΈ Note that it is just Flow IV β¨
A Controller B C
|(1) BYE | | |
|--------------->| | |
|(2) 200 OK | | |
|<---------------| | |
| |(3) INV no media| |
| |-------------------------------->|
| |(4) 200 no media| |
| |<--------------------------------|
| |(5) ACK | |
| |-------------------------------->|
| |(6) INV no SDP | |
| |--------------->| |
| |(7) 200 offer3 | |
| |<---------------| |
| |(8) INV offer3' | |
| |-------------------------------->|
| |(9) 200 answer3'| |
| |<--------------------------------|
| |(10) ACK | |
| |-------------------------------->|
| |(11) ACK answer3| |
| |--------------->| |
| | |(12) RTP |
| | |................|
Figure 7
From here, new parties can be added, removed, transferred, and so on, as the controller sees fit π In many cases, the controller will need to modify the SDP exchanged between the participants to make these changes happen π In particular, the version number in the SDP will need to be changed by the controller in certain cases π’ If the controller issues an SDP offer on its own (for example, to place a call on hold), it will need to increment the version number in the SDP offer π The other participant in the call will not know that the controller did this, so any subsequent offer it generates will have the wrong version number as far as its peer is concerned π΅βπ« As a result, the controller will be required to modify the version number in SDP messages to match what the recipient is expecting π§Ύ
It is important to point out that the call need not have been established by the controller in order for this section's processing to be used πββοΈ Rather, the controller could have acted as a B2BUA during a call established by A towards B (or vice versa) π«Ά
8. 3pcc and Early Media β¨
okay so early media is when the session is already set up (the offer/answer dance is finished π), but the call hasn't actually been accepted yet π. it's usually there for tones or announcements about how the call is going π. honestly, handling early media in a third party call is super straightforward π«Ά
A Controller B
| | |
|(1) INVITE offer1 | |
|no media | |
|<---------------------| |
| | |
|<ring> | |
| | |
|<answer> | |
| | |
|(2) 200 answer1 | |
|no media | |
|--------------------->| |
|(3) ACK | |
|<---------------------| |
| |(4) INVITE no SDP |
| |--------------------->|
| | |<ring>
| |(5) 183 offer2 |
| |<---------------------|
|(6) INVITE offer2' | |
|<---------------------| |
|(7) 200 answer2' | |
|--------------------->| |
|(8) ACK | |
|<---------------------| |
| |(9) PRACK answer2 |
| |--------------------->|
| |(10) 200 PRACK |
| |<---------------------|
|(11) RTP | |
|.............................................|
| | |<answer>
| |(12) 200 OK |
| |<---------------------|
| |(13) ACK |
| |--------------------->|
Figure 8
so Figure 8 is the case where user B makes early media before picking up π§ and honestly it's giving almost identical to Flow IV from Figure 4 π the only real difference is that B sends a reliable provisional response (5) [6] instead of a final response, and answer2 rides along in a PRACK (9) instead of an ACK π when B finally accepts the call (12), nothing changes in the session state, so there's no signaling to do with user A π the controller just ACKs the 200 OK (13) to confirm the dialog, and we're done β¨
A Controller B
| | |
|(1) INVITE offer1 | |
|no media | |
|<---------------------| |
| | |
|ring | |
| | |
|(2) 183 answer1 | |
|no media | |
|--------------------->| |
|(3) PRACK | |
|<---------------------| |
|(4) 200 PRACK | |
|--------------------->| |
| |(5) INVITE no SDP |
| |--------------------->|
| | |ring
| | |
| | |answer
| | |
| |(6) 200 OK offer2 |
| |<---------------------|
|(7) UPDATE offer2' | |
|<---------------------| |
| | |
|(8) 200 answer2' | |
|--------------------->| |
| |(9) ACK answer2 |
| |--------------------->|
|(10) RTP | |
|.............................................|
| | |
|answer | |
| | |
|(11) 200 OK | |
|--------------------->| |
|(12) ACK | |
|<---------------------| |
Figure 9
now the case where user A makes early media is the messy one π it's shown in Figure 9 and it's based on Flow IV π the controller sends an INVITE to user A (1) with an offer that has no media streams π«₯ user A sends back a reliable provisional response (2) with an answer that also has no media streams, and the controller PRACKs it (3) π¨ then the controller sends an INVITE without SDP to user B (5) π B's phone rings, they pick up, and you get a 200 OK (6) carrying an offer, offer2 π₯Ή
here's the tricky part: the controller needs to update the session parameters with user A, but the call hasn't been answered yet, so it can't use a re-INVITE π ββοΈ instead it uses a SIP UPDATE request (7) [7] and passes along the offer, after tweaking it so the origin field is correct π οΈ user A puts its answer in the 200 OK to the UPDATE (8), and that answer gets handed to user B inside the ACK (9) π when user A finally answers (11), nothing changes in the session state, so the controller just ACKs the 200 OK (12) and bestie, we're finished π
ngl there's likely going to be some clipping of media in this call flow π user A is likely a PSTN gateway, and it made a provisional response because of early media coming in from the PSTN side π‘ the PSTN will deliver that media anyway, even though the gateway has nowhere to send it, because the controller's initial offer had no media streams π¬ when user B answers, media can start flowing πΆ but any media the PSTN sent the gateway before that point is gone forever π
9. Third Party Call Control and SDP Preconditions π§
okay so there's a SIP extension that lets signaling and resource reservation get coupled together [2] π this spec depends on session descriptions getting exchanged before the call setup is complete π€― those flows kick off when certain SDP parameters show up in the initial INVITE π which means how this mechanism plays with third party call control isn't obvious at all, so it's totally worth walking through π
9.1. Controller Initiates π
okay so in this scenario the controller wants to use preconditions to dodge those call failure scenarios from Section 4.4 π. the big goal is that neither party gets alerted unless there's a common set of media and codecs π. it can also show both people the media makeup of the call before they decide to pick up β¨
User A Controller Customer Service
(User B)
| | |
|(1) INVITE no SDP | |
|require precon | |
|<------------------| |
|(2) 183 offer1 | |
|optional precon | |
|------------------>| |
| | |
| |(3) INVITE offer1 |
| |------------------>|
| | |
| | |
| | |<answer>
| |(4) 200 OK answer1 |
| |no precon |
| |<------------------|
| |(5) ACK |
| |------------------>|
|(6) PRACK answer1 | |
|<------------------| |
|<ring> | |
| | |
|(7) 200 PRACK | |
|------------------>| |
|<answer> | |
| | |
|(8) 200 INVITE | |
|------------------>| |
|(9) ACK | |
|<------------------| |
Figure 10
the flow for this one is shown in Figure 10 π¦. we're assuming user B is an automata or agent of some sort that answers the call immediately, so the flow is based on Flow I π€. the controller sends an INVITE to user A with no SDP, but with a Require header saying preconditions are required. this exact combo (an INVITE without an offer but with a Require header for preconditions) is not described in [2] π. it is RECOMMENDED that the UAS respond with an offer in a 1xx that includes the media streams it wants to use for the call, and that it lists all the preconditions it supports as optional for each one. the user is obviously not alerted at this point π€«. the controller takes this offer and passes it to user B (3). user B doesn't support preconditions, or does but isn't interested in them, so when it answers, the 200 OK has an answer with no preconditions listed (4) π. that answer gets passed to user A in the PRACK (6). so user A knows there are no preconditions actually in use for the call, and therefore it can alert the user π. when the call is answered, user A sends a 200 OK to the controller (8) and the call is complete π
in the event that the offer generated by user A wasn't acceptable to user B (because of non-overlapping codecs or media, for example), user B would immediately reject the INVITE (message 3) π¬. the controller would then CANCEL the request to user A. in this situation, neither user A nor user B would have been alerted, which is the desired effect π. it's kind of iconic that this property is achieved using preconditions even though it doesn't matter what specific types of preconditions are supported by user A π§
it's also totally possible that user B actually does want preconditions π. in that case it might generate a 1xx of its own with an answer containing preconditions. that answer would still be passed to user A, and both parties would proceed with whatever measures are necessary to meet the preconditions. neither user would be alerted until the preconditions were met π
9.2. Party A Initiates β¨
Okay so in Section 9.1, the controller asked for preconditions because it had a specific goal in mind π―. But here's the twist: the controller doesn't have to care about preconditions at all (maybe it doesn't even know what they are π). One of the participants in the call might still care, though, and that's what this flow is about. Figure 11 shows the call flow for this case π .
A Controller B
|(1) INVITE offer1 | |
|no media | |
|<---------------------| |
|(2) 183 answer1 | |
|no media | |
|--------------------->| |
|(3) PRACK | |
|<---------------------| |
|(4) 200 OK | |
|--------------------->| |
| |(5) INVITE no SDP |
| |--------------------->|
| |(6) 183 offer2 |
| |des=sendrecv |
| |conf=recv |
| |cur=none |
| |<---------------------|
|(7) UPDATE offer2' | |
|des=sendrecv | |
|conf=recv | |
|cur=none | |
|<---------------------| |
|(8) 200 UPDATE | |
|answer2' | |
|des=sendrecv | |
|conf=recv | |
|cur=none | |
|--------------------->| |
| |(9) PRACK answer2 |
| |des=sendrecv |
| |conf=recv |
| |cur=none |
| |--------------------->|
| |(10) 200 PRACK |
| |<---------------------|
|(11) reservation | |
|-------------------------------------------->|
|(12) reservation | |
|<--------------------------------------------|
|(13) UPDATE offer3 | |
|des=sendrecv | |
|conf=recv | |
|cur=recv | |
|--------------------->| |
| |(14) UPDATE offer3' |
| |des=sendrecv |
| |conf=recv |
| |cur=recv |
| |--------------------->|
| |(15) 200 UPDATE |
| |answer3' |
| |des=sendrecv |
| |conf=recv |
| |cur=send |
| |<---------------------|
|(16) 200 UPDATE | |
|answer3 | |
|des=sendrecv | |
|conf=recv | |
|cur=send | |
|<---------------------| |
| | |<ring>
| |(17) UPDATE offer4 |
| |des=sendrecv |
| |conf=recv |
| |cur=sendrecv |
| |<---------------------|
|(18) UPDATE offer4' | |
|des=sendrecv | |
|conf=recv | |
|cur=sendrecv | |
|<---------------------| |
|<ring> | |
|(19) 200 UPDATE | |
|answer4' | |
|des=sendrecv | |
|conf=recv | |
|cur=sendrecv | |
|--------------------->| |
| |(20) 200 UPDATE |
| |answer4 |
| |des=sendrecv |
| |conf=recv |
| |cur=sendrecv |
| |--------------------->|
|(21) 180 INVITE | |
|--------------------->| |
| |(22) 180 INVITE |
| |<---------------------|
|<answer> | |
|(23) 200 INVITE | |
|--------------------->| |
|(24) ACK | |
|<---------------------| |
| | |<answer>
| |(25) 200 INVITE |
| |<---------------------|
| |(26) ACK |
| |--------------------->|
Figure 11
The controller follows Flow IV π§, since it has no specific requirements for support of the preconditions specification [2]. So it sends an INVITE (1) with SDP that has no media lines. User A wants preconditions and doesn't want its phone ringing until resources are reserved ππ«. There are no media streams in that INVITE, so it can't reserve anything for them, which means it can't ring the phone until media shows up in a later offer and gets reserved. A generates a 183 with the answer and doesn't alert the user (2). The controller sends PRACK for this (3), and A responds to that PRACK (4). Bestie, A is patient π₯Ή.
Now the controller tries to bring B into the call. It sends B an INVITE without SDP (5). B wants preconditions for this call too, so it generates its offer in a 183 containing the right SDP attributes (6). The controller passes that offer to A in an UPDATE request (7). It uses UPDATE and not a re-INVITE because the call hasn't been answered yet π. User A sees that its peer can handle preconditions, and since it wants them, it answers with a 200 OK to the UPDATE (8). That answer gets passed to B inside the PRACK for the provisional response (9) β¨.
Both sides now do resource reservation. A finishes first and sends an updated session description in an UPDATE request (13). The controller just passes it along to B (after changing the origin field, as Flow IV requires) in an UPDATE (14), and B's answer (15) comes back to A (16). The same thing happens in reverse, from B to A, when B's reservation succeeds (17-20) π. Once the preconditions are met, both sides ring (21 and 22), and then both answer (23 and 25) to complete the call ππ₯.
The big takeaway: the controller doesn't know anything about preconditions π«£. It just passes the SDP back and forth as needed. The trick is usingUPDATEandPRACKto carry the SDP at the right moments, and that decision is made entirely by the offer/answer rules in [6] and [7], totally independent of preconditions. Iconic, honestly π.
10. Example Call Flows π
10.1. Click-to-Dial π
okay so the first app we're looking at is click-to-dial π picture this: a user is browsing an e-commerce site and wants to talk to a customer service rep. they click a link, a call gets placed to the rep, and when the rep picks up, the phone on the user's desk rings. the user picks up and the rep is right there, ready to chat π«Ά
Customer Service Controller User's Phone User's Browser
| |(1) HTTP POST | |
| |<--------------------------------------|
| |(2) HTTP 200 OK | |
| |-------------------------------------->|
|(3) INVITE offer1 | | |
|no media | | |
|<------------------| | |
|(4) 200 answer1 | | |
|no media | | |
|------------------>| | |
|(5) ACK | | |
|<------------------| | |
| |(6) INVITE no SDP | |
| |------------------>| |
| |(7) 200 OK offer2 | |
| |<------------------| |
|(8) INVITE offer2' | | |
|<------------------| | |
|(9) 200 answer2' | | |
|------------------>| | |
| |(10) ACK answer2 | |
| |------------------>| |
|(11) ACK | | |
|<------------------| | |
|(12) RTP | | |
|.......................................| |
Figure 12
so the call flow for this one is in Figure 12, and it's literally identical to Figure 4 β¨ the only difference is the whole thing kicks off with an HTTP POST when the user clicks the link. normally that POST doesn't carry either number π the user's number usually comes from back-end databases, since they've presumably logged into the site and the server already has that context. the customer service number usually comes from provisioning. so the HTTP POST is really just the server going "yep, a call is wanted" π
we should also note that this service can be done through other mechanisms, namely PINT [9]. however, there are a bunch of differences between how PINT does it and how it's done here π
- β¨ The PINT solution enables calls only between two PSTN endpoints. The solution described here allows calls between PSTN phones (through SIP enabled gateways) and native IP phones.
- π When used for calls between two PSTN phones, the solution here may result in a portion of the call being routed over the Internet. In PINT, the call is always routed only over the PSTN. This may result in better quality calls with the PINT solution, depending on the codec in use and QoS capabilities of the network routing the Internet portion of the call.
- π§© The PINT solution requires extensions to SIP (PINT is an extension to SIP), whereas the solution described here is done with baseline SIP.
- π The PINT solution allows the controller (acting as a PINT client) to "step out" once the call is established. The solution described here requires the controller to maintain call state for the entire duration of the call.
10.2. Mid-Call Announcement Capability ποΈ
the third party call control mechanism we've been talking about can also do mid-call announcements π¦ let's say we're running a pre-paid calling card service. once the pre-paid call is up, the system sets a timer to fire when the user runs out of minutes. when that timer fires, the user hears an announcement telling them to enter a credit card to keep going. once they punch in the card info, more money gets added to the pre-paid card, and the user gets reconnected to the destination party π°
here we're only using third party call control for playing the mid-call dialog that collects the credit card info π€
Pre-Paid User Controller Called Party Media Server
| |(1) INV SDP c=bh | |
| |------------------>| |
| |(2) 200 answer1 | |
| |<------------------| |
| |(3) ACK | |
| |------------------>| |
|(4) INV no SDP | | |
|<------------------| | |
|(5) 200 offer2 | | |
|------------------>| | |
| |(6) INV offer2 | |
| |-------------------------------------->|
| |(7) 200 answer2 | |
| |<--------------------------------------|
|(8) ACK answer2 | | |
|<------------------| | |
| |(9) ACK | |
| |-------------------------------------->|
|(10) RTP | | |
|...........................................................|
| |(11) BYE | |
| |-------------------------------------->|
| |(12) 200 OK | |
| |<--------------------------------------|
| |(13) INV no SDP | |
| |------------------>| |
| |(14) 200 offer3 | |
| |<------------------| |
|(15) INV offer3' | | |
|<------------------| | |
|(16) 200 answer3' | | |
|------------------>| | |
| |(17) ACK answer3' | |
| |------------------>| |
|(18) ACK | | |
|<------------------| | |
|(19) RTP | | |
|.......................................| |
Figure 13
we assume the call is set up so the controller is in the middle as a B2BUA π§ when the timer fires, we want to connect the caller to a media server, and the flow for that is in Figure 13. the controller places the called party with a connection address of 0.0.0.0 (1), which effectively "disconnects" them. then the controller sends an INVITE without SDP to the pre-paid caller (4). the offer that comes back from the caller (5) gets used in an INVITE to the media server that's going to collect the digits (6). this is an instantiation of Flow I, and it only works here because the media server is an automata that answers the INVITE immediately. if the controller were connecting the pre-paid user with another end user, Flow III would be needed instead π ββοΈ the media server sends back an immediate 200 OK (7) with an answer, which gets passed to the caller in an ACK (8). end result: the media server and the pre-paid caller have their media streams connected πΆ
the media server plays the announcement and prompts the user to enter a credit card number. after collecting the number, the card number gets validated. the media server then passes the card number to the controller (using some means outside the scope of this specification), and then hangs up the call (11) π³
after hanging up with the media server, the controller reconnects the user to the original called party. to do that, the controller sends an INVITE without SDP to the called party (13). the 200 OK (14) contains an offer, offer3. the controller modifies the SDP (the same way it's done in Flow III) and passes the offer in an INVITE to the pre-paid user (15). the pre-paid user generates an answer in a 200 OK (16), which the controller passes to user B in the ACK (17). at this point, the caller and called party are reconnected π₯°
11. Implementation Recommendations π οΈ
most of the work for third party call control happens in the controller π a standard SIP UA should be controllable using the mechanisms described here. BUT third party call control leans on a few features that might not be implemented, so we RECOMMEND that implementors of user agent servers support the following:
- Offers and answers that contain a connection line with an address of 0.0.0.0.
- Re-INVITE requests that change the port to which media should be sent
- Re-INVITEs that change the connection address
- Re-INVITEs that add a media stream
- Re-INVITEs that remove a media stream (setting its port to zero)
- Re-INVITEs that add a codec amongst the set in a media stream
- SDP Connection address of zero
- Initial INVITE requests with a connection address of zero
- Initial INVITE requests with no SDP
- Initial INVITE requests with SDP but no media lines
- Re-INVITEs with no SDP
- The UPDATE method [7]
- Reliability of provisional responses [6]
- Integration of resource management and SIP [2].
12. Security Considerations π
12.1. Authorization and Authentication β¨
Okay so most of the time, whether a SIP INVITE gets a yes or a no comes down to a human looking at info about the call, like who's calling π. Other times an automaton picks up, and whether it answers can depend on the app. Like if you ring a voice portal, it might bounce you unless you signed up earlier (maybe on a website) π. Call handling can also run on automated scripts, like the ones in the Call Processing Language [11]. And ngl, those decisions are often based on who the caller is π«Ά
These authorization checks apply to regular first party calls and third party calls, because from the outside they look exactly the same π. So it's super important that the policies keep working for third party calls. But third party calls add a plot twist: the one who starts the third party call π³. Should the policies look at that person's identity, or at the people actually on the call? Ideally everyone would know both other parties' identities, and policies could use those as needed. Sadly, that's not doable with current mechanisms π. So the next best thing is for the INVITE requests to carry the identity of the third party. That's the person who's actually asking for the communication, so it makes total sense for call policies to key off them π₯
That means the controller has to authenticate itself as that third party. It can be tricky, and the right method depends on the scenario π₯Ί
In one common setup, the controller is acting for one of the participants. Click-to-dial is the classic example, where the controller and the customer service rep live in the same admin domain πββοΈ. For identification purposes, the controller can legitimately claim to be the customer service rep β¨. So the INVITE to the end user should have a From field identifying the CSR, and the request gets authenticated with S/MIME (see RFC 3261 [1], Section 23) signed with the CSR's key, which the controller holds π
But that needs the controller to actually have credentials to pose as the CSR. In lots of other cases, the controller represents a participant but doesn't have their credentials, and sadly there are no standard ways for a user to delegate credentials to a controller in a way that's limited to specific third party call control operations π©. Without that, the best we've got is using the display name in the From field to show whose behalf the call is on. It is RECOMMENDED that the display name be set to "[controller] on behalf of [user]", where user and controller are textual identities of the user and controller, respectively. In that case, the URI in the From field identifies the controller π
In other situations, the controller and the participants have no real relationship at all. Ideally, the controller would be able to assert that the call comes from a particular identity (which could be one of the participants, or even a third party, depending on the app), and validate that assertion with a signature using the controller's key π§
12.2. End-to-End Encryption and Integrity π
Here's the thing: with third party call control, the controller is actually one of the participants as far as the SIP dialog is concerned. So the encryption and integrity that S/MIME gives the SIP messages happen between the participants and the controller, not directly between the participants π
Still, integrity, authenticity and confidentiality of the media sessions can be provided through a controller. End-to-end media security is built on exchanging keying material within SDP [10] π
These mechanisms only work properly if the controller behaves itself. As long as it isn't trying to explicitly turn them off, the protocols will work between the participants, giving a secure media session that even the controller can't eavesdrop on or modify π. Since third party call control runs on a model of trust between the users and the controller, it's reasonable to assume it's behaving well. But no crypto can stop the controller from interfering with the initial exchanges of keying material. So it's trivially possible for the controller to slide in as a middleman on the media, if it were ever so inclined π
13. Acknowledgements π«Ά
Huge thanks to Paul Kyzivat, Rohan Mahy, Eric Rescorla, Allison Mankin and Sriram Parameswar for their comments π
14. References π
14.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] Camarillo, G., Ed., Marshall, W., Ed. and J. Rosenberg,
"Integration of Resource Management and Session Initiation
Protocol (SIP)", RFC 3312, October 2002.
[3] Bradner, S., "Key words for use in RFCs to Indicate Requirement
Levels", BCP 14, RFC 2119, March 1997.
[4] Rosenberg, J. and H. Schulzrinne, "An Offer/Answer Model with
Session Description Protocol (SDP)", RFC 3264, June 2002.
[5] Schulzrinne, H., Oran, D. and G. Camarillo, "The Reason Header
Field for the Session Initiation Protocol (SIP)", RFC 3326,
December 2002.
[6] Rosenberg, J. and H. Schulzrinne, "Reliability of Provisional
Responses in Session Initiation Protocol (SIP)", RFC 3262, June
2002.
[7] Rosenberg, J., "The Session Initiation Protocol (SIP) UPDATE
Method", RFC 3311, October 2002.
14.2. Informative References
[8] Schulzrinne, H., Casner, S., Frederick, R. and V. Jacobson,
"RTP: A Transport Protocol for Real-Time Applications", RFC
3550, July 2003.
[9] Petrack, S. and L. Conroy, "The PINT Service Protocol:
Extensions to SIP and SDP for IP Access to Telephone Call
Services", RFC 2848, June 2000.
[10] Andreasen, F., Baugher, M. and D. Wing, "SDP Security
Descriptions for Media Streams", Work in Progress, October 2003.
[11] Lennox, J., Wu, X. and H. Schulzrinne, "CPL: A Language for User
Control of Internet Telephony Services", Work in Progress,
August 2003.
15. Authors' Addresses πΈ
Jonathan Rosenberg
dynamicsoft
600 Lanidex Plaza
Parsippany, NJ 07054
US
Phone: +1 973 952-5000
EMail: jdrosen@dynamicsoft.com
URI: http://www.jdrosen.net
Jon Peterson
Neustar
1800 Sutter Street
Suite 570
Concord, CA 94520
US
Phone: +1 925 363-8720
EMail: jon.peterson@neustar.biz
URI: http://www.neustar.biz
Henning Schulzrinne
Columbia University
M/S 0401
1214 Amsterdam Ave.
New York, NY 10027
US
EMail: schulzrinne@cs.columbia.edu
URI: http://www.cs.columbia.edu/~hgs
Gonzalo Camarillo
Ericsson
Hirsalantie 11
Jorvas 02420
Finland
EMail: Gonzalo.Camarillo@ericsson.com
16. Full Copyright Statement π
The legal bits, verbatim, because they matter π
Copyright (C) The Internet Society (2004). 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 on whether any Intellectual Property Rights or other rights that might be claimed to cover the technology in this document are valid or in scope, or whether any license under those rights might be available. It also doesn't claim to have made any independent effort to find such rights. You can find the procedures for rights in RFC documents in BCP 78 and BCP 79.
Copies of IPR disclosures made to the IETF Secretariat, any assurances of licenses to be made available, or the results of an attempt to get a general license or permission for implementers or users to use these proprietary rights, can be found in the IETF's online 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 needed to implement this standard. Send that information to the IETF at ietf-ipr@ietf.org π¬
Acknowledgement π
Funding for the RFC Editor function is currently provided by the Internet Society π
π¦ where this page comes from
- ietf: rfc3725 2004-04
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms